【问题标题】:Sending a JSON object to a C# WebAPI POST method which takes in a generic abstract class as a parameter将 JSON 对象发送到 C# WebAPI POST 方法,该方法将通用抽象类作为参数
【发布时间】:2021-08-11 17:58:32
【问题描述】:

我有一个通用抽象类,它描述了某人将发布到此端点的对象类型,该类如下所示,以及该类可能是的类型示例:

public abstract class Animal<T>
    {
        public string Name { get; set; }

        public virtual T Properties{ get; set; }
    }
public class Pig : Animal<List<int>>
    {
        public Pig()
        {
            Name = "pigEntity";
            Properties = new List<int>();
        }
    }

下面是我的控制器方法调用 API 端点的样子:

[HttpPost]
[Route("...")]
public async Task<bool> SaveAnimalSetting([FromBody] Animal<JObject> animalType)
{}

当尝试通过 Postman 调用此端点时,我返回输入无效,下面是我尝试向其发布的 JSON 对象,它应该与上面的 Pig 对象等效:

{
   "key":"pigEntity",
   "value":[
      1,
      2,
      3,
      4,
      5,
      6
   ]
}

有谁知道我哪里出错了,或者当使用通用抽象类作为参数调用端点时,JSON 对象的示例会是什么样子,或者是否有其他方法可以做到这一点?我在这里找到了一个线程,其中有人也有一个泛型类,这是他们被推荐的方法,因此尝试做同样的事情。

【问题讨论】:

  • 您基本上是在要求反序列化器创建抽象类的实例,这是不可能的。除非您有某处代码告诉框架如何将输入反序列化为正确的派生类,否则这根本行不通。具体来说,如果您想采用这种方法,则必须使用反序列化框架。
  • 你不能轻易做到这一点。您将需要指定端点中预期的实际类型。像 [FromBody Animal anymalType].... 此外,您不应该使用抽象类或接口。
  • 您可能会使用自定义转换器并使用包装器和显式类型并从属性返回对象。
  • @JonathanAlfaro 是的,他需要为(我假设)System.Json JSON 序列化程序编写自定义转换器
  • 有没有办法让它与端点中的基类(在这种情况下为动物)一起工作?因为那是我之后的主要事情。之后我的计划是根据 JSON 中的“关键”属性,直接使用 switch case 将该对象转换为其正确的派生类。目前没有实现这个,因为不能让它首先工作,所以暂时使用常规的 JObject 参数

标签: c# json .net asp.net-core asp.net-web-api


【解决方案1】:

如果您尝试用作输入参数

{
   "key":"pigEntity",
   "value":[
      1,
      2,
      3,
      4,
      5,
      6
   ]
}

你可以使用 JObject,但只能这样

public bool SaveAnimalSetting([FromBody] JObject animalType)
{
    var key = animalType["key"].ToString();

    switch (key)
    {
    case "pigEntity":

     var properties = JsonConvert.DeserializeObject<List<int>> (animalType["value"].ToString());
     var pig = new Pig { Properties = properties };
                    break;
        
                default:
                    break;
            }
}

我很抱歉,但这对我来说没有任何意义。由于每个类都应该有特殊的属性,在任何情况下你都应该知道在发送带有输入参数的 json 之前需要创建什么类型。只有当您想在一个请求中创建多个不同的类时,它才会有用。

问题在于,由于您需要反序列化数据,因此您需要知道用于反序列化的类型。也许您可以使用反射来创建类型,但与使用新的相比,它需要更多的时间和资源。我建议仅在没有反射就无法完成任务的情况下使用反射。

【讨论】:

  • 是的,这是有道理的。我的问题是可能有不同类型的动物,例如Dog 或 Tiger 类,但我设计它的方式是它们每个都有 2 个字段,字符串名称和属性,名称将始终是字符串,但属性可以是任何数据类型,这就是我选择的原因为它使用泛型
  • 我很抱歉,但这对我来说没有任何意义。如果你必须为每个类发送一个特殊的属性,你应该在发送输入参数之前知道是什么类型。
  • 对您的 JObject 示例有意义。这就是我目前正在使用的它及其工作,但只是想知道是否有任何方法可以做到这一点而不是使用 JObject
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 2015-10-19
  • 2014-08-04
相关资源
最近更新 更多