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

如何修复Blazor WASM中System.Text.Json的SerializationNotSupportedParentType相关异常?

解决Blazor WASM PWA部署Azure时System.Text.Json 8.0.5与TelerikDatePicker的序列化异常问题

问题背景

基于.NET7开发Blazor WASM PWA时,为修复NU1903漏洞升级System.Text.Json到兼容.NET7的8.0.5版本,部署到Azure后出现运行时异常,堆栈信息显示SerializationNotSupportedParentType和ThrowNotSupportedException_ConstructorContainsNullParameterNames,本地开发无此问题。经排查:

  • TelerikDatePicker通过反射序列化KeyValuePair进行JS互操作
  • .NET8+的WASM链接器默认会修剪仅通过反射引用的程序集(如KeyValuePair所在程序集)
  • Azure使用了更高版本的.NET运行时(如v9.0),导致System.Text.Json 8.0.5触发该运行时的回归问题
  • 暂不想升级Telerik到修复该问题的v5.0.1版本(重大升级)

解决方案

1. 配置链接器强制保留KeyValuePair类型

在Blazor WASM项目根目录创建或修改BlazorWebAssemblyLinker.xml文件,添加规则避免KeyValuePair被链接器修剪:

<linker>
  <assembly fullname="System.Private.CoreLib">
    <type fullname="System.Collections.Generic.KeyValuePair`2" preserve="all" />
  </assembly>
</linker>

若项目未自动识别该文件,手动在项目文件(.csproj)中添加引用:

<ItemGroup>
  <None Include="BlazorWebAssemblyLinker.xml" />
</ItemGroup>

2. 强制Azure使用.NET7运行时

通过Azure配置指定运行时版本,避免触发高版本运行时的回归问题:

  • Azure门户操作:进入你的App Service → 配置 → 应用程序设置 → 添加新设置,键为DOTNET_VERSION,值为7.0
  • Azure CLI命令:
az webapp config appsettings set --name <你的应用名称> --resource-group <资源组名称> --settings DOTNET_VERSION=7.0

3. 自定义System.Text.Json转换器处理KeyValuePair序列化

编写自定义转换器替代默认的KeyValuePair序列化逻辑,绕开反射依赖问题:

using System.Text.Json;
using System.Text.Json.Serialization;

public class KeyValuePairConverter<TKey, TValue> : JsonConverter<KeyValuePair<TKey, TValue>>
{
    public override KeyValuePair<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        var root = doc.RootElement;
        var key = root.GetProperty("Key").Deserialize<TKey>(options);
        var value = root.GetProperty("Value").Deserialize<TValue>(options);
        return new KeyValuePair<TKey, TValue>(key, value);
    }

    public override void Write(Utf8JsonWriter writer, KeyValuePair<TKey, TValue> value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WritePropertyName("Key");
        JsonSerializer.Serialize(writer, value.Key, options);
        writer.WritePropertyName("Value");
        JsonSerializer.Serialize(writer, value.Value, options);
        writer.WriteEndObject();
    }
}

在Program.cs中注册转换器(根据Telerik实际使用的泛型类型添加对应转换器):

builder.Services.AddControllersWithViews()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new KeyValuePairConverter<object, object>());
        // 若Telerik使用特定类型的KeyValuePair,比如<string, DateTime>,可添加对应转换器:
        // options.JsonSerializerOptions.Converters.Add(new KeyValuePairConverter<string, DateTime>());
    });

内容的提问来源于stack exchange,提问作者Jesper Risager

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:50:14