Hospedaje de una aplicación web Blazor en una aplicación .NET MAUI mediante BlazorWebView
BlazorWebView de .NET Multi-platform App UI (.NET MAUI) es un control que permite hospedar una aplicación web blazor en tu aplicación .NET MAUI. Estas aplicaciones, conocidas como aplicaciones híbridas de Blazor, permiten que una aplicación web blazor se integre con las características de la plataforma y los controles de interfaz de usuario. El control BlazorWebView se puede agregar a cualquier página de una aplicación .NET MAUI y apuntar a la raíz de la aplicación Blazor. Loscomponentes de Razor se ejecutan de forma nativa en el proceso de .NET y representan la interfaz de usuario web en un control de vista web incrustado. En .NET MAUI, las aplicaciones híbridas de Blazor se pueden ejecutar en todas las plataformas compatibles con .NET MAUI.
BlazorWebView define las siguientes propiedades:
- HostPage, de tipo
string?
, que define la página raíz de la aplicación web Blazor. - RootComponents, de tipo
RootComponentsCollection
, que especifica la colección de componentes raíz que se pueden agregar al control. - StartPath, de tipo
string
, que define la ruta de acceso para la navegación inicial dentro del contexto de navegación Bazor cuando el componente Blazor termina de cargarse.
La clase RootComponent define las propiedades siguientes:
- Selector, de tipo
string?
, que define la cadena del selector CSS que especifica dónde se debe colocar el componente en el documento. - ComponentType, de tipo
Type?
, que define el tipo del componente raíz. - Parameters, de tipo
IDictionary<string, object?>?
, que representa un diccionario opcional de parámetros que se va a pasar al componente raíz.
Además, BlazorWebView define los eventos siguientes:
- BlazorWebViewInitializing, con un objeto complementario
BlazorWebViewInitializingEventArgs
, que se genera antes de inicializar BlazorWebView. Este evento habilita la personalización de la configuración BlazorWebView. - BlazorWebViewInitialized, con un objeto
BlazorWebViewInitializedEventArgs
complementario, que se genera después de inicializarse BlazorWebView, pero antes de que se haya representado cualquier componente. Este evento permite la recuperación de la instancia de vista web específica de la plataforma. - UrlLoading, con un objeto
UrlLoadingEventArgs
adjunto, se genera cuando se hace clic en un hipervínculo dentro de BlazorWebView. Este evento habilita la personalización de si se abre un hipervínculo en BlazorWebView, en una aplicación externa o si se cancela el intento de carga de direcciones URL.
Los componentes de Razor existentes se pueden usar en una aplicación Blazor de .NET MAUI moviendo el código a la aplicación o haciendo referencia a una biblioteca de clases o a un paquete existente que contiene el componente. Para obtener más información, consultaReutilización de componentes Razor en ASP.NET Core Blazor Hybrid.
Las herramientas de desarrollo del explorador se pueden usar para inspeccionar aplicaciones Blazor de .NET MAUI. Para obtener más información, consulta Uso de herramientas para desarrolladores de exploradores con aplicaciones Blazor Hybrid de ASP.NET Core.
Nota:
Aunque Visual Studio instala todas las herramientas necesarias para desarrollar aplicaciones Blazor de .NET MAUI, los usuarios finales de aplicaciones Blazor de .NET MAUI en Windows deben instalar el tiempo de ejecución de WebView2.
Para obtener más información sobre las aplicaciones híbridas de Blazor, consulta Blazor Hybrid de ASP.NET Core.
Creación de una aplicación Blazor de .NET MAUI
Una aplicación Blazor de NET MAUI se puede crear en Visual Studio mediante la plantilla Blazor de .NET MAUI:
Esta plantilla de proyecto crea una aplicación Blazor .NET MAUI de destino múltiple que se puede implementar en Android, iOS, macOS y Windows. Para obtener instrucciones paso a paso sobre cómo crear una aplicación Blazor de .NET MAUI, consulta Compilación de una aplicación Blazor de .NET MAUI.
La plantilla de proyecto BlazorWebView creada se define en MainPage.xaml y apunta a la raíz de la aplicación 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>
El componente de Razor raíz de la aplicación está en Main.razor, que Razor compila en un tipo denominado Main
en el espacio de nombres raíz de la aplicación. El resto de los componentes de Razor se encuentran en las carpetas de proyecto Pages y Shared, y son idénticas a los componentes usados en la plantilla web de Blazor predeterminada. Los recursos web estáticos de la aplicación se encuentran en la carpeta wwwroot.
Adición de BlazorWebView a una aplicación existente
El proceso para agregar un BlazorWebView a una aplicación .NET MAUI existente es el siguiente:
Agrega el SDK
Microsoft.NET.Sdk.Razor
de Razor al proyecto editando su primera línea del archivo de proyecto CSPROJ:<Project Sdk="Microsoft.NET.Sdk.Razor">
El SDK de Razor es necesario para compilar y empaquetar proyectos que contengan archivos Razor para proyectos de Blazor.
Agrega el componente de Razor raíz de la aplicación al proyecto.
Agrega los componentes de Razor a las carpetas de proyecto denominadas Pages y Shared.
Agrega los recursos web estáticos a una carpeta de proyecto denominada wwwroot.
Agrega los archivos opcionales _Imports.razor al proyecto.
Agrega un elemento BlazorWebView a una página en la aplicación .NET MAUI y apunta a la raíz de la aplicación 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>
Modifica el método
CreateMauiApp
de la claseMauiProgram
para registrar el control BlazorWebView para su uso en la aplicación. Para ello, en el objetoIServiceCollection
, llama al métodoAddMauiBlazorWebView
para agregar servicios de vista web de componentes a la colección de servicios: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(); } }
Acceso a servicios con ámbito desde la interfaz de usuario nativa
BlazorWebView tiene un método TryDispatchAsync que puede llamar a un Action<ServiceProvider>
especificado de forma asincrónica y pasa los servicios con ámbito disponibles en los componentes de Razor. Esto permite que el código de la interfaz de usuario nativa acceda a servicios con ámbito como 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.
}
}
Diagnóstico de problemas
BlazorWebView tiene un registro integrado que puede ayudarte a diagnosticar problemas en la aplicación Blazor Hybrid. Hay dos pasos para habilitar este registro:
- Habilite BlazorWebView y los componentes relacionados para registrar la información de diagnóstico.
- Configura un registrador para que escriba la salida del registro donde puedas verla.
Para obtener más información sobre el registro, consulta Registro en C# y en .NET.
Habilitación del registro de BlazorWebView
Toda la configuración de registro se puede realizar como parte del registro del servicio en el sistema de inserción de dependencias. Para habilitar el registro máximo para BlazorWebView y los componentes relacionados en el espacio de nombres Microsoft.AspNetCore.Components.WebView, agrega el siguiente código donde están registrados los servicios de la aplicación.
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
Como alternativa, para habilitar el registro máximo para cada componente que use Microsoft.Extensions.Logging, puedes usar el siguiente código:
services.AddLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Trace);
});
Configuración de la salida del registro y visualización de la salida
Después de configurar los componentes para escribir información de registro, configura dónde los registradores deben escribir información de registro.
Los proveedores de registro de depuración escriben la salida mediante instrucciones Debug
y la salida se puede ver desde Visual Studio.
Para configurar el proveedor de registro de Depuración, agrega primero una referencia en el proyecto al paquete NuGet Microsoft.Extensions.Logging.Debug
. Después registra el proveedor dentro de la llamada a AddLogging que agregaste en el paso anterior llamando al método de extensión AddDebug:
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
logging.AddDebug();
});
Cuando la aplicación se ejecuta desde Visual Studio con la depuración habilitada, la salida de depuración aparece en la ventana Salida de Visual Studio.
Reproducción de vídeo insertado en iOS
Para reproducir vídeo insertado en una aplicación híbrida de Blazor en iOS, en un BlazorWebView, debe:
Establezca la propiedad UrlLoadingStrategy en
OpenInWebView
. Esto se puede lograr en el controlador de eventos para el UrlLoading evento:private void BlazorUrlLoading(object? sender, UrlLoadingEventArgs e) { #if IOS e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView; #endif }
Asegúrese de que la propiedad
AllowsInlineMediaPlayback
de un objetoConfiguration
está establecida entrue
. Esto se puede lograr en el controlador de eventos para el evento BlazorWebViewInitializing:private void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e) { #if IOS e.Configuration.AllowsInlineMediaPlayback = true; #endif }
Corrección de interbloqueos de eliminación en Android
De forma predeterminada, BlazorWebView realiza la eliminación asincrónica a través de la sincronización, lo que significa que bloquea el subproceso hasta que se complete la eliminación asincrónica. Sin embargo, esto puede provocar interbloqueos si la eliminación necesita ejecutar código en el mismo subproceso (porque el subproceso está bloqueado mientras espera).
Si encuentras bloqueos en Android con BlazorWebView, debes habilitar un modificador AppContext en el método CreateMauiApp
en MauiProgram.cs:
AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", true);
Este modificador permite a BlazorWebView activar y olvidar la eliminación asincrónica que se produce y, como resultado, corrige la mayoría de los interbloqueos de eliminación que se producen en Android.
Advertencia
Habilitar este modificador significa que la eliminación puede devolverse antes de que se eliminen todos los objetos, lo que puede provocar cambios de comportamiento en la aplicación. Los elementos que se eliminan son en parte los propios tipos internos de Blazor, pero también tipos definidos por la aplicación, como los servicios con ámbito que se usan dentro de la parte BlazorWebView de la aplicación.
Hospedaje de contenido mediante el comportamiento heredado en iOS y Mac Catalyst
En iOS y Mac Catalyst 18, el comportamiento predeterminado para hospedar contenido de una BlazorWebView ha cambiado a localhost
. La dirección interna 0.0.0.1
se usa para hospedar el contenido que ya no funciona y, como resultado, BlazorWebView no carga ningún contenido y se representa como un rectángulo vacío.
Para participar en el uso de la 0.0.0.1
dirección, agrega el código siguiente al método CreateMauiApp
en MauiProgram.cs:
// Set this switch to use the LEGACY behavior of always using 0.0.0.1 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);