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
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.