Problem:
HostObjectToScript throws exception when trying to execute a passed-in function
Scenario:
WPF application has a WebView2 tab embedded and exposes an object for scripting using CoreWebView2.AddHostObjectToScript(). I'm able to access this object using Javascript:
window.blah = chrome.webview.hostObjects.sync.blah_blah_external;
and call functions without issue. Everything works just fine until I call a function that creates a class and passes in a function as parameter to that class. The parameters pass in just fine, but when the code tries to call the functions it throws the System.NotImplementedException exception. This worked just fine before replacing the IE-based browser control with WebView2, so I'm hoping it's something simple I'm missing.
Environment:
The Host object is exposed with this:
variablename.CoreWebView2.AddHostObjectToScript("blah_blah_external", new MYTABExternal(_tabHost));
The Host Object looks like this:
namespace MYTAB
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisibleAttribute(true)]
public class MYTABExternal
{
public void createTHING(String user, dynamic onError)
{
CLASSNAME currentCLASSNAME = new CLASSNAME(user, onError);
currentCLASSNAME.create();
}
}
}
The class that throws the error is setup as such:
namespace MYTAB
{
public class CLASSNAME
{
protected String user;
protected dynamic onError;
public CLASSNAME(String user, dynamic onError)
{
this.user= user;
this.onError = onError;
}
public void create()
{
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork -= backgroundWorker_DoWork;
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; //Tell the user how the process went
RequestContext requestContext = EXTERNALLIBRARY.SharedContext.Instance;
backgroundWorker.RunWorkerAsync(requestContext);
}
/// <summary>
/// Fires when the background task is complete
/// </summary>
private void backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
this.onError("The creation process was cancelled"); // HERE'S THE EXCEPTION
}
}
...
The javascript to call the function is:
window.setTimeout(function () {
window.blah.createTHING(btn.attr('data-requestor-user-id'), function (onErrorResponse) {
dialog.$modal.addClass('type-danger');
dialog.setMessage('<p>' + onErrorResponse + '</p>');
spinner.stop();
});
}, 1000);
Exception stack trace is:
Exception thrown: 'System.NotImplementedException' in System.Dynamic.dll
Exception thrown: 'System.NotImplementedException' in System.Dynamic.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>BLAH</AppDomain><Exception><ExceptionType>System.NotImplementedException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType><Message>The method or operation is not implemented.</Message><StackTrace> at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Dynamic.ComRuntimeHelpers.GetITypeInfoFromIDispatch(IDispatch dispatch, Boolean throwIfMissingExpectedTypeInfo)
at System.Dynamic.IDispatchComObject.EnsureScanDefinedMethods()
at System.Dynamic.IDispatchComObject.System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
at System.Dynamic.DynamicMetaObject.Create(Object value, Expression expression)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at CallSite.Target(Closure , CallSite , Object , String )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
at MyTab.CLASSNAME.backgroundWorker_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) in C:CLASSNAME.cs:line 145
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.AsyncOperationCompleted(Object arg)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</StackTrace><ExceptionString>System.NotImplementedException: The method or operation is not implemented.
at System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode, IntPtr errorInfo)
at System.Dynamic.ComRuntimeHelpers.GetITypeInfoFromIDispatch(IDispatch dispatch, Boolean throwIfMissingExpectedTypeInfo)
at System.Dynamic.IDispatchComObject.EnsureScanDefinedMethods()
at System.Dynamic.IDispatchComObject.System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
at System.Dynamic.DynamicMetaObject.Create(Object value, Expression expression)
at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at CallSite.Target(Closure , CallSite , Object , String )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
at MyTab.CLASSNAME.backgroundWorker_RunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e) in C:\CLASSNAME.cs:line 145
at System.ComponentModel.BackgroundWorker.OnRunWorkerCompleted(RunWorkerCompletedEventArgs e)
at System.ComponentModel.BackgroundWorker.AsyncOperationCompleted(Object arg)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</ExceptionString><DataItems><Data><Key>ApplicationName</Key><Value>BLAH</Value></Data></DataItems></Exception></TraceRecord>
question from:
https://stackoverflow.com/questions/66066692/webview2-hostobjecttoscript-throws-runtime-system-notimplementedexception-except