Blazor WebAssembly预渲染传递Shared对象触发AggregateException问题
问题分析与解决方案
问题核心
在启用WebAssemblyPrerendered预渲染的ASP.NET Core托管Blazor WASM应用中,从.cshtml视图通过<component>标签的param-MyObject传递Shared项目自定义类对象到Razor组件时,页面初始渲染正常,但组件内交互(如按钮点击)会触发System.AggregateException,提示无法找到指定类型的参数,导致交互功能失效。
根因
预渲染阶段在服务器端执行,交互阶段切换到客户端WASM运行时。通过param-*传递自定义对象时,服务器端序列化的对象在客户端反序列化时,由于客户端WASM运行时无法识别服务器端传递的类型元数据,导致参数匹配失败,触发异常。
解决方案
方案1:拆解为简单类型或使用可序列化DTO
避免直接传递自定义类对象,将属性拆解为独立简单参数,或定义标记[Serializable]的DTO类,确保两端序列化/反序列化兼容:
- 在Shared项目定义DTO:
[Serializable] public class MyClassDto { public int Id { get; set; } public string Name { get; set; } }
- .cshtml中传递DTO参数:
<component type="typeof(MyComponent)" render-mode="WebAssemblyPrerendered" param-MyObject="new MyClassDto { Id = 1, Name = 'Test' }" />
- 组件接收DTO:
<button @onclick="HandleClick">点击测试</button> @code { [Parameter] public MyClassDto MyObject { get; set; } private void HandleClick() { // 交互逻辑实现 } }
方案2:传递标识+客户端异步获取数据
预渲染时仅传递对象唯一标识(如ID),组件在客户端初始化阶段通过API重新获取完整对象:
- .cshtml中传递ID参数:
<component type="typeof(MyComponent)" render-mode="WebAssemblyPrerendered" param-ObjectId="1" />
- 组件实现:
<button @onclick="HandleClick">点击测试</button> @code { [Inject] private HttpClient Http { get; set; } [Parameter] public int ObjectId { get; set; } private MyClass MyObject { get; set; } protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { MyObject = await Http.GetFromJsonAsync<MyClass>($"api/objects/{ObjectId}"); StateHasChanged(); } } private void HandleClick() { // 使用MyObject的交互逻辑 } }
方案3:配置JSON序列化支持类型信息(不推荐)
通过配置JSON序列化添加类型元数据,让客户端识别服务器端传递的类型,此方案复杂度高且可能引入类型安全问题,仅作为备选:
- 服务器端(Program.cs):
builder.Services.AddControllersWithViews() .AddJsonOptions(options => { options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => typeInfo.Properties.Add(new JsonPropertyInfo { Name = "$type", PropertyType = typeof(string), Get = obj => obj.GetType().AssemblyQualifiedName, Set = (obj, value) => { } }) } }; });
- 客户端(Program.cs):
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }) .AddJsonOptions(options => { options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => typeInfo.Properties.Add(new JsonPropertyInfo { Name = "$type", PropertyType = typeof(string), Get = obj => obj.GetType().AssemblyQualifiedName, Set = (obj, value) => { var type = Type.GetType((string)value); // 自定义类型解析逻辑 } }) } }; });
验证步骤
- 按照上述方案修改代码
- 重新运行应用,测试组件初始渲染和交互功能
- 确认
System.AggregateException不再触发,交互正常
内容的提问来源于stack exchange,提问作者XT Lab
相关产品推荐
相关产品推荐

