Search code examples
javascriptc#webviewcomwin-universal-app

C# class attributes not accessible in Javascript


I want to make a class of mine accessible in JavaScript via a C# WebView-Control. Therefore I am using the WebView.AddWebAllowedObject method. However if I assign an attribute, it works fine, but if I assign the whole class to get all attributes in js, all of the attributes(and methods btw) are "undefined". I tried everything I found in the www. See the attached code:

        //The class I want to make accessible
        [AllowForWeb, ComVisible(true)]
        [MarshalingBehavior(MarshalingType.Agile)]
        public class DeviceInformation
        {
            public string IPAdress { get; private set; }

            public DeviceInformation()
            {
                IPAdress = GetIPAdress();
            }

            public string GetDeviceUUID()
            {
                EasClientDeviceInformation deviceinfo = new EasClientDeviceInformation();
                return deviceinfo.Id.ToString();
            }

            public string GetIPAdress()
            {
                List<string> ipAddresses = new List<string>();
                var hostnames = NetworkInformation.GetHostNames();
                foreach (var hn in hostnames)
                {
                    if (hn?.IPInformation != null && (hn.IPInformation.NetworkAdapter.IanaInterfaceType == 71 ||
                        hn.IPInformation.NetworkAdapter.IanaInterfaceType == 6))
                    {
                        string ipadress = hn.DisplayName;
                        return ipadress;
                    }
                }
                return string.Empty;
            }
        }

Here the objects are initialized.

DeviceInformation devinf = new DeviceInformation();
private void View_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
    {
        if (args.Uri.Host == "")
        {
            //win_ipadress has an ipadress as value
            view.AddWebAllowedObject("win_ipadress", devinf.IPAdress);
            //deviceInformation is initialized as well but I have no access to its attributes
            view.AddWebAllowedObject("deviceInformation", devinf);
        }
    }

That's the way i call it in js:

else if ($.os.ie) {
                    myIpAdr = window.win_ipadress;
                    //Throws an exception because GetIPAdress() is "undefined"
                    myIpAdr = window.deviceInformation.GetIPAdress();
                }

I am using this in a Windows Universal App. The Javascript and in the WebView displayed HTML-Code is already in use for Android an iOS.


Solution

  • I believe you need to define the method name starting with a lower case character.

    For example: change GetIPAddress to getIPAddress.

    I tested it on my side and found if I use the upper case name 'GetIPAddress', it won't work. But if I use getIPAddress, it works.

    And after I read kangax's explanation in this thread, I think it makes sense.

    [Update]

    Since it still doesn't work after you make the change on method name, I think the issue should be related to how you expose the windows runtime object. I guess you simply defined the DeviceInformation class and tried to use it in the same project.

    First, we need to create a separate windows universal windows runtime component project.

    The c# class DeviceInformation should be put into this project. Keep the same code.

    Then, in your universal app project, add reference to the windows runtime component and keep rest code to consume the windows runtime object.

    [Update 2]

    Just noticed an interesting behavior in VS. No matter if the Method name we defined in C# is starting with uppercase or lowercase, the visual studio intellisense shows the lowercase, so the method name will be automatically converted when we try to use it in js.