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

ASP.NET Core中如何将JSON多字段反序列化为IEnumerable<Book>

解决JSON多字段转IEnumerable集合的反序列化问题

我明白你遇到的问题了:一开始自定义的BooksJsonConverter没被触发,加了[JsonProperty("FirstBook")]虽然能调用转换器,但又不知道怎么处理多个字段转集合。让我一步步帮你解决这个问题:

核心问题分析

你最初的转换器没被调用,原因很简单:Json.NET只会在JSON中存在对应属性键的时候,才会触发该属性的转换器。你的Result类里的Books属性在JSON里没有对应的"Books"字段,所以转换器根本不会被执行。而添加[JsonProperty("FirstBook")]后,Json.NET会把"FirstBook"的值传给转换器,但这只是单个字段,不是我们需要的多字段集合。

正确解决方案:给Result类使用自定义转换器

更合适的做法是给整个Result类添加自定义转换器,这样我们可以在序列化/反序列化时手动处理所有相关字段,把FirstBook、SecondBook、ThirdBook收集成IEnumerable<Book>集合。

步骤1:编写Result类的自定义转换器

public class ResultJsonConverter : JsonConverter<Result>
{
    // 反序列化逻辑:把JSON中的多Book字段转成集合
    public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 加载整个Result对应的JSON对象
        var jObject = JObject.Load(reader);
        
        var result = new Result
        {
            // 读取Id字段
            Id = jObject.GetValue("Id").ToObject<int>(serializer),
            Books = new List<Book>()
        };

        // 定义需要收集的Book字段列表
        var bookFieldNames = new[] { "FirstBook", "SecondBook", "ThirdBook" };
        
        foreach (var fieldName in bookFieldNames)
        {
            // 读取字段值,跳过空值
            var bookName = jObject[fieldName]?.ToString();
            if (!string.IsNullOrWhiteSpace(bookName))
            {
                result.Books.Add(new Book { Name = bookName });
            }
        }

        return result;
    }

    // 可选:如果需要把Result序列化为原始JSON格式,实现WriteJson方法
    public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
    {
        var jObject = new JObject();
        jObject.Add("Id", value.Id);
        
        var booksList = value.Books?.ToList();
        if (booksList != null)
        {
            if (booksList.Count > 0) jObject.Add("FirstBook", booksList[0].Name);
            if (booksList.Count > 1) jObject.Add("SecondBook", booksList[1].Name);
            if (booksList.Count > 2) jObject.Add("ThirdBook", booksList[2].Name);
        }
        
        jObject.WriteTo(writer);
    }
}

步骤2:给Result类添加转换器属性

修改你的Result类,加上[JsonConverter]属性:

[JsonConverter(typeof(ResultJsonConverter))]
public class Result 
{ 
    public int Id { get; set;} 
    public IEnumerable<Book> Books { get; set; } 
}

步骤3:正常执行反序列化

现在你可以直接调用原来的反序列化代码,转换器会自动触发:

var results = JsonConvert.DeserializeObject<IEnumerable<Result>>(json);

额外说明

如果你不想给整个类加转换器,也可以通过自定义ContractResolver来实现字段映射,但类级别的转换器逻辑更直观,容易维护。另外,上面的代码还包含了序列化的逻辑,如果你的场景不需要序列化,可以去掉WriteJson方法,同时重写CanWrite属性返回false。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:47:44