Search code examples
json.netwebview2

WebView2 - Convert HTML Tbody To A Collection Using JSON


I have a table in my HTML page that I need to send to the host. I use ExecuteScriptAsync method (WebView2) in order to do that. That method returns a Newtonsoft.Json.Linq.JObject as a result. and it looks like this {{ "1": {}, "2": {}, "3": {}, "4": {}, "5": {}, "6": {}, "7": {} }} . The number of rows is correct but as you can see you don't have a full access to the table.

What is the proper way to deserialize a JObject to get a table

JsonConvert.DeserializeObject<object>(await this.WebView2Form.ExecuteScriptAsync("document.getElementById('" + TABLEID + "')." + rows));

In other words, I need to execute the javascript below and be able to read the result in C#

document.getElementById("myTable").rows

Solution

  • Well, @David Risney explains very well, why you can't serialize a HTMLCollection (which what the rows property returns) to JSON.

    What you can do instead is to write a javascript function that returns a 2 dimensional array, which will automatically be serialized to JSON and easily deserialized back to a 2 dimensional array in C#.

    I assume you want to read the text of all cells as an array.

    Such function is here:

    var TableContent = function (tableId)
    {
        let array = [];
    
        /** @type {NodeListOf<HTMLTableRowElement>} */
        let rows = document.querySelectorAll('#' + tableId + ' > tbody > tr');
    
        rows.forEach(function (row, i, rows)
        {
            array[i] = [];
            Array.from(row.cells).forEach(function (cell, j, cells)
            {
                array[i][j] = cell.textContent;
            });
        });
        return array;
    };
    

    (You know how to inject javascript into WebView2).

    Now in C# its quite easy to get an array:

    string tableId = "GridView1";
    string json = await webView21.ExecuteScriptAsync("TableContent('" + tableId + "')");
    string[][] cellsContent = Newtonsoft.Json.JsonConvert.DeserializeObject<string[][]>(json);
    

    Now you have a 2 dimensional string array with all cells text.

    You can access it like this:

    cellsContent[rowIndex][cellIndex]