我们正处于一个信息大暴发的时代,每天都能产生数以百万计的新闻资讯!
虽然有大数据推荐,但面对海量数据,通过我们的调研发现,在一个小时的时间里,您通常无法真正有效地获取您感兴趣的资讯!
头条新闻资讯订阅,旨在帮助您收集感兴趣的资讯内容,并且在第一时间通知到您。可以有效节约您获取资讯的时间,避免错过一些关键信息。
假设有一个 Person 抽象基类,其中包含 Student 和 Teacher 派生类:
public class Person
{
public string Name { get; set; }
}
public class Student : Person
{
public int Score { get; set; }
}
public class Teacher : Person
{
public string Title { get; set; }
}
如果 API 输入类型是单个 Person 抽象基类,即使我们传入正确格式的派生类 JSON 字符串,System.Text.Json也只会使用基类进行反序列化:
[HttpPost]
[Route("get")]
public string Get(Person person)
{
return person.GetType().ToString();
}
我们必须主动告诉System.Text.Json如何处理反序列化派生类,因此需要自定义转换器。
思路
与序列化相反,我们需要实现自定义转换器的Read方法:
public class PersonConverter : JsonConverter
{
public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
}
}
现在的关键是,如何判断到底要反序列化成哪个派生类型。
我们可以使用Read方法遍历 JSON 的所有 Property, 找到对应派生类型独有的属性,即可知道当前需要反序列化成哪个派生类型。
实现
为基类创建自定义转换器,实现Read方法:
public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
Utf8JsonReader readerClone = reader;
while (readerClone.Read())
{
JsonTokenType tokenType = readerClone.TokenType;
switch (tokenType)
{
case JsonTokenType.PropertyName:
if (readerClone.ValueTextEquals("score"))
{
return (Person)JsonSerializer.Deserialize(ref reader,typeof(Student), options);
}
else if (readerClone.ValueTextEquals("title"))
{
return (Person)JsonSerializer.Deserialize(ref reader, typeof(Teacher), options);
}
break;
}
}
throw new NotImplementedException();
}
因为 Utf8JsonReader 是只进读取器,因此这里需要创建 Utf8JsonReader 实例的克隆readerClone去遍历 JSON,而原始 reader 用于反序列化派生类。
然后修改 Startup.cs 文件,注册自定义转换器:
services.AddControllers()
.AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new PersonConverter()));
运行,反序列化成功:
结论
通过自定义转换器,我们实现了使用System.Text.Json反序列化派生类。返回搜狐,查看更多
责任编辑:
以上内容为资讯信息快照,由td.fyun.cc爬虫进行采集并收录,本站未对信息做任何修改,信息内容不代表本站立场。
快照生成时间:2022-12-19 05:39:43
本站信息快照查询为非营利公共服务,如有侵权请联系我们进行删除。
信息原文地址: