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

System.Text.Json:如何像序列化普通类一样序列化IEnumerable对象?

.NET 7 解决实现IEnumerable接口的类序列化时忽略自身字段的问题

当类实现IEnumerable<T>接口时,System.Text.Json默认会将其视为集合类型,仅序列化枚举返回的内容,忽略类自身的字段或属性。比如你提供的Book类中,Title字段就不会被序列化。在Newtonsoft.Json中可以通过添加[JsonObject]特性解决这个问题,而在.NET 7使用JsonResult时,可通过以下两种等效方案处理:

方法一:自定义JsonConverter

创建针对Book类的转换器,手动控制序列化逻辑,确保所有字段都被序列化:

public class BookConverter : JsonConverter<Book>
{
    public override Book Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var book = new Book();
        using (var doc = JsonDocument.ParseValue(ref reader))
        {
            var root = doc.RootElement;
            if (root.TryGetProperty("Title", out var titleElem))
                book.Title = titleElem.GetString();
            if (root.TryGetProperty("Pages", out var pagesElem))
                book.Pages = JsonSerializer.Deserialize<IList<string>>(pagesElem.GetRawText(), options);
        }
        return book;
    }

    public override void Write(Utf8JsonWriter writer, Book value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        writer.WriteString("Title", value.Title);
        writer.WritePropertyName("Pages");
        JsonSerializer.Serialize(writer, value.Pages, options);
        writer.WriteEndObject();
    }
}

使用方式

  • 直接在Book类上添加特性:
[JsonConverter(typeof(BookConverter))]
public class Book:IEnumerable<string>
{
    // 类原有内容不变
}
  • 或者在JsonSerializerOptions中注册转换器:
var options = new JsonSerializerOptions 
{ 
    IncludeFields = true,
    Converters = { new BookConverter() }
};
return new JsonResult(myBook, options);

方法二:配置类型元数据

通过DefaultJsonTypeInfoResolver修改类型序列化元数据,让System.Text.Json将Book视为普通对象而非集合:

var resolver = new DefaultJsonTypeInfoResolver();
resolver.Modifiers.Add(typeInfo =>
{
    if (typeInfo.Type == typeof(Book))
    {
        // 将类型标记为对象类型,而非集合
        typeInfo.Kind = JsonTypeInfoKind.Object;
        // 添加需要序列化的字段
        typeInfo.Properties.Add(new JsonPropertyInfo
        {
            Name = "Title",
            PropertyType = typeof(string),
            Getter = obj => ((Book)obj).Title,
            Setter = (obj, value) => ((Book)obj).Title = (string)value,
            DeclaringType = typeof(Book)
        });
        typeInfo.Properties.Add(new JsonPropertyInfo
        {
            Name = "Pages",
            PropertyType = typeof(IList<string>),
            Getter = obj => ((Book)obj).Pages,
            Setter = (obj, value) => ((Book)obj).Pages = (IList<string>)value,
            DeclaringType = typeof(Book)
        });
    }
});

var options = new JsonSerializerOptions 
{ 
    IncludeFields = true,
    TypeInfoResolver = resolver
};
return new JsonResult(myBook, options);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:55:31