Skip to content

[Problem/Bug]: Class not registered when invoking host object event #5145

@parzivail

Description

@parzivail

What happened?

Unable to subscribe to events from within JavaScript.

The docs state,

addEventListener | This method only exists on proxies for .NET objects. Bind the JavaScript handler to the C# event, so that the JavaScript handler can be called through the C# event. For example, chrome.webview.hostObjects.sample.addEventListener('TestEvent', () => { alert('Invoked from remote');}); bind an anonymous JavaScript function to a C# event called 'TestEvent'.

however, I cannot get this functionality to work.

Removing the event handler attachment within JS prevents the exception from occurring. I assume this is because there is, then, nothing subscribed to the event from the C# side, and the event invocation is a no-op. Luckily, this proves that the event registration works as intended from the JS side.

Importance

Important. My app's user experience is significantly compromised.

Runtime Channel

Stable release (WebView2 Runtime)

Runtime Version

128.0.2739.54

SDK Version

1.0.3065.39

Framework

WPF

Operating System

Windows 10

OS Version

19045.4842

Repro steps

Registering a host object:

[ComVisible(true)]
public class AppState
{
	private int _testProp = 0;

	public int TestProp
	{
		get
		{
			Console.WriteLine($"Get TestProp ({_testProp})");
			return _testProp;
		}
		set
		{
			Console.WriteLine($"Set TestProp to {value}");
			SetField(ref _testProp, value);
		}
	}


	public event Action? PropertyChanged;

	protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
	{
		PropertyChanged?.Invoke();
	}

	protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
	{
		if (EqualityComparer<T>.Default.Equals(field, value)) return false;
		field = value;
		OnPropertyChanged(propertyName);
		return true;
	}
}

as such

// obtain an instance of AppState, I have mine as a field within my WPF window's backing class
AppState state = ...
// assuming a WPF element named myWebView, and invoking this method in the CoreWebView2InitializationCompleted callback:
myWebView.CoreWebView2.AddHostObjectToScript("state", state);

with the following JS having run inside the browser:

chrome.webview.hostObjects.state.addEventListener('PropertyChanged', () => { console.log('fired'); });

then, firing the PropertyChanged event by setting a property:

AppState state = ...
state.TestProp = 1;

will cause the following exception:

System.Runtime.InteropServices.COMException (0x8007046B): Class not registered

   at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode)
   at Microsoft.Web.WebView2.Core.JSHandlerWrapper.Invoke(Object[] args)
   at DelegateHandler(JSHandlerWrapper)
   at WebviewTest2.AppState.OnPropertyChanged(String propertyName) in C:\Users\cnewman\RiderProjects\WebviewTest2\WebviewTest2\MainWindow.xaml.cs:line 37
   at WebviewTest2.AppState.SetField[T](T& field, T value, String propertyName) in C:\Users\cnewman\RiderProjects\WebviewTest2\WebviewTest2\MainWindow.xaml.cs:line 44
   at WebviewTest2.AppState.set_TestProp(Int32 value) in C:\Users\cnewman\RiderProjects\WebviewTest2\WebviewTest2\MainWindow.xaml.cs:line 28

Repros in Edge Browser

Don't know

Regression

Don't know

Last working version (if regression)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions