Attention: We are retiring the ASP.NET Community Blogs. Learn more >

Contents tagged with WebView2

  • WebView2 Getting Started

    The Microsoft WebView2 control allows you to embed Web Tech in native applications. It’s miles better than the old web browser controls. The WebView2 control is based on the Chromium platform.

    The official docs for the control are found here: https://docs.microsoft.com/en-us/microsoft-edge/webview2/

    Pre-reqs

    Important note (as of 2021-01-20) - ensure you installed the following list of pre-requisites before proceeding:

    I suggest you visit https://www.microsoftedgeinsider.com/download and get the “Edge Canary Channel” that way.

    Install WebView2 SDK in Visual Studio

    Once you’ve created your WebForms or WPF project, install the Microsoft.Web.WebView2 package from Nuget:

    PM> Install-Package Microsoft.Web.WebView2

    Initializing WebView2 Control

    Much about the control is asynchronous, and to make sure the control is loaded and ready, add an InitializeAsync() method to your form constructor, and place the events of interest there, like so:

            public webView2TestForm()
            {
                InitializeComponent();
                InitializeAsync();
            }
    
            async void InitializeAsync()
            {
                webViewControl.NavigationCompleted += WebViewControlOnNavigationCompleted;
                webViewControl.WebMessageReceived += WebViewControlOnWebMessageReceived;
    
                await webViewControl.EnsureCoreWebView2Async(null);
            }
    
    

    Send Message to Web Page

    Easiest way to communicate between the web page and the native application is to send messages. From the native app:

    webViewControl.CoreWebView2.PostWebMessageAsString("proxy.object.added");
    

    To handle messages, the web page need some scripting:

            window.chrome.webview.addEventListener('message',
                event => {
                    console.log('Got message from host!');
                    console.log(event.data);
                    handleMessages(event.data);
                });
    
    

    Send Message to Host

    To send a message from the web page

    window.chrome.webview.postMessage('page.ready');
    

    To handle messages from web page in the host:

            private void WebViewControlOnWebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
            {
                var message = e.TryGetWebMessageAsString();
                switch (message)
                {
                    case "page.ready":
                        Trace.TraceInformation("Got page.ready message!");
                        break;
                    default:
                        Trace.TraceWarning("Unknown message received: " + message);
                        break;
                }
            }
    
    

    Proxy Objects

    One of the coolest features availeble is to send a “proxy object” from the native application to the web page. There are some limitations but powerful enough. The best info I’ve found is this: https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addhostobjecttoscript 

    The class/object must be exposed as a COM object (!):

        [ClassInterface(ClassInterfaceType.AutoDual)]
        [ComVisible(true)]
        public class ProxyHostObject
        {
            // sample property
            public string Name { get; set; } = "Johan";
    
            // sample method
            public string GetName()
            {
                return Name;
            }
    
            // sample indexed property
            [System.Runtime.CompilerServices.IndexerName("Items")]
            public string this[int index]
            {
                get => _dictionary[index];
                set => _dictionary[index] = value;
            }
            private Dictionary<int, string> _dictionary = new Dictionary<int, string>();
        }
    
    

    The use of the ClassInterface attribute is discussed in the Edge github repo, because the AutoDual value is not recommended in the docs, and even deprecated in dotnet:

    Using AutoDual is strongly discouraged because of the versioning limitations described in System.Runtime.InteropServices.ClassInterfaceAttribute.

    The issue is discussed here: https://github.com/MicrosoftEdge/WebView2Feedback/issues/517

    To create and use the proxy object in the web page:

        async function handleMessages(message) {
            switch (event.data) {
            case 'proxy.object.added':
                {
                    const obj = window.chrome.webview.hostObjects.proxyobject;
                    console.log(obj);
    
                    var name1 = await obj.Name;
                    console.log('name prop: ' + name1);
                    var name2 = await obj.GetName();
                    console.log('name func: ' + name2);
    
                    obj.GetName().then(name => {
                        console.log("GetName promise name: " + name);
                    });
    
                    // Indexed properties
                    let index = 123;
                    obj[index] = "test";
                    let result = await obj[index];
                    console.log(result);
                }
                break;
    
            default:
                console.log("unknown message: " + event.data);
            }
        }