Dam*_*les 5 .net system.text.json
似乎如果一个对象是 an IEnumerable,Json 会忽略它的字段并序列化可枚举。例如,对于如下所示的类,Title未序列化。我发现了几乎相同的问题,答案是添加[JsonObject]到类中,但它是关于使用 Newtonsoft.Json 的,我正在通过 .NET 7.0 的 Json 使用JsonResult。.NET Json 有等效的东西吗?
var myBook = new Book()
{
Title = "Jane Eyre",
Pages = new List<string>() { "page1", "page2", "page3" }
};
var options = new JsonSerializerOptions { IncludeFields = true };
return new JsonResult(myBook, options);
}
public class Book:IEnumerable<string>
{
public string Title;
public IList<string> Pages;
public IEnumerator<string> GetEnumerator()
{
return Pages.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Pages.GetEnumerator() as IEnumerator;
}
}
Run Code Online (Sandbox Code Playgroud)
实际上不是,但已要求这样做:
为序列化程序提供选项,将 IEnumerables 视为具有成员的对象#1808
System.Text.Json有转换器JsonObjectConverter有可以完成这项工作的
在未来的 .NET 版本中,将公开内部转换器:
开发人员应该有权访问 System.Text.Json 的默认内部转换器#63791
之后,您将可以:
[JsonConverter(typeof(JsonObjectConverter))]
public class Book:IEnumerable<string>
{...}
Run Code Online (Sandbox Code Playgroud)
目前,解决方法是为每种IEnumerable类型编写一个转换器,例如:
public class BookConverter : Json.Serialization.JsonConverter<Book>
{
public override Book? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
var obj = new Book();
do
{
reader.Read();
if (reader.TokenType == JsonTokenType.PropertyName)
{
string propName = reader.GetString();
reader.Read();
switch(propName)
{
case "Title":
obj.Title = reader.GetString();
break;
case "Pages":
obj.Pages = JsonSerializer.Deserialize<IList<string>>(ref reader, options);
break;
default:
throw new JsonException();
}
}
else if (reader.TokenType == JsonTokenType.EndObject)
{
break;
}
} while (true);
return obj;
}
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();
}
}
Run Code Online (Sandbox Code Playgroud)