3

To authenticate an API service, it is required for the user to sign into a webpage. If the sign-in is valid, an authentication code is appended to the end of a redirected Uri. The authentication code is then used in the oauth to get the key, etc... To faciliate this, I have implemented WebView2:

        <wv2:WebView2 Name="webView"
                  Width="800"
                  Height="500"
                  Source="{Binding WebUri, Mode=TwoWay}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SourceChanged">
                <i:InvokeCommandAction Command="{Binding SourceChangedCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </wv2:WebView2>

I have validation logic in the viewmodel to recognize when the redirect uri contains the authentication code; this is done through the SourceChangedCommand that is called when the SourceChanged event is thrown on the WebView (following the navigation event lifecycle described here). The SourceChangedCommand.Execute is as follows:

    public void Execute(object? parameter)
    {
        if (ValidateUri(_viewModel.WebUri.ToString()))
        {
            var str = _viewModel.WebUri.ToString().Substring(50);
            _navigationService.Authenticate(str);
        }
    }

Here is where I am running into a problem: I also have a NavigationService which navigates between viewmodels and changes view by datatemplates, etc... When navigating away from the view with the WebView2 (ie: changing data contexts on the parent view), I am given the following error:

The Source property cannot be set to null

enter image description here

This is extremely confusing as the source for the WebView2 is never actually set to null - it is maintained as the redirected Uri. What is going wrong here and how can I navigate away from this view?

Possible solutions I am exploring is creating a custom control extending WebView2 with a bool dependency property mapped to WebView2.Dispose(bool) -> if true, the webview will be disposed. This however seems like overkill and might bring up other issues relating to ObjectDisposedException's.

jgrmn
  • 134
  • 12

1 Answers1

0

I had the same problem and found it was because I was setting IsAsync=true on the binding.

Also inspect the properties you are binding to. They always need to be able to get a value that isn't null.

When my properties are initialized I set them to new Uri("about:blank").
Additionally, use this._myProp = new UriBuilder(value).Uri ?? new Uri("about:blank") on the field set to ensure no nulls

Hey Microsoft how about a static Uri.Empty property with about:blank in it?

I hope this helps

Tim Jarosz
  • 1,133
  • 1
  • 8
  • 15