C# webapi模型绑定与多态继承

C# webapi模型绑定与多态继承,c#,json,asp.net-web-api,json.net,C#,Json,Asp.net Web Api,Json.net,我问是否有人知道是否有可能将继承自抽象类的具体类传递到Web Api中 例如: public abstract class A { A(); } public class B : A { } [POST("api/Request/{a}")] public class Request(A a) { } 目前,我已经环顾四周,大多数解决方案似乎都说使用TypeNameHandling会起作用 JsonMediaTypeFormatter jsonFormatter

我问是否有人知道是否有可能将继承自抽象类的具体类传递到Web Api中

例如:

public abstract class A
{
    A();
}

public class B : A
{
}

[POST("api/Request/{a}")]
public class Request(A a)
{
}
目前,我已经环顾四周,大多数解决方案似乎都说使用TypeNameHandling会起作用

JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
然而,情况并非如此。此外,我的模型正在从控制台应用程序传递到webapi。我已经读到,我可能能够反序列化json对象,在尝试了几次之后,我决定这是行不通的

我已经考虑过创建一个客户模型绑定器,但是,我不想让我的应用程序变得更加复杂。目前,我从抽象类继承了3个模型,但将来可能会扩展它。正如您可能注意到的,添加自定义模型绑定可能需要多个绑定,除非有一种方法可以使一个绑定对所有类型的抽象类通用

为了在我的控制台应用程序中对此进行扩展,我已经实例化了类b,然后在发布到我的webapi之前将其传递给ObjectContent

item = B();

//serialize and post to web api
MediaTypeFormatter formatter;
JsonMediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
formatter = jsonFormatter;

_content = new ObjectContent<A>(item, formatter);
var response = _client.PostAsync("api/Request", _content).Result;
item=B();
//序列化并发布到web api
MediaTypeFormatter格式化程序;
JsonMediaTypeFormatter jsonFormatter=新的JsonMediaTypeFormatter();
jsonFormatter.SerializerSettings.TypeNameHandling=TypeNameHandling.Auto;
formatter=jsonFormatter;
_内容=新对象内容(项、格式化程序);
var response=_client.PostAsync(“api/Request”,_content).Result;

当调用webapi操作时,对象为空

,这可以通过默认模型绑定实现。检查下面的方法

public abstract class RequestBase
{
    public int ID { get; set; }
}

public class MyRequest : RequestBase
{
    public string Name { get; set; }
}



[RoutePrefix("api/home")]
public class HomeController : ApiController
{
    [HttpPost]
    [Route("GetName")]
    public IHttpActionResult GetName([FromBody]MyRequest _request)
    {
        return Ok("Test");
    }
}

如果一个人真的想实现问题中的问题,有一种定制的方法可以实现

首先,创建一个从
JsonConverter
继承的自定义json转换器,在其中选择一个目标类并反序列化一个实例

然后,在
WebApiConfig.Register
中,将新的转换器添加到
config.Formatters.JsonFormatter.SerializerSettings.Converters
中,并享受这一怪诞的操作

你应该这样做吗?没有

理解如何使用这样的API不会给任何新用户带来任何乐趣,记录这一点并不容易,而且最重要的是,以这种方式实现它没有任何好处。如果输入类型不同,那么它们应该使用具有不同URL的单独API方法。如果只有少数属性不同,则将其设置为可选

为什么这个例子不起作用? 源于Json.NET,Web API对此一无所知,并且类型信息不是Json规范的一部分,因此没有标准方法来解决此特定问题。

请将
[POST(“API/Request/{a}”)]
更改为
[POST(“API/Request”)]

您的参数来自body,而不是route。

您可能可以在这里查看我关于继承和模型绑定的回答:看起来JSON.NET中的以下问题在今年3月得到了解决。或许可以尝试获取最新版本的Json.net,看看您的问题是否仍然存在:我已经对此进行了进一步研究,并回答了我自己的问题。不能通过模型绑定传递抽象类,因为不能实例化抽象类。解决这个问题的唯一方法是使base none抽象,这样模型绑定工作得非常好。根据定义,您的请求参数是DTO。避免对DTO进行继承,因为它几乎没有任何用途,如果必须,可以编写。想想你将要实现什么——你从HTTP请求中得到一个属性包,然后选择一个随机的a实现,只填充要传递给你的方法的基本字段?你没有一个格式良好的对象,它在普通具体的DTO之上也没有任何用途。我猜这不是Ian的意图,他想使用基类(而不是派生类)作为api方法接受的类型。