Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to parse the result returned from ExecuteScriptAsync() in WebView2 #2365

Closed
PriyankaSOracle opened this issue Apr 14, 2022 · 5 comments
Closed
Assignees

Comments

@PriyankaSOracle
Copy link

Hi,

I am using ExecuteScriptAsync() method to get hold of the HTML in WebView2.
I have a requirement where I need to get all the input tags and iterate over them and store the value of all input tags in some hashmap for it to be used further in my code.
await webView2Browser.CoreWebView2.ExecuteScriptAsync("document.getElementsByTagName('input'));
I need it to convert it into html collection so that i can access html elements and their values.

Any help on how this could be done would be appreciated.

Thanks,
Priyanka

@david-risney
Copy link
Contributor

david-risney commented Apr 14, 2022

WebView2 doesn't directly expose DOM objects as C# objects like the WebBrowser control did. I would recommend doing what you can in script to iterate over the input elements and extract the values you require and return that via ExecuteScriptAsync. The result string of ExecuteScriptAsync is the result of the execution of the JavaScript converted to JSON. So you'll need to parse the JSON

        string inputElementsIdAndValueAsJsonString = await webView.ExecuteScriptAsync(
            "Array.from(document.getElementsByTagName('input')).map(inputElement => { " +
                "return { " +
                    "'id': inputElement.id || inputElement.name, " +
                    "'value': inputElement.value " +
                "} " +
            "});");

        JsonDocument inputElementsIdAndValueAsJsonDocument = JsonDocument.Parse(inputElementsIdAndValueAsJsonString);
        foreach (var entry in inputElementsIdAndValueAsJsonDocument.RootElement.EnumerateArray())
        {
            Console.WriteLine(entry.GetProperty("id") + " " + entry.GetProperty("value"));
        }

It is also important to note that the conversion of script execution result to JSON is the same as JSON.stringify which only examines the owned properties of a script object. Most properties of DOM objects are inherited and so don't show up. That's why if in DevTools in the browser you do JSON.stringify(document.getElementsByTagName("input")) you get {"0":{},"1":{},... an array of empty JS objects. The array-like object returned by getElementsByTagName is converted to JSON like you might expect but the DOM element objects inside the array all show up as {} because all their properties are inherited. We avoid this issue in the above code snippet by copying the properties we care about off of the DOM object onto a new JavaScript object.

@cdz1980
Copy link

cdz1980 commented Apr 15, 2022

directly expose DOM objects as C# , verry good

@amaitland
Copy link

If you are interested in an alternative to using JavaScript see #77 (comment)

@PriyankaSOracle
Copy link
Author

Hi @david-risney ,
Thanks for your response.
I tried to use the code snippet provided above but i am getting compilation error in the below line.
JsonDocument inputElementsIdAndValueAsJsonDocument = JsonDocument.Parse(inputElementsIdAndValueAsJsonString);
I have installed System.Text.json package from nuget package manager but still I am landing into compilation error when using System.Text.json. Error is System.Text does not contain System.Text.json.
I am using Visual studio 2019 and .NET framework 4.5.2.

Thanks,
Priyanka

@david-risney
Copy link
Contributor

It seems like there are many options for parsing JSON in C# and I'm not an expert on which are available in which versions of .NET. I used JsonDocument.Parse which is available for .NET Core 3.0, Core 3.1, 5, 6, 7 Preview 1 according to the docs.

Another way to go might be JsonValue.Parse but I'm not sure if that's available for your version of .NET either

            JsonArray resultArray = (JsonArray)JsonValue.Parse(inputElementsIdAndValueAsJsonString);
            foreach (JsonNode entry in resultArray)
            {
                JsonObject entryAsObject = entry.AsObject();
                JsonNode idAsJsonNode;
                JsonNode valueAsJsonNode;
                entryAsObject.TryGetPropertyValue("id", out idAsJsonNode);
                entryAsObject.TryGetPropertyValue("value", out valueAsJsonNode);
                string id = idAsJsonNode.GetValue<string>();
                string value = valueAsJsonNode.GetValue<string>();
                Console.WriteLine("id " + id + " value " + value);
            }

There are other options for parsing JSON in C# that may work better for you, but that part is independent of WebView2. You can try searching for other JSON parsing options like this stackoverflow thread on JSON parsing in C#.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants