6

I'm using a webview2-control in a winforms application. I use messages to communicate between c# and Javascript

  • window.chrome.webview.addEventListener / window.chrome.webview.postMessage in Javascript
  • event .CoreWebView2.WebMessageReceived and method CoreWebView2.PostWebMessageAsString in C#

The communication works BUT only after the page in webview2 has been somehow refreshed. The first message sent by c# is always ignored/not received by JS. The messages after that are correcly received and processed.

My UI code:

public GUI()
{
    InitializeComponent();
    browser.Source = new Uri(System.IO.Path.GetFullPath("HTML/ui.html"));
    InitializeAsync();
}
async void InitializeAsync()
{
    await browser.EnsureCoreWebView2Async(null);
    browser.CoreWebView2.WebMessageReceived += MessageReceived;
    }
void MessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs args)
{
    String content = args.TryGetWebMessageAsString();
    if (content.StartsWith("getData"))
    {
        ReadDataFromCATIA();
        var serializerSettings = new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects };
        string jsonRootNode = JsonConvert.SerializeObject(this.RootNode, Formatting.Indented, serializerSettings); //here I've got the message I want to post
        //String input = args.TryGetWebMessageAsString();
        //MessageBox.Show("string from JS: " + input);
        browser.CoreWebView2.PostWebMessageAsString(jsonRootNode);
    }
    else //object received
    {
        ProductNode received = JsonConvert.DeserializeObject<ProductNode>(content);
        MessageBox.Show(received.PartNumber + " received");
    }
}

and my JS in ui.html

window.chrome.webview.addEventListener('message', event => {
    alert(event.data);
    WriteDataFromCsharp(event.data);
});
function WriteDataFromCsharp(data) {
    var target = document.getElementById('target');
    if (target === null) { alert('target not found') };
    //alert(target.id);
    //target.textContent = event.data;

    rootNode = JSON.parse(data);
    target.innerHTML = addTable(rootNode); //addTable create an HTML table from the deserialized object rootNode
}
function RequestData() {
    //function triggered by a button on the html page
    //alert('post to c#');
    window.chrome.webview.postMessage('getData');
}

So far, i've tried to:

  • ensure the javascript is as late as possible in the page (defer, at the end of body). No changes.
  • inject the javascript to the page after it has been loaded using .CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(jsCode). Same behavior.
  • inject the javascript after once the event NavigationCompleted has fired. same behavior.

What do I miss ?

7
  • I suggest to initialize in OnLoad() or the Load handler (making them async) and subscribe to CoreWebView2InitializationCompleted. Some examples here: e.NewWindow = (CoreWebView2)sender still results in a separate instance and here: Which WebView2 event/function can be use to replace ScriptNotify Webview event? (slightly different language, same thing) Commented Feb 17, 2022 at 9:19
  • I've tried these two points: - move the initialization to the onload method, add the MessageREceived event in InitializationCompleted (Js still in html) --> same behavior - add the JS code with AddScriptToExecuteOnDocumentCreatedAsync in the event NavigationCompleted --> same behavior Commented Feb 17, 2022 at 9:47
  • It looks like you're posting to the Document only when you receive a message from the Document, but I don't see any call to window.chrome.webview.postMessage(). The JavaScript only adds an event listener that waits for messages sent by the host. Commented Feb 17, 2022 at 10:37
  • sorry, i've omitted this part of my code. I've got a button on my html page triggering the request. I've edited my question. Commented Feb 17, 2022 at 10:42
  • So, are you saying that clicking this Button doesn't raise WebMessageReceived? Or the event is raised, but the Document doesn't receive the post-back message from your App, so the listener of message doesn't trigger? -- ReadDataFromCATIA(); doesn't do anything here, but I assume you're calling that for a reason. After that, you're calling again args.TryGetWebMessageAsString();, but that's supposed to contain getData. There's something else missing here. -- Remove the MessageBoxes, write to the Output Pane of VS instead. Commented Feb 17, 2022 at 10:51

1 Answer 1

2

Finally found the culprit: in my HTML-page, i've used a "submit" instead of "button". With

<input type="button" value="Load data from V5" onclick="RequestData()" />

The page behavior is as expected.

Sign up to request clarification or add additional context in comments.

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
I will give the extra info: A submit button will refresh the page doing a post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.