Teilen über


Hosten einer Blazor-Webanwendung in einer .NET MAUI-App mit BlazorWebView

Die .NET Multiplattform App UI (.NET MAUI) BlazorWebView ist ein Steuerelement, das es Ihnen ermöglicht, eine Blazor-Web-App in Ihrer .NET MAUI-App zu hosten. Diese als Blazor-Hybrid-Apps bezeichneten Apps ermöglichen die Integration einer Blazor-Webanwendung mit Plattformfunktionen und UI-Steuerungen. Das BlazorWebView-Steuerelement kann zu jeder Seite einer .NET-MAUI-App hinzugefügt werden und verweist auf das Stammverzeichnis der Blazor-App. Die Razor-Komponenten laufen nativ im .NET-Prozess und geben die Web-UI an ein eingebettetes Web-View-Control weiter. In .NET MAUI können Blazor Hybrid-Apps auf allen von .NET MAUI unterstützten Plattformen laufen.

BlazorWebView definiert die folgenden Eigenschaften:

  • HostPage, vom Typ string?, der die Root-Seite der Blazor-Web-App definiert.
  • RootComponents, vom Typ RootComponentsCollection, der die Sammlung von Stammkomponenten angibt, die dem Steuerelement hinzugefügt werden können.
  • StartPath, vom Typ string, der den Pfad für die anfängliche Navigation innerhalb des Blazor-Navigationskontexts definiert, wenn die Blazor-Komponente fertig geladen ist.

Die RootComponent-Klasse definiert die folgenden Eigenschaften:

  • Selector, vom Typ string?, der die CSS-Selektorzeichenfolge definiert, die angibt, wo im Dokument die Komponente platziert werden soll.
  • ComponentType, vom Typ Type?, der den Typ der Stammkomponente definiert.
  • Parameters vom Typ IDictionary<string, object?>?, der ein optionales Verzeichnis von Parametern darstellt, die an die Stammkomponente übergeben werden.

Darüber hinaus werden in BlazorWebView die folgenden Ereignisse definiert:

  • BlazorWebViewInitializing, mit einem begleitenden BlazorWebViewInitializingEventArgs-Objekt, das vor der BlazorWebView-Initialisierung ausgelöst wird. Dieses Ereignis ermöglicht die Anpassung der BlazorWebView-Konfiguration.
  • BlazorWebViewInitialized, mit einem begleitenden BlazorWebViewInitializedEventArgs-Objekt, das ausgelöst wird, nachdem das BlazorWebView initialisiert wurde, aber bevor eine Komponente gerendert wurde. Dieses Ereignis ermöglicht das Abrufen der plattformspezifischen Web-View-Instanz.
  • UrlLoading wird mit einem zugehörigen UrlLoadingEventArgs-Objekt ausgelöst, wenn ein Hyperlink innerhalb einer BlazorWebView angeklickt wird. Dieses Ereignis ermöglicht die Anpassung, ob ein Hyperlink in der BlazorWebView, in einer externen App geöffnet wird oder ob der URL-Ladeversuch abgebrochen wird.

Vorhandene Razor-Komponenten können in einer .NET MAUI Blazor-App verwendet werden, indem der Code in die App verschoben wird oder indem auf eine vorhandene Klassenbibliothek oder ein Paket verwiesen wird, das die Komponente enthält. Weitere Informationen finden Sie unter Wiederverwendung von Razor-Komponenten in ASP.NET Core Blazor Hybrid.

Browser-Entwickler-Tools können verwendet werden, um .NET MAUI Blazor-Apps zu inspizieren. Weitere Informationen finden Sie unter Verwenden von Browser-Entwickler-Tools mit ASP.NET Core Blazor Hybrid.

Hinweis

Während Visual Studio alle erforderlichen Werkzeuge für die Entwicklung von .NET MAUI Blazor-Apps installiert, müssen Endbenutzer*innen von .NET MAUI Blazor-Apps auf Windows die WebView2-Laufzeitumgebung installieren.

Weitere Informationen zu Blazor-Hybrid-Apps finden Sie unter ASP.NET Core Blazor Hybrid.

Erstellen einer .NET MAUI-App

Eine .NET MAUI Blazor App kann in Visual Studio mit der .NET MAUI Blazor App-Vorlage erstellt werden:

Screenshot der .NET MAUI Blazor-App-Projektvorlage.

Diese Projektvorlage erstellt eine multizentrische .NET MAUI Blazor-App, die auf Android, iOS, macOS und Windows bereitgestellt werden kann. Eine schrittweise Anleitung zum Erstellen einer .NET MAUI Blazor-App finden Sie unter Erstellen einer .NET MAUI Blazor-App.

Das BlazorWebView, das von der Projektvorlage erstellt wird, ist in MainPage.xaml definiert und verweist auf das Stammverzeichnis der Blazor-App:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:BlazorWebViewDemo"
             x:Class="BlazorWebViewDemo.MainPage"
             BackgroundColor="{DynamicResource PageBackgroundColor}">

    <BlazorWebView HostPage="wwwroot/index.html">
        <BlazorWebView.RootComponents>
            <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
        </BlazorWebView.RootComponents>
    </BlazorWebView>

</ContentPage>

Die Stamm-Razor-Komponente für die App befindet sich in Main.razor, die Razor zu einem Typ namens Main im Stamm-Namenspace der App kompiliert. Die restlichen Razor-Komponenten befinden sich in den Projektordnern Pages und Shared und sind identisch mit den Komponenten, die in der Standard-Blazor-Webvorlage verwendet werden. Statische Web-Assets für die App befinden sich im Ordner wwwroot.

Hinzufügen einer BlazorWebView zu einer bestehenden App

Das Verfahren zum Hinzufügen eines BlazorWebView zu einer bestehenden .NET MAUI-App ist wie folgt:

  1. Fügen Sie das Razor SDK, Microsoft.NET.Sdk.Razor zu Ihrem Projekt hinzu, indem Sie die erste Zeile der CSPROJ-Projektdatei bearbeiten:

    <Project Sdk="Microsoft.NET.Sdk.Razor">
    

    Das Razor SDK wird benötigt, um Projekte zu erstellen und zu verpacken, die Razor-Dateien für Blazor-Projekte enthalten.

  2. Fügen Sie die Stammkomponente Razor für die App zum Projekt hinzu.

  3. Fügen Sie Ihre Razor-Komponenten zu den Projektordnern mit den Namen Pages und Shared hinzu.

  4. Fügen Sie Ihre statischen Web-Assets in einen Projektordner namens wwwroot ein.

  5. Fügen Sie alle optionalen _Imports.razor Dateien zu Ihrem Projekt hinzu.

  6. Fügen Sie BlazorWebView zu einer Seite in Ihrer .NET MAUI-App hinzu und verweisen Sie auf das Stammverzeichnis der Blazor-App:

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:MyBlazorApp"
                 x:Class="MyBlazorApp.MainPage">
    
        <BlazorWebView HostPage="wwwroot/index.html">
            <BlazorWebView.RootComponents>
                <RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
            </BlazorWebView.RootComponents>
        </BlazorWebView>
    
    </ContentPage>
    
  7. Ändern Sie die CreateMauiApp-Methode Ihrer MauiProgram-Klasse, um das BlazorWebView-Steuerelement für die Verwendung in Ihrer App zu registrieren. Rufen Sie dazu im IServiceCollection-Objekt die AddMauiBlazorWebView-Methode auf, um Komponenten-Webansichtsdienste zur Dienstesammlung hinzuzufügen:

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });
    
            builder.Services.AddMauiBlazorWebView();
    #if DEBUG
            builder.Services.AddBlazorWebViewDeveloperTools();
    #endif
            // Register any app services on the IServiceCollection object
            // e.g. builder.Services.AddSingleton<WeatherForecastService>();
    
            return builder.Build();
        }
    }
    

Zugreifen auf bereichsbezogene Dienste über die native Benutzeroberfläche

BlazorWebView verfügt über eine TryDispatchAsync-Methode, die einen angegebenen Action<ServiceProvider> asynchron aufrufen und die in Razor-Komponenten verfügbaren Scoped Services übergeben kann. Auf diese Weise kann Code über die native Benutzeroberfläche auf bereichsbezogene Dienste zugreifen, z. B. NavigationManager:

private async void OnMyMauiButtonClicked(object sender, EventArgs e)
{
    var wasDispatchCalled = await blazorWebView.TryDispatchAsync(sp =>
    {
        var navMan = sp.GetRequiredService<NavigationManager>();
        navMan.CallSomeNavigationApi(...);
    });

    if (!wasDispatchCalled)
    {
        // Consider what to do if it the dispatch fails - that's up to your app to decide.
    }
}

Diagnostizieren von Problemen

BlazorWebView verfügt über eine integrierte Protokollierung, die Ihnen bei der Diagnose von Problemen in Ihrer Blazor Hybrid-App helfen kann. Es gibt zwei Schritte, um diese Protokollierung zu aktivieren:

  1. Aktivieren Sie BlazorWebView und verwandte Komponenten zum Protokollieren von Diagnoseinformationen.
  2. Konfigurieren Sie einen Logger, der die Protokollausgabe an einen Ort schreibt, an dem Sie sie einsehen können.

Weitere Informationen zur Protokollierung finden Sie unter Protokollierung in C# und .NET.

BlazorWebView-Protokollierung einschalten

Die gesamte Konfiguration der Protokollierung kann als Teil der Dienstregistrierung im System für die Injektion von Abhängigkeiten durchgeführt werden. Um die maximale Protokollierung für BlazorWebView und verwandte Komponenten unter dem Microsoft.AspNetCore.Components.WebView-Namenspace zu aktivieren, fügen Sie den folgenden Code dort ein, wo die Dienste Ihrer App registriert sind:

services.AddLogging(logging =>
{
    logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});

Um die maximale Protokollierung für jede Komponente zu aktivieren, die Microsoft.Extensions.Logging verwendet, könnten Sie alternativ folgenden Code verwenden:

services.AddLogging(logging =>
{
    logging.SetMinimumLevel(LogLevel.Trace);
});

Konfigurieren der Protokollierungsausgabe und Anzeigen der Ausgabe

Nachdem Sie die Komponenten so konfiguriert haben, dass sie Protokollinformationen schreiben, müssen Sie konfigurieren, wohin die Logger die Protokolle schreiben sollen, und dann die Protokollausgabe anzeigen.

Die Debug Logging Provider schreiben die Ausgabe mit Debug-Anweisungen, und die Ausgabe kann in Visual Studio angezeigt werden.

Um den Debug Logging Provider zu konfigurieren, fügen Sie zunächst in Ihrem Projekt einen Verweis auf das Microsoft.Extensions.Logging.Debug NuGet-Paket hinzu. Registrieren Sie dann den Anbieter innerhalb des Aufrufs von AddLogging, den Sie im vorherigen Schritt hinzugefügt haben, indem Sie die Erweiterungsmethode AddDebug aufrufen:

services.AddLogging(logging =>
{
    logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
    logging.AddDebug();
});

Wenn Sie die App von Visual Studio aus ausführen (mit aktiviertem Debugging), können Sie die Debug-Ausgabe im Fenster Ausgabe von Visual Studio anzeigen.

Wiedergeben von Inlinevideos unter iOS

Zum Wiedergeben von Inlinevideos in einer Blazor-Hybrid-App unter iOS in einem BlazorWebView sollten Sie:

  • Setzen Sie die UrlLoadingStrategy-Eigenschaft auf OpenInWebView. Dies kann im Ereignishandler für das UrlLoading-Ereignis erreicht werden:

    private void BlazorUrlLoading(object? sender, UrlLoadingEventArgs e)
    {
    #if IOS
        e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView;
    #endif
    }
    
  • Stellen Sie sicher, dass die AllowsInlineMediaPlayback-Eigenschaft in einem Configuration-Objekt auf true festgelegt ist. Dies kann im Ereignishandler für das BlazorWebViewInitializing-Ereignis erreicht werden:

    private void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
    {
    #if IOS
        e.Configuration.AllowsInlineMediaPlayback = true;
    #endif
    }
    

Behebung von Entsorgungs-Deadlocks unter Android

Standardmäßig führt BlazorWebView eine async-over-sync-Entsorgung durch, was bedeutet, dass der Thread blockiert wird, bis die async-Beseitigung abgeschlossen ist. Dies kann jedoch zu Deadlocks führen, wenn bei der Beseitigung Code für denselben Thread ausgeführt werden muss (da der Thread beim Warten blockiert wird).

Wenn Sie auf Android mit BlazorWebView hängen bleiben, sollten Sie einen Schalter AppContext in der Methode CreateMauiApp in MauiProgram.cs aktivieren:

AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", true);

Dieser Schalter ermöglicht BlazorWebView das Auslösen und Vergessen der asynchronen Entsorgung, die auftritt, und behebt daher die meisten der Entsorgungs-Deadlocks, die auf Android auftreten.

Warnung

Die Aktivierung dieses Schalters bedeutet, dass die Entsorgung zurückkehren kann, bevor alle Objekte verworfen werden, was zu Verhaltensänderungen in Ihrer App führen kann. Die verworfenen Elemente sind teilweise die eigenen internen Typen von Blazor, aber auch App-definierte Typen wie bereichsbezogene Dienste, die innerhalb des Teils BlazorWebView Ihrer App verwendet werden.

Hosten von Inhalten mithilfe des Legacyverhaltens unter iOS und Mac Catalyst

Unter iOS und Mac Catalyst 18 hat sich das Standardverhalten für das Hosten von Inhalten in einer BlazorWebView zu localhost geändert. Die interne 0.0.0.1-Adresse, die zum Hosten von Inhalten verwendet wurde, funktioniert nicht mehr und führt dazu, das BlazorWebView keine Inhalte lädt und ein leeres Rechteck angezeigt wird.

Um die 0.0.0.1-Adresse zu verwenden, fügen Sie den folgenden Code zur CreateMauiApp-Methode in MauiProgram.cs hinzu:

// Set this switch to use the LEGACY behavior of always using 0.0.0.1 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);