Welcome Guest Search | Active Topics | Sign In | Register

Injecting Javascript Bridge into WebView Options
leo158
Posted: Wednesday, July 5, 2017 4:52:11 PM
Rank: Newbie
Groups: Member

Joined: 7/5/2017
Posts: 6
Hello,

I am attempting to "inject" a .NET object into the web view, in other browsers I have used, the method looks something like this:

webView.RegisterJSObject("ObjectName", CustomDotNetObject);

And from here the Javascript can access the object's methods by calling ObjectName.GetName(), ObjectName.GetTime(), etc etc.

Note: I have no control over the JS component of this development. The js side of things is calling "window.CustomObject.GetContent()", and I need to find a way for that CustomObject to be my complex .NET object where I have a method called GetContent() on it.



I have not found a simple way to do this, and I've also learned that EO doesn't allow passing objects through, here are a few things I have tried.

Method 1:

webControl.WebView.RegisterJSExtensionFunction("window.CustomObject", WebView_CustomObject);

private void WebView_CustomObject(object sender, JSExtInvokeArgs e)
{
//This is the object I am trying to pass through.
CustomObject obj = new CustomObject();
string serializedObject = JsonConvert.SerializeObject(obj);
e.ReturnValue = serializedObject;

}


I was hoping to for "window.CustomObject" to be intercepted as a method and have my object returned in the e.ReturnValue, but this does not work.


Method 2:

webControl.WebView.RegisterJSExtensionFunction("GetData", WebView_CustomObjectGetData);

private void WebView.CustomObjectGetData(object sender, JSExtInvokeArgs e)
{
//This is the object I am trying to pass through.
CustomObject obj = new CustomObject();
string serializedObject = JsonConvert.SerializeObject(obj);
e.ReturnValue = serializedObject;

}

var jsScript1= "var CustomObject= null;";

var jsScript2= @"function CallThis() {
CustomObject= GetData();
}
CallThis();";

webControl.WebView.EvalScript(jsScript1);
webControl.WebView.EvalScript(jsScript2);


In Method 2 I managed to get GetData() called and returning the serialized version of the data, but it doesn't appear to be setting the CustomObject value to the results of GetData().


Method 3:

var jsScript1="var CustomObject = "+serializedObject;

or

var jsScript1="var CustomObject = "+"JSON.parse("\"+serializedObject+"\");"

webControl.WebView.EvalScript(jsScript1);


I guess my problem is really specific here and I am running out of ideas, I would like to know if I want to do is possible and whether I was going about it the wrong way.






eo_support
Posted: Thursday, July 6, 2017 8:21:07 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,225
Hi,

The key is you need to stop trying to pass object to the JavaScript ---- it won't work for your purpose because anything you passed to the JavaScript side is a COPY. So you will not be able to use that copy to call back to your original object from JavaScript. The reason we only pass a copy is both for performance and reliability reasons --- for EO.WebBrowser, the browser engine runs OUTSIDE of your process in a separate child process, as such the child process can not directly hold a reference to any of your object.

There are a number of ways to work around this, but any method you use would rely on either of both of these features: RegisterJSExtensionFunction/ExtInvoke. For example, instead of trying to pass the object to JavaScript, you can create a GUID as key, then put your object in a Dictionary object on your .NET side with that key. After that instead of passing the object to the JavaScript side, you would pass the GUID to the JavaScript side instead. You can then pass this GUID back when you call into the .NET code from your JavaScript code.

Thanks!
leo158
Posted: Thursday, July 6, 2017 3:58:44 PM
Rank: Newbie
Groups: Member

Joined: 7/5/2017
Posts: 6
Hi,

Thanks for the quick reply. Unfortunately like I mentioned in the first post, I have zero control over the Javascript side of this development. The existing architecture currently works with multiple other browsers across multiple platforms, changing the JS side of things would mean significant changes outside that are not acceptable.

The only idea I have left is somehow override that call on the JS side via Eval Script, making it redirect window.CustomObject to actually calling GetData() or something on my end so I can return relevant data.
eo_support
Posted: Thursday, July 6, 2017 4:57:47 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,225
leo158 wrote:

The only idea I have left is somehow override that call on the JS side via Eval Script, making it redirect window.CustomObject to actually calling GetData() or something on my end so I can return relevant data.


You can do that as well. You can use WebView.EvalScript to dynamically defines your window.CustomObject and implement all methods however you want. For example, you can run the following JavaScript code to define window.CustomObject to have two methods "hello" and "doSomething":

Code: JavaScript
//Define window.CustomObject to have several functions
window["CustomObject"] = 
{
   //Define hello method
   hello: function()
   {
        //Use extInvoke to call into the .NET side, replace "..." with actual
        //arguments that works for you
        eoWebBrowser.extInvoke(......);
   }

   //Define another method doSomething
   doSomething: function(someArgs)
   {
        //Use extInvoke to call into the .NET side, replace "..." with actual
        //arguments that works for you
        eoWebBrowser.extInvoke(......);
   }
};


Thanks


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.