首页 > 解决方案 > 确定控制器类中的对象类型

问题描述

我有一个映射到 API 端点的控制器,它接受一个对象列表(比如 Dog),然后我将它反序列化为 IEnumerable。我怎么知道这个对象是 Dog 还是 Cat 或其他类型?我的控制器看起来像这样

string objectType  = "Dog"  //can be anything like Dog,Cat etc

var list = System.Text.Json.JsonSerializer
    .Deserialize<IEnumerable<objectType>>(content.ToString());

var output = services.InsertObject<objectType>(list);

显然我不能写 IEnumerable< objectType > 因为它会抛出错误。由于我也想将此动态对象类型传递给其他层,因此我希望它是通用的。我的方法看起来像这样。 InsertObject<T>(IEnumerable<T>items);

标签: c#genericsreflectionasp.net-core-webapijson-deserialization

解决方案


默认情况下,您不能拥有一个接受不同对象类型的 API 端点,因为序列化程序无法猜测要反序列化为哪种对象类型。

您需要一些鉴别器来告诉序列化程序要从主体反序列化哪种对象。

鉴于这个机构:

{
    "name": "Foo",
    "size": "Large"
}

这些类中的哪一个匹配?

public class TShirt
{
    public string Name { get; set; }
    public string Size { get; set; }
}

public class Dog
{
    public string Name { get; set; }
    public string Size { get; set; }
}

关键是:两者都匹配。因此,如果这是一个 API,您可以通过路由 ( /api/tshirts, /api/dogs) 来识别,并且在您的代码或配置中的某处将路由映射到一个类。

你可以在你的身体中包含这个鉴别器:

{
    "$type": "Dog",
    "name": "Woof",
    "size": "smol"
}

然后你会在某处使用钩子来读取$type字段并返回适当的类以反序列化。

如何做到这一点完全是另一个问题,并且取决于您在服务的哪一侧(您是在为现有 API 编写 API 控制器还是客户端?)以及您正在使用什么框架等等。


至于您的实际问题,您可以执行以下操作:

public void Insert<T>(string json)
{
    var list = System.Text.Json.JsonSerializer
    .Deserialize<IEnumerable<T>>(json);

    var output = services.InsertObject<T>(list);
}

然后通过反射调用该方法使用从其名称中获得的 Type

工作所需的可怕代码量应该会阻止您这样做。如果没有,请参阅这两个问题来编写它。


推荐阅读