|
Rank: Member Groups: Member
Joined: 7/30/2018 Posts: 16
|
Hi Guys, I was using one of the 2019 builds and I was able to use the ObjectForScripting for two way communication between javascript - .NET or vice versa. Right now , in the 2024 builds or any build after 2020 I can only communicate to .NET from Javascript however I can not call any javascript function from .NET My ussage was like this: webControl1.WebView.ObjectForScripting = new ScriptManager(this);an example data pass or function call: webControl1.WebView.InvokeFunction("testfunction","testdata");or webControl1.WebView.InvokeFunction("testfunction1");in either case I get "Object Reference not set to an instance of an object error" I have searched the forum and found a message related to re-entering however I did not understand at all, how should I fix my approach. This is the topic link: https://www.essentialobjects.com/forum/postst11763_ObjectForScripting-stoped-working-in-version-201450-with-JSObject.aspxcan someone explain to me how can I pass data to javascript?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,182
|
Hi, You can still use InvokeFunction to call JavaScript code. However you can not immediately call back into .NET from the JavaScript code that you are calling. For example, if you have the following code in your testfunction then it would be problematic:
Code: JavaScript
function testfunction(data)
{
window.external.SomeDotNetFunction();
}
This causes the sequence of .NET Code -> JavaScript code (through InvokeFunction("testfunction","testdata")) -> .NET Code (through window.external.SomeDotNetFunction()). This causes .NET code re-entering and it is not allowed. The other case is JavaScript code -> .NET code -> JavaScript code. For example, if you have the following JavaScript code:
Code: JavaScript
window.external.SomeDotNetFunction();
Then on your .NET side inside your SomeDotNetFunction() you call InvokeFunction:
Code: C#
void SomeDotNetFunction()
{
webControl1.WebView.InvokeFunction("testfunction","testdata");
}
This causes the sequence of JavaScript code -> .NET code (through window.external.SomeDotNetFunction()) -> JavaScript code (through WebView.InvokeFunction), which causes the JavaScript code re-entering which is again not allowed. Your case most likely is the second one. In that case you can wrap your InvokeFunction call inside WebView.RunLater:
Code: C#
void SomeDotNetFunction()
{
webControl1.WebView.RunLater(() =>
{
webControl1.WebView.InvokeFunction("testfunction","testdata");
});
}
This would delay the call to WebView.InvokeFunction until after SomeDotNetFunction returns. If your case is the first case, the solution is similar except for such delay would be implemented in JavaScript code. You can do that with setTimeout:
Code: JavaScript
function testfunction(data)
{
setTimeout(function()
{
window.external.SomeDotNetFunction();
}, 1);
}
Hope this helps. Please feel free to let us know if you still have any questions. Thanks!
|
|
Rank: Member Groups: Member
Joined: 7/30/2018 Posts: 16
|
my case is usually the second one. Right now I implemented this and seems to be working
Code: JavaScript
function callTest(){
window.external.testFunction();
}
Code: C#
public bool testFunction(){
//some sql queries
Task.Delay(1).ContinueWith(t => webControl1.WebView.InvokeFunction("testfunction","testdata"));
return true;
}
However I can not understand the logic behind it, does this not cause unpredictable behaviour under different cirscumstances like how fast it runs etc? Additionally, is there any chance that you guys can make the re-entering optional for your customers who have been happily and succesfuly using for 5+ years? Please let me know. Thanks
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,182
|
Hi,
The root reason of this change is JavaScript engine does not natively allow re-entering. So if we were to introduce re-entering then it can potentially cause many serious issues that leads to all sort of problems, from obvious logic issues (as explained in our reply in the link you posted) to internal JavaScript engine state corruptions. The fact that you have been running it sucessfully for 5+ years does not mean you won't run into any issues because a lot of such issues are triggered by timing. So the same application can work with no problem on one system but could run into all sort of problems on a different system with different set of hardware.
Thanks!
|
|
Rank: Member Groups: Member
Joined: 7/30/2018 Posts: 16
|
I understand, thanks for the explanation however I am still inclined to think that it should be an option for users to choose whether allow this or no.
In addition, do you approve, find it safe to use the above approach or any bullet proof suggestions for such uses?
Thanks!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,182
|
Yes. Use Task.Delay is safe for this particular case.
|
|
Rank: Member Groups: Member
Joined: 7/30/2018 Posts: 16
|
Thanks! would you say 1 is enough, how do you guys normally recommend it?
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,182
|
Hi,
1 is enough. The key is not about how much you delay. The key is WebView.InvokeFunction must be called AFTER testFunction returns. Any delay value would achieve that goal.
Thanks!
|
|
Rank: Member Groups: Member
Joined: 7/30/2018 Posts: 16
|
Thank you so much for guiding through it!
|
|
Rank: Administration Groups: Administration
Joined: 5/27/2007 Posts: 24,182
|
You are very welcome. Please feel free to let us know if there is anything else.
|
|