You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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类,确保两端序列化/反序列化兼容:

  1. 在Shared项目定义DTO:
[Serializable]
public class MyClassDto
{
    public int Id { get; set; }
    public string Name { get; set; }
}
  1. .cshtml中传递DTO参数:
<component type="typeof(MyComponent)" render-mode="WebAssemblyPrerendered" 
           param-MyObject="new MyClassDto { Id = 1, Name = 'Test' }" />
  1. 组件接收DTO:
<button @onclick="HandleClick">点击测试</button>

@code {
    [Parameter]
    public MyClassDto MyObject { get; set; }

    private void HandleClick()
    {
        // 交互逻辑实现
    }
}

方案2:传递标识+客户端异步获取数据

预渲染时仅传递对象唯一标识(如ID),组件在客户端初始化阶段通过API重新获取完整对象:

  1. .cshtml中传递ID参数:
<component type="typeof(MyComponent)" render-mode="WebAssemblyPrerendered" 
           param-ObjectId="1" />
  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序列化添加类型元数据,让客户端识别服务器端传递的类型,此方案复杂度高且可能引入类型安全问题,仅作为备选:

  1. 服务器端(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) => { }
            }) }
        };
    });
  1. 客户端(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);
                // 自定义类型解析逻辑
            }
        }) }
    };
});

验证步骤

  1. 按照上述方案修改代码
  2. 重新运行应用,测试组件初始渲染和交互功能
  3. 确认System.AggregateException不再触发,交互正常

内容的提问来源于stack exchange,提问作者XT Lab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:00:40