Search code examples
c#webviewmauigeturl

Get the url from a side inside a WebView in Maui.Net


I tested a bunch of changes in my code for getting the URL out of a webside from a WebView object and print the url to a entry.

private async void YoutubeWebView_Navigated(object? sender, WebNavigatedEventArgs e)
{
    try
    {
        string currentUrl = await youtubeWebView.EvaluateJavaScriptAsync(
            "window.location.href;");
        urlEntry.Text = currentUrl;
    }
    catch (Exception ex)
    {
        await Console.Out.WriteLineAsync($"JavaScript execution error: {ex.Message}");
        throw;
    }
}

private void YoutubeWebView_Navigating(object? sender, WebNavigatingEventArgs e)
{
    urlEntry.Text = e.Url;
}

I tested the e.url. Not working. EvaluateJavaScriptAsync. Not working. change the Webview.source. Not working. Maybe One of your Proffs. can help me.


Solution

  • You can try the following code:

    xaml:

    <Entry x:Name="urlentry" TextColor="OrangeRed"/>
     
    <WebView Source="https://learn.microsoft.com/en-us/dotnet/maui/user-interface/layouts/grid?view=net-maui-8.0"
             x:Name="webview"
             Navigating="webview_Navigating"
             Navigated="webview_Navigated"
             HeightRequest="500"/>
    

    code behind:

    private void webview_Navigating(object sender, WebNavigatingEventArgs e)
    {
        urlentry.Text = e.Url;
    }
     
    private async void webview_Navigated(object sender, WebNavigatedEventArgs e)
    {
        try 
        { 
            string currentUrl = await webview.EvaluateJavaScriptAsync("window.location.href;"); 
            urlentry.Text = currentUrl; 
        } 
        catch (Exception ex) 
        { 
            await Console.Out.WriteLineAsync($"JavaScript execution error: {ex.Message}"); 
            throw; 
        }
    }
    

    You can try to set Source of WebView to .NET MAUI to see if urlentry.Text will update.

    Update:

    For Android, you can use WebViewClient.DoUpdateVisitedHistory() method of WebView if the base url doesnt change like it happens in single page applications and it detects URL change by javascript which does not lead to a web page reload. In addition, you can use WeakReferenceMessenger to exchange message(pass url to urlentry). Use the follwing steps:

    Install the CommunityToolkit.Mvvm NuGet package into your project and Add SendItemMessage.cs in your root directory:

    public class SendItemMessage : ValueChangedMessage<string> 
    {
        public SendItemMessage(string value) : base(value)
        {
        }
    }
    

    Create MyClient.cs in your Platforms/Android, to get url and send it:

    public class MyClient: WebViewClient
    {
        public override void DoUpdateVisitedHistory(global::Android.Webkit.WebView? view, string? url, bool isReload)
        {
            var a = view?.Url;
            WeakReferenceMessenger.Default.Send(new SendItemMessage(a));
            base.DoUpdateVisitedHistory(view, url, isReload);
        }
    }
    

    Modify your webview and receive url in MainPage.xaml.cs:

    public partial class MainPage : ContentPage
        {
            public MainPage()
            {
                InitializeComponent();
                ModifyWebView();
                WeakReferenceMessenger.Default.Register<SendItemMessage>(this, (r, m) =>
                {
                    OnMessageReceived(m.Value);
                });
            }
     
            private void OnMessageReceived(string value)
            {
                 urlentry.Text = value;
            }
     
            void ModifyWebView()
            {
                Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
                {
    #if ANDROID
                    handler.PlatformView.SetWebViewClient(new Platforms.Android.MyClient());
    #endif
                });
            }
    ....