Ospitare un'app Web Blazor in un'app MAUI .NET usando BlazorWebView
L'interfaccia utente dell'app multipiattaforma .NET (.NET MAUI) BlazorWebView è un controllo che consente di ospitare un'app Web Blazor nell'app MAUI .NET. Queste app, note come app ibride Blazor, consentono di integrare un'app Web Blazor con funzionalità della piattaforma e controlli dell'interfaccia utente. Il BlazorWebView controllo può essere aggiunto a qualsiasi pagina di un'app MAUI .NET e punta alla radice dell'app Blazor. I componenti Razor vengono eseguiti in modo nativo nel processo .NET ed esegue il rendering dell'interfaccia utente Web in un controllo visualizzazione Web incorporato. In .NET MAUI le app blazor ibride possono essere eseguite in tutte le piattaforme supportate da .NET MAUI.
BlazorWebView definisce le proprietà seguenti:
-
HostPage, di tipo
string?
, che definisce la pagina radice dell'app Web Blazor. -
RootComponents, di tipo
RootComponentsCollection
, che specifica la raccolta di componenti radice che possono essere aggiunti al controllo . -
StartPath, di tipo
string
, che definisce il percorso per la navigazione iniziale all'interno del contesto di navigazione Blazor al termine del caricamento del componente Blazor.
La RootComponent classe definisce le proprietà seguenti:
-
Selector, di tipo
string?
, che definisce la stringa del selettore CSS che specifica dove deve essere inserito il componente nel documento. -
ComponentType, di tipo
Type?
, che definisce il tipo del componente radice. -
Parameters, di tipo
IDictionary<string, object?>?
, che rappresenta un dizionario facoltativo di parametri da passare al componente radice.
Definisce inoltre BlazorWebView gli eventi seguenti:
-
BlazorWebViewInitializing, con un oggetto associato
BlazorWebViewInitializingEventArgs
, che viene generato prima dell'inizializzazione BlazorWebView di . Questo evento abilita la personalizzazione della BlazorWebView configurazione. -
BlazorWebViewInitialized, con un oggetto associato
BlazorWebViewInitializedEventArgs
, che viene generato dopo l'inizializzazione BlazorWebView di ma prima del rendering di qualsiasi componente. Questo evento abilita il recupero dell'istanza della visualizzazione Web specifica della piattaforma. -
UrlLoading, con un oggetto associato
UrlLoadingEventArgs
, viene generato quando viene fatto clic su un collegamento ipertestuale all'interno di un oggetto BlazorWebView. Questo evento consente di personalizzare se un collegamento ipertestuale viene aperto in BlazorWebView, in un'app esterna o se il tentativo di caricamento dell'URL viene annullato.
I componenti Razor esistenti possono essere usati in un'app Blazor MAUI .NET spostando il codice nell'app o facendo riferimento a una libreria di classi o a un pacchetto esistente che contiene il componente. Per altre informazioni, vedere Riutilizzare i componenti Razor in ASP.NET Core Blazor Hybrid.
Gli strumenti di sviluppo del browser possono essere usati per esaminare le app Blazor MAUI .NET. Per altre informazioni, vedere Usare gli strumenti di sviluppo del browser con ASP.NET Core Blazor Hybrid.
Nota
Mentre Visual Studio installa tutti gli strumenti necessari per sviluppare app Blazor .NET MAUI, gli utenti finali di app Blazor .NET MAUI in Windows devono installare il runtime WebView2 .
Per altre informazioni sulle app ibride Blazor, vedere ASP.NET Core Blazor Hybrid.
Creare un'app Blazor .NET MAUI
Un'app Blazor .NET MAUI può essere creata in Visual Studio dal modello di app Blazor .NET MAUI:
Questo modello di progetto crea un'app Blazor .NET multi-destinazione che può essere distribuita in Android, iOS, macOS e Windows. Per istruzioni dettagliate sulla creazione di un'app Blazor MAUI .NET, vedere Creare un'app Blazor MAUI .NET.
L'oggetto BlazorWebView creato dal modello di progetto è definito in MainPage.xaml e punta alla radice dell'app Blazor:
<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>
Il componente Razor radice Main
Il resto dei componenti Razor si trovano nelle cartelle Pagine e Progetto condiviso e sono identici ai componenti usati nel modello Web Blazor predefinito. Gli asset Web statici per l'app si trovano nella cartella wwwroot .
Aggiungere un oggetto BlazorWebView a un'app esistente
Il processo per aggiungere un BlazorWebView oggetto a un'app MAUI .NET esistente è il seguente:
Aggiungere Razor SDK
Microsoft.NET.Sdk.Razor
al progetto modificando la prima riga del file di progetto CSPROJ:<Project Sdk="Microsoft.NET.Sdk.Razor">
Razor SDK è necessario per compilare e creare progetti contenenti file Razor per i progetti Blazor.
Aggiungere il componente Razor radice per l'app al progetto.
Aggiungere i componenti Razor alle cartelle di progetto denominate Pages e Shared.
Aggiungere gli asset Web statici a una cartella di progetto denominata wwwroot.
Aggiungere eventuali file facoltativi _Imports.razor al progetto.
Aggiungere un oggetto BlazorWebView a una pagina nell'app MAUI .NET e puntare alla radice dell'app Blazor:
<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>
Modificare il
CreateMauiApp
metodo dellaMauiProgram
classe per registrare il BlazorWebView controllo da usare nell'app. A tale scopo, nell'oggetto IServiceCollection chiamare ilAddMauiBlazorWebView
metodo per aggiungere servizi visualizzazione Web componenti alla raccolta di servizi: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(); } }
Questo codice abilita anche gli strumenti di sviluppo nei controlli WebView sottostanti, quando l'app è in esecuzione nella configurazione di debug.
Accedere ai servizi con ambito dall'interfaccia utente nativa
BlazorWebView dispone di un TryDispatchAsync metodo che può chiamare un oggetto specificato Action<ServiceProvider>
in modo asincrono e passare i servizi con ambito disponibili nei componenti Razor. In questo modo il codice dall'interfaccia utente nativa può accedere ai servizi con ambito, NavigationManagerad esempio :
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.
}
}
Diagnosi dei problemi
BlazorWebView include la registrazione predefinita che consente di diagnosticare i problemi nell'app Blazor Hybrid. Per abilitare questa registrazione sono necessari due passaggi:
- Abilitare e i componenti correlati per registrare BlazorWebView le informazioni di diagnostica.
- Configurare un logger per scrivere l'output del log in cui è possibile visualizzarlo.
Per altre informazioni sulla registrazione, vedere Registrazione in C# e .NET.
Abilitare la registrazione blazorWebView
Tutte le configurazioni di registrazione possono essere eseguite come parte della registrazione del servizio nel sistema di inserimento delle dipendenze. Per abilitare la registrazione massima per BlazorWebView e i componenti correlati nello Microsoft.AspNetCore.Components.WebView spazio dei nomi, aggiungere il codice seguente alla posizione in cui vengono registrati i servizi dell'app:
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
In alternativa, per abilitare la registrazione massima per ogni componente che usa Microsoft.Extensions.Logging, è possibile usare il codice seguente:
services.AddLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Trace);
});
Configurare l'output di registrazione e visualizzare l'output
Dopo aver configurato i componenti per scrivere le informazioni di log, è necessario configurare dove i logger devono scrivere i log e quindi visualizzare l'output del log.
I provider di registrazione debug scrivono l'output usando Debug
istruzioni e l'output può essere visualizzato da Visual Studio.
Per configurare il provider di registrazione debug , aggiungere prima di tutto un riferimento nel progetto al Microsoft.Extensions.Logging.Debug
pacchetto NuGet. Registrare quindi il provider all'interno della chiamata a AddLogging cui è stato aggiunto nel passaggio precedente chiamando il AddDebug metodo di estensione:
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
logging.AddDebug();
});
Quando si esegue l'app da Visual Studio (con debug abilitato), è possibile visualizzare l'output di debug nella finestra Output di Visual Studio.
Riprodurre video inline in iOS
Per riprodurre video inline in un'app ibrida Blazor in iOS, in un BlazorWebView, è necessario:
Impostare la proprietà UrlLoadingStrategy su
OpenInWebView
. Questa operazione può essere eseguita nel gestore eventi per l'evento UrlLoading :private void BlazorUrlLoading(object? sender, UrlLoadingEventArgs e) { #if IOS e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView; #endif }
Assicurarsi che la
AllowsInlineMediaPlayback
proprietà in unConfiguration
oggetto sia impostata sutrue
. Questa operazione può essere eseguita nel gestore eventi per l'evento BlazorWebViewInitializing :private void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e) { #if IOS e.Configuration.AllowsInlineMediaPlayback = true; #endif }
Deadlock di eliminazione in Android
Per impostazione predefinita, BlazorWebView genera e dimentica l'eliminazione asincrona dell'oggetto sottostante WebViewManager
. In questo modo si riduce il rischio che si verifichino deadlock di eliminazione in Android.
Avviso
Questo comportamento predefinito fire-and-forget significa che lo smaltimento può restituire prima che tutti gli oggetti vengano eliminati, che possono causare modifiche comportamentali nell'app. Gli elementi eliminati sono tipi interni di Blazor parzialmente personalizzati, ma anche tipi definiti dall'app, ad esempio i servizi con ambito usati all'interno della BlazorWebView parte dell'app.
Per rifiutare esplicitamente questo comportamento, è necessario configurare l'app per bloccare l'eliminazione tramite un'opzione AppContext nel CreateMauiApp
metodo nella MauiProgram
classe:
AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", false);
Se l'app è configurata per bloccare l'eliminazione tramite questa opzione, BlazorWebView esegue l'eliminazione asincrona tramite sincronizzazione, il che significa che blocca il thread fino al completamento dell'eliminazione asincrona. Tuttavia, questo può causare deadlock se l'eliminazione deve eseguire codice nello stesso thread (perché il thread è bloccato durante l'attesa).
Usa il comportamento legacy per ospitare i contenuti
Il comportamento predefinito per l'hosting dei contenuti in un BlazorWebView è stato modificato in 0.0.0.1
. L'indirizzo interno 0.0.0.0
usato per ospitare il contenuto non funziona più e comporta il BlazorWebView mancato caricamento di alcun contenuto e il rendering come rettangolo vuoto.
Per acconsentire esplicitamente all'uso dell'indirizzo 0.0.0.0
, aggiungere il codice seguente al CreateMauiApp
metodo in MauiProgram.cs:
// Set this switch to use the LEGACY behavior of always using 0.0.0.0 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);