C# Blazor混合应用方法 C#如何使用MAUI Blazor构建桌面和移动应用

3次阅读

Blazor Hybrid 是 Blazor 组件在原生容器中运行的模式,ui 由 Blazorwebview 渲染,C# 逻辑直接调用平台 API,不依赖服务器或 WebAssembly,所有代码在原生进程内执行。

C# Blazor混合应用方法 C#如何使用MAUI Blazor构建桌面和移动应用

Blazor Hybrid 是什么,和传统 Blazor Server/WebAssembly 有什么根本区别

Blazor Hybrid 不是新框架,而是 Blazor 组件在原生容器中运行的模式:UI 用 BlazorWebView 渲染,C# 逻辑直接调用平台 API(如文件系统、摄像头、通知),无需 http 请求或 js 桥接。它不依赖服务器(排除了 BlazorServer),也不打包成 wasm(区别于 BlazorWebAssembly)。核心在于 microsoft.Maui.ControlsMicrosoft.AspNetCore.Components.WebView 的组合。

  • BlazorWebView 是 MAUI 中的控件,负责加载并托管 Razor 组件
  • 所有 C# 代码(包括 @code 块、服务、IHostBuilder 配置)都在原生进程内执行,可直接 new HttpClient()、读写 Environment.GetFolderPath(SpecialFolder.MyDocuments)、调用 Geolocation.default.GetLastKnownLocation()
  • 不需要 wwwroot 静态资源托管,也不走 Kestrel;但若需本地 HTTP API,仍可手动启动 Webapplication.CreateBuilder() 并监听 https://www.php.cn/link/6060d322713797e84f598ea25c812cab

创建 MAUI Blazor 项目的最小必要步骤

用 .NET 7+ SDK(推荐 .NET 8),命令行比 visual studio 向导更可控:

dotnet new maui-blazor -n MyHybridApp

这会生成含以下关键结构的项目:

  • Platforms/ 下各平台入口(androidManifest.xmlInfo.plistProgram.cs 初始化)
  • MainPage.xaml 中包含 BlazorWebView 控件,并绑定 HostPage 属性指向 wwwroot/index.html
  • wwwroot/ 仅用于初始 HTML 容器(不是 SPA 资源目录),实际组件由 App.razor 驱动
  • MauiProgram.cs 中注册服务时,必须调用 builder.Services.AddMauiBlazorWebView() —— 漏掉会导致组件不渲染且无报错

常见错误现象:BlazorWebView 显示空白,控制台无错误。大概率是没调用 AddMauiBlazorWebView(),或 App.razor 中未正确设置 routerAppAssembly

在 Blazor Hybrid 中安全调用平台 API 的方式

不能直接在 @code 块里写 windows.Devices.GeolocationAndroid.App.Activity —— 这些类型跨平台不可用,且 MAUI 已封装统一接口

  • 使用 MAUI 抽象层:例如定位用 Geolocation.Default.GetLastKnownLocation(),相册用 MediaPicker.PickPhoto(),通知用 NotificationManager.Default.Send()
  • 若需深度平台能力(如 Android 自定义 ContentProviderios CoreML 模型),应封装为 C# 接口,在 Platform/ 目录下实现,并通过 DI 注入。例如:
    builder.Services.AddSingleton();
  • 注意线程:MAUI 平台 API 多数要求 UI 线程调用。在 Blazor 组件中使用 InvokeAsync(() => { ... }) 包裹,否则 Android 可能抛 java.Lang.RuntimeException: Can't create handler inside Thread that has not called Looper.prepare()

调试 Blazor Hybrid 应用时最易忽略的三件事

  • 浏览器开发者工具无法直接调试 C# 断点:必须在 VS 或 VS Code 中附加到原生进程(Android 选“Android App”,windows 选“Windows machine”),然后在 .razor 文件中设断点才生效
  • console.WriteLine 输出默认不显示在 VS 输出窗口:需在 MauiProgram.cs 中显式添加日志提供程序,例如
    builder.Logging.AddDebug();

    ,否则 Console.WriteLine("test") 就静默消失

  • 修改 wwwroot/index.html 后,iOS 模拟器可能缓存旧版本:必须 Clean + Rebuild,不能只 Build;Android 则需注意 Assets/ 下的 wwwroot.zip 是否被旧包覆盖

MAUI Blazor 的混合能力很实在,但它的“透明感”恰恰是陷阱来源——你以为在写 Web,其实已深入原生线程和生命周期。越早确认 BlazorWebView 是否真正挂载、平台服务是否完成 DI、日志是否真实输出,越少陷入“页面不动、控制台无声、断点不命”的三重静默状态。

text=ZqhQzanResources