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

Blazor WebAssembly无法解析JSON到泛型类问题求助

问题解决方法

核心原因

System.Text.Json默认会将继承自List<T>这类集合类型的对象视为纯集合处理:序列化时仅输出集合元素,忽略额外的TotalItems属性;反序列化时无法识别集合外的属性,最终抛出NotSupportedException。


方案一:修改类结构(推荐)

放弃继承List<T>,改用组合方式将集合作为类的属性,让序列化器能正常处理所有成员:

public class GridDto<T>
{
    // 存储列表数据
    public List<T> Items { get; set; } = new List<T>();
    // 总条数
    public int TotalItems { get; set; }

    // 业务构造函数
    public GridDto(IEnumerable<T> items, int totalItems = 0)
    {
        Items = items.ToList();
        TotalItems = totalItems;
    }

    // 必须添加无参构造函数,供反序列化使用
    public GridDto() { }
}

修改后,ReadFromJsonAsync可正常序列化/反序列化Items和TotalItems属性,不会再抛出异常。


方案二:自定义JSON转换器(保留继承结构)

如果必须保留继承List<T>的结构,可编写自定义转换器手动处理序列化和反序列化逻辑:

1. 实现转换器

public class GridDtoConverter<T> : JsonConverter<GridDto<T>>
{
    public override GridDto<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var doc = JsonDocument.ParseValue(ref reader);
        var root = doc.RootElement;
        
        // 解析集合元素和总条数
        var items = root.GetProperty("Items").Deserialize<List<T>>(options);
        var totalItems = root.GetProperty("TotalItems").GetInt32();
        
        return new GridDto<T>(items, totalItems);
    }

    public override void Write(Utf8JsonWriter writer, GridDto<T> value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        // 序列化集合元素到Items字段
        writer.WritePropertyName("Items");
        JsonSerializer.Serialize(writer, value as List<T>, options);
        // 序列化TotalItems字段
        writer.WriteNumber("TotalItems", value.TotalItems);
        writer.WriteEndObject();
    }
}

2. 使用转换器

调用ReadFromJsonAsync时,在序列化选项中添加自定义转换器:

var options = new JsonSerializerOptions();
options.Converters.Add(new GridDtoConverter<YourItemType>());

var gridDto = await JsonSerializer.DeserializeAsync<GridDto<YourItemType>>(jsonStream, options);

或者直接在GridDto<T>类上标记转换器属性:

[JsonConverter(typeof(GridDtoConverter<T>))]
public class GridDto<T> : List<T>
{
    // 原有代码不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:35:03