Open Mirzek opened 7 months ago
The behavior depends on how .NET implements with IDispatch witch WebView2 uses to interact with host objects. Which version of .NET are you using? In my project targeting .NET Framework 4.6 (net462, with LangVersion set to be 8.0 so that I can get nullable reference support), calling from JS with lower case method name testMethodB actually it actually worked the same way as TestMethodB.
I was using .NET 8.0, but it doesn't seem dependant on the version of the .NET as I recreated the project in .NET Framework 4.6.2 and it behaves exactly the same in every way I described above. I only changed the string to not have explicit nullable reference as it is nullable implicitly in .NET Framework:
[ComVisible(true)]
public class BridgeHostObject
{
public string TestMethodA(string str)
{
return str;
}
public string TestMethodB(string str = null)
{
return str;
}
}
It is the known issue with .NET core interaction. The issue repros with .NET core but not legacy .NET Framework. No easy fix from WebView2 side.
The hit of TestMethodB actually was due to WebView2 code tries to figure out whether testMethodB is a property by invoking the IDispatch object with DISPATCH_PROPERTYGET.
This is similar to https://github.com/MicrosoftEdge/WebView2Feedback/issues/2840#issuecomment-1284347447.
Once again. I tried it also in .NET Framework 4.6.2 and it behaves exactly the same, so no it does not seem to be issue only with .NET core. However if there is no easy fix from WebView2 side I guess that is the answer anyway, but I just wanted to clarify that using .NET Framework 4.6.2 is not a workaround as it doesn't work there as well.
Figured out why it didn't repro for me with .NET Framework and repro for you. I also have [ClassInterface(ClassInterfaceType.AutoDual)]
on the class. If you add that to the class, it should work when running with .NET Framework:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class BridgeHostObject
Yes, with that AutoDual attribute it now works fine both with lower case and upper case first letter with .NET Framework for me as well. Thank you.
I tested it again in actual real application and it still didn't work (btw we had AutoDual
there from the start and it is .NET Framework application) and I found out it doesn't work even in .NET Framework and AutoDual
when the methods are async.
With following code it behaves once again exactly the same as my original description above:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class BridgeHostObject
{
public async Task<string> TestMethodA(string str)
{
return str;
}
public async Task<string> TestMethodB(string str = null)
{
return str;
}
}
It seems that the .NET's type info for the IDispatch doesn't contain the async methods in its member list. We do use some helper that tries to use .NET reflection to figure out whether it is a method. However, that requires exact matching of the name.
Unfortunately, there is no much that we could do in this case.
What happened?
The bug was found in more complex project, but I reproduced it in the most simple way possible in separate clear WPF project. I added only WebView2 there and added HostObject by calling AddHostObjectToScript with code below:
To explore all basic possibilities the BridgeHostObject has following two methods:
I found out about the bug as we are moving an application from CefSharp to WebView2 and CefSharp supported calling HostObject methods with any first letter from JavaScript side so it was causing errors after switching to WebView2. However thanks to that I also found about following weird inconsistent behavior.
When calling methods with JavaScript using upper case first letter the behavior is as expected.
When calling methods with JavaScript using lower case first letter the behavior is following where in case of
TestMethodA
the break point on the side of WPF application is not activated, but in case ofTestMethodB
it is and its parameter is always null even when value 'abcd' was entered from the side of the JavaScript.Importance
Moderate. My app's user experience is affected, but still usable.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
123.0.2420.47
SDK Version
1.0.2420.47
Framework
WPF
Operating System
Windows 11
OS Version
Edition Windows 11 Enterprise Version 22H2 Installed on 11. 4. 2024 OS build 22621.3447 Experience Windows Feature Experience Pack 1000.22688.1000.0
Repro steps
TestMethodA
andTestMethodB
await chrome.webview.hostObjects.bridge.testMethodA('abcd')
await chrome.webview.hostObjects.bridge.testMethodB('abcd')
Expected behavior: No breakpoint activated as well
Actual behavior: Breakpoint for
TestMethodB
activated and the parameter str having value null instead of "abcd" and as the code was successfully executed and null was returned at least seeing that in Console would be expected, but not even that happened as "Unable to call method on non-function" error message was shown instead.Repros in Edge Browser
No, issue does not reproduce in the corresponding Edge version
Regression
Don't know
Last working version (if regression)
No response