培训
模块
使用 Blazor 混合和 .NET MAUI 生成移动和桌面应用 - Training
了解如何设置开发环境,以及如何使用 Blazor、.NET MAUI 和 C# 生成你的首个跨平台混合应用。
.NET 多平台应用 UI (.NET MAUI) BlazorWebView 是一个控件,可用于在 .NET MAUI 应用中托管 Blazor Web 应用。 这些应用称为 Blazor 混合应用,使 Blazor Web 应用能够与平台功能和 UI 控件集成。 BlazorWebView 控件可以添加到 .NET MAUI 应用的任何页面,并指向 Blazor 应用的根目录。 Razor 组件在 .NET 进程中本机运行,并将 Web UI 呈现到嵌入式 Web 视图控件。 在 .NET MAUI 中,Blazor 混合应用可以在 .NET MAUI 支持的所有平台上运行。
BlazorWebView 定义以下属性:
string?
,用于定义 Blazor Web 应用的根目录页。RootComponentsCollection
,指定可添加到控件的根组件的集合。string
,用于定义 Blazor 导航上下文中完成加载 Blazor 组件时初始导航的路径。RootComponent 类定义以下属性:
string?
,用于定义 CSS 选择器字符串,该字符串指定应在文档中放置组件的位置。Type?
,用于定义根组件的类型。IDictionary<string, object?>?
,用于表示要传递给根组件的可选参数字典。此外,BlazorWebView 定义以下事件:
BlazorWebViewInitializingEventArgs
对象,该对象在 BlazorWebView 初始化之前引发。 此事件允许自定义 BlazorWebView 配置。BlazorWebViewInitializedEventArgs
对象,该对象在 BlazorWebView 初始化后,呈现任何组件之前引发。 此事件允许检索特定于平台的 Web 视图实例。UrlLoadingEventArgs
对象,单击 BlazorWebView 内某个超链接时引发。 此事件允许自定义超链接是否在 BlazorWebView 中,在外部应用中打开,或者是否 URL 加载尝试已取消。现有 Razor 组件可以通过将代码移动到应用中,或通过引用包含组件的现有类库或包,在 .NET MAUI Blazor 应用中使用。 详情请参阅在 ASP.NET Core Blazor Hybrid 中重复使用 Razor 组件。
浏览器开发者工具可用于检查 .NET MAUI Blazor 应用。 有关详细信息,请参阅 将浏览器开发者工具与“ASP.NET Core Blazor 混合”配合使用。
备注
虽然 Visual Studio 安装开发 .NET MAUI Blazor 应用所需的所有工具,但 Windows 上的 .NET MAUI Blazor 应用的最终用户必须安装 WebView2 运行时。
有关 Blazor 混合应用的详细信息,请参阅 ASP.NET Core Blazor 混合。
.NET MAUI Blazor 应用可以通过 .NET MAUI Blazor 应用模板在Visual Studio中创建:
这个项目模板创建了一个多目标 .NET MAUI Blazor 应用,可以部署到 Android、iOS、macOS 和 Windows 上。 有关创建 .NET MAUI Blazor 应用的分步说明,请参阅生成 .NET MAUI Blazor 应用。
项目模板创建的 BlazorWebView 是在 MainPage.xaml 中定义的,并指向 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>
应用的根 Razor 组件 位于 Main.razor 中,Razor 编译为应用程序根命名空间中命名为 Main
的类型。 其余 Razor 组件位于“Pages”和“共享”项目文件夹中,与默认 Blazor Web 模板中使用的组件相同。 应用的静态 Web 资产位于 wwwroot 文件夹中。
向现有 .NET MAUI 应用添加 BlazorWebView 的过程如下所示:
通过编辑其 CSPROJ 项目文件的第一行,将 Razor SDK,Microsoft.NET.Sdk.Razor
添加到项目:
<Project Sdk="Microsoft.NET.Sdk.Razor">
为 Blazor 项目生成和打包包含 Razor 文件的项目需要 Razor SDK。
将应用的根 Razor组件添加到项目中。
将 Razor 组件添加到名为“Pages”和“共享”的项目文件夹中。
将静态 Web 资产添加到名为 wwwroot 的项目文件夹中。
将任何可选的 _Imports.razor 文件添加到项目。
将 BlazorWebView 添加到 .NET MAUI 应用中的页面,并将其指向 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>
修改 CreateMauiApp
类的 MauiProgram
方法,以注册 BlazorWebView 控件以在应用中使用。 为此,请在 IServiceCollection 对象上调用 AddMauiBlazorWebView
方法,将组件 Web 视图服务添加到服务集合:
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();
}
}
当应用在调试配置中运行时,此代码还支持基础 WebView 控件上的开发人员工具。
BlazorWebView 具有一种 TryDispatchAsync 方法,该方法以异步方式调用指定的 Action<ServiceProvider>
,并传入 Razor 组件中可用的作用域服务。 这样,本机 UI 中的代码就可以访问范围内服务,例如 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.
}
}
BlazorWebView 具有内置日志记录,可帮助诊断 Blazor Hybrid 应用中的问题。 启用此日志记录分为两个步骤:
有关日志记录的详细信息,请参阅 C# 和 .NET 中的日志记录。
所有日志记录配置都可以作为依赖项注入系统中服务注册的一部分执行。 要在 BlazorWebView 命名空间下为 Microsoft.AspNetCore.Components.WebView 和相关组件启用最大日志记录,请在应用服务的注册位置添加以下代码:
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
});
或者,使用以下代码为使用 Microsoft.Extensions.Logging 的每个组件启用最大日志记录:
services.AddLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Trace);
});
配置组件以写入日志信息后,需要配置记录器应写入日志的位置,然后查看日志输出。
“调试”日志记录提供程序使用 Debug
语句写入输出,可以从 Visual Studio 查看输出。
要配置“调试”日志记录提供程序,请在项目中添加对 Microsoft.Extensions.Logging.Debug
NuGet 包的引用。 然后,调用 AddLogging 扩展方法,将调用内的提供程序注册至在上一步中添加的 AddDebug:
services.AddLogging(logging =>
{
logging.AddFilter("Microsoft.AspNetCore.Components.WebView", LogLevel.Trace);
logging.AddDebug();
});
从已启用调试的 Visual Studio 运行应用时,可以在 Visual Studio 的“输出”窗口中查看调试输出。
若要在 iOS 上的 Blazor 混合应用中播放内联视频,应在 BlazorWebView 中:
将 UrlLoadingStrategy 属性设置为 OpenInWebView
。 可以在 UrlLoading 事件的事件处理程序中完成此操作:
private void BlazorUrlLoading(object? sender, UrlLoadingEventArgs e)
{
#if IOS
e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView;
#endif
}
确保 AllowsInlineMediaPlayback
对象中的 Configuration
属性设置为 true
。 可以在 BlazorWebViewInitializing 事件的事件处理程序中完成此操作:
private void BlazorWebViewInitializing(object? sender, BlazorWebViewInitializingEventArgs e)
{
#if IOS
e.Configuration.AllowsInlineMediaPlayback = true;
#endif
}
默认情况下, BlazorWebView 触发并忘记基础 WebViewManager
的异步处置。 这减少了在 Android 上发生的处置死锁的可能性。
警告
此触发和忘记的默认行为意味着处置可以在释放所有对象之前返回,这可能会导致应用中的行为更改。 释放的项部分是 Blazor 自己的内部类型,但也包括应用定义的类型,例如应用的 BlazorWebView 部分中使用的作用域服务。
若要选择退出此行为,应将应用配置为通过AppContext类中方法中的CreateMauiApp
MauiProgram
开关阻止释放:
AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", false);
如果应用配置为通过此开关阻止释放, BlazorWebView 则执行异步过度同步处置,这意味着它会阻止线程,直到异步处置完成。 但是,如果处置需要在同一线程上运行代码(因为线程在等待时被阻止),这可能会导致死锁。
在 BlazorWebView 中托管内容的默认行为已更改为 0.0.0.1
。 用于托管内容的内部 0.0.0.0
地址不再有效,导致 BlazorWebView 无法加载任何内容并呈现为空矩形。
若要选择使用 0.0.0.0
地址,请将以下代码添加到 CreateMauiApp
中的 方法:
// Set this switch to use the LEGACY behavior of always using 0.0.0.0 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);
培训
模块
使用 Blazor 混合和 .NET MAUI 生成移动和桌面应用 - Training
了解如何设置开发环境,以及如何使用 Blazor、.NET MAUI 和 C# 生成你的首个跨平台混合应用。