web api接口返回實現類集合的姿勢了解

web api接口返回實現類集合的姿勢了解

net web api接口返回基類列表,測試接口只返回了基類的屬性,實現類的屬性怎麼返回呢?

最后更新 2023/3/19 下午8:55
沙漠尽头的狼
预计阅读 3 分钟
分类
ASP.NET Core
标签
.NET C# ASP.NET Core Web API

大家好,我是沙漠盡頭的狼。

一.問題描述

如下圖,定義兩個子類student和employ,都繼承自抽象類personbase:

public abstract class PersonBase
{
    public string Name { get; set; }

    protected PersonBase(string name)
    {
        Name = name;
    }
}

public class Student : PersonBase
{
    public string Number { get; set; }

    public Student(string name, string number) : base(name)
    {
        Number = number;
    }
}

public class Employ : PersonBase
{
    public string CompanyName { get; set; }

    public Employ(string name, string companyName) : base(name)
    {
        CompanyName = companyName;
    }
}

添加web api接口返回基類集合:

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
    [HttpGet(Name = "GetDetails")]
    public IEnumerable<PersonBase> Get()
    {
        return new List<PersonBase>()
        {
            new Student("学生A", "学生号01"),
            new Employ("职员01", "百度")
        };
    }
}

接口返回值:

[
  {
    "name": "学生A"
  },
  {
    "name": "职员01"
  }
]

發現問題了嗎?student類和employ類實例的擴展屬性(student的number屬性,employ的company屬性)都未被序列化展示,那麼怎麼序列化子類的所有屬性呢?

二、實現類的所有屬性序列化

参考微软文档《如何使用System.Text.Json序列化派生类的属性》,有两种实现方式站长觉得比较简单。

2.1、.net 7之前的實現方式

在 .net 7 之前的版本中,system.text.json 不支持多態類型層次結構的序列化。例如,如果接口的返回值類型為接口或抽象類集合,那麼即使運行時類型具有其他屬性,也只會序列化對接口或抽象類定義的屬性。

解决方案:将接口返回值由IEnumerable<PersonBase>改为object,接口实现的List<PersonBase>改为List<object>:

[HttpGet(Name = "GetDetails")]
public object Get()
{
    return new List<object>()
    {
        new Student("学生A", "学生号01"),
        new Employ("职员01", "百度")
    };
}

修改後,接口成功返回詳細json信息:

[
  {
    "number": "学生号01",
    "name": "学生A"
  },
  {
    "companyName": "百度",
    "name": "职员01"
  }
]

原理: 改為object後,默認就是對實現類進行序列化了,改之前system.text.json只認識實現類的爸爸。

2.2、.net 7及以後的實現方式

從 .net 7 開始,system.text.json 支持使用特性標註的多態類型層次結構序列化和反序列化。

我們將接口恢復,在抽象類上添加特性,標明基類序列化時需要映射的子類類型:

[JsonDerivedType(typeof(Student))]
[JsonDerivedType(typeof(Employ))]
public abstract class PersonBase

問題解決,接口返回值同上。

文档关于JsonDerivedTypeAttribute的描述:当放置在类型声明中时,则指示应选择指定的子类型进行多态序列化。 它还公开用于指定类型鉴别器的功能。

三、總結

上面两种方式看.NET版本选择,第二种方式需要您明确知道子类类型,详细使用请看微软文档:如何使用System.Text.Json序列化派生类的属性

如果您有更好的方式歡迎留言探討。

  • 微信技術交流群:添加微信(codewf)備註“入群”
  • qq技術交流群:771992300。

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2022/4/13

asp.net core webapi返回結果統一包裝實踐

關於webapi統一結果返回的時候,讓我也有了更一步的思考,首先是如何能更好的限制返回統一的格式,其次是關於結果的包裝一定是更簡單更強大。在不斷的思考和完善中,終於有了初步的成果,便分享出來,學無止境思考便無止境,希望以此能與君共勉。

继续阅读