如何让WebAssembly组件在托管式Blazor Web App项目中正常运行?
操作背景
完全使用VS2022、.NET 8官方模板操作,未添加自定义代码:
操作步骤
步骤1:创建目标框架为.NET 8的Blazor Web App项目
DemoServer,使用标准「Blazor Web App」模板。修改App.razor将全局渲染模式设为InteractiveServer:<head> <HeadOutlet @rendermode="InteractiveServer" /> </head> <body> <Routes @rendermode="InteractiveServer" /> <script src="_framework/blazor.web.js"></script> </body>步骤2:创建提供Wasm组件的WebAssembly项目
WasmFileEditor,基于「Blazor WebAssembly App Empty」模板。添加Razor组件FileEditor.razor:<h3>File Editor Wasm Component</h3> @code { }单独运行该项目时,
Program.cs中的断点可正常命中。步骤3:将
WasmFileEditor项目引用添加到DemoServer;为WasmFileEditor安装NuGet包Microsoft.AspNetCore.Components.WebAssembly.Server。修改WasmFileEditor的Program.cs,移除Layout文件夹、App.razor等冗余内容,剩余代码如下:using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using WasmFileEditor; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); await builder.Build().RunAsync();
遇到的问题
切换到添加了
FileEditor组件的Counter页面时,出现运行时错误:Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
Unhandled exception in circuit bezeKQ89kvCeszvNMm1N8p1w6wo0QP_y3HZBEBM5_SU
System.NotSupportedException: Cannot create a component of type 'DemoServer.Components.Pages.Counter' because its render mode 'Microsoft.AspNetCore.Components.Web.InteractiveWebAssemblyRenderMode' is not supported by interactive server-side rendering.将
App.razor中的<Routes @rendermode="InteractiveServer" />改为<Routes />后,页面和组件可显示,但控制台出现错误:ManagedError: One or more errors occurred. (Root component type 'DemoServer.Components.Pages.Counter' could not be found in the assembly 'DemoServer'.)
额外问题:
WasmFileEditor项目Program.cs中的断点未命中,组件无法获取DI注入的HttpClient。
解决方案
1. 解决渲染模式冲突问题
全局设置InteractiveServer渲染模式后,若页面引用Wasm组件,需为该页面单独指定InteractiveWebAssembly渲染模式,而非直接移除全局渲染模式:
- 打开
Counter.razor,在页面顶部添加渲染模式声明:
该页面会以Wasm模式运行,与全局Server模式无冲突。@page "/counter" @rendermode InteractiveWebAssembly
2. 修复Wasm项目的配置与DI问题
配置DemoServer的服务与路由:在
DemoServer的Program.cs中添加Wasm支持的配置:var builder = WebApplication.CreateBuilder(args); // 添加Wasm组件支持 builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents(); var app = builder.Build(); // 映射Wasm静态资源 app.MapWebAssemblyAssets(); app.UseStaticFiles(); app.UseAntiforgery(); app.MapRazorComponents<App>() .AddInteractiveServerRenderMode() .AddInteractiveWebAssemblyRenderMode(); app.Run();恢复Wasm项目的根组件:无需移除
App.razor,简化内容即可,保证Wasm运行时能找到根组件:<!-- WasmFileEditor/App.razor --> <Router AppAssembly="@typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="@routeData" /> </Found> </Router>此修改可让Wasm的
Program.cs断点正常命中。确保HttpClient注入正常:Wasm项目中注册的
HttpClient会自动被组件获取,只要Wasm运行时初始化正确,无需额外配置。
3. 验证断点与组件运行
- 确保
WasmFileEditor项目的生成配置为「Debug」,启动项目时选择DemoServer作为启动项。 - 运行项目后,切换到Counter页面,Wasm的
Program.cs断点会命中,FileEditor组件可正常获取注入的HttpClient。
内容的提问来源于stack exchange,提问作者Michael EstrinOne

