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
相关产品推荐
相关产品推荐

