我可以传递一个基于接口的对象到MVC 4 WebApi POST
本文关键字:对象 POST WebApi 接口 MVC 于接口 一个 我可以 | 更新日期: 2023-09-27 17:50:20
我想有一个这样的API:
public class RelayController : ApiController
{
// POST api/values
public void Post([FromBody]IDataRelayPackage package)
{
MessageQueue queue = new MessageQueue(".''private$''DataRelay");
queue.Send(package);
queue.Close();
}
}
我得到一个空值的"包",所以我想知道什么可能会出错。我唯一的想法是默认的JSON
序列化器不能处理这个问题,但我不清楚如何修复它。
使用自定义模型绑定器可以很容易地做到这一点。以下是对我有效的方法。(使用Web API 2和JSON。网6)
public class JsonPolyModelBinder : IModelBinder
{
readonly JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var content = actionContext.Request.Content;
string json = content.ReadAsStringAsync().Result;
var obj = JsonConvert.DeserializeObject(json, bindingContext.ModelType, settings);
bindingContext.Model = obj;
return true;
}
}
Web API控制器看起来像这样。(注意:也应该为常规MVC动作工作-我以前也为他们做过这样的事情。)
public class TestController : ApiController
{
// POST api/test
public void Post([ModelBinder(typeof(JsonPolyModelBinder))]ICommand command)
{
...
}
}
我还应该注意,当您序列化JSON时,您应该使用相同的设置序列化它,并将其序列化为一个接口,以使Auto启动并包含类型提示。像这样。
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
string json = JsonConvert.SerializeObject(command, typeof(ICommand), settings);
您正在尝试反序列化到一个接口。除非被告知,否则序列化器将不知道实例化什么类型。
看一下TypeNameHandling选项post一个子类集合
或者看看创建一个自定义的JsonConverter。看看这个问题如何在JSON中实现自定义JsonConverter。. NET反序列化基类对象的列表?
Json。. NET (asp.net默认的Json序列化器)。. NET Web API)可以处理这种情况。您所需要做的就是更改序列化器设置,并将TypeNameHandling设置为All(或Objects)。这将在json中添加一个"$type"-json属性,包含实例的类型名称。另一方面,它会再次尝试反序列化为此类型。
序列化器需要一个它可以构造的类型,一个具有空(默认)构造函数的类型。由于不能构造接口,因此序列化失败,您将得到一个空值。
两个选择:
- 使用POCO (Plain Old Clr Object)和默认构造函数
- 使用IActionValueBinder实现你自己的绑定器