【问题标题】:MediaFormatter or ModelBinder for web api PUT methodWeb api PUT 方法的 MediaFormatter 或 ModelBinder
【发布时间】:2015-05-03 06:50:35
【问题描述】:

我在 web api 中有一个 PUT 方法,它接受 JSON 数据和路由数据,如下所示。

[Route("api/v1/Orders/{orderId}/active")]
    public HttpResponseMessage Put(Guid? orderId,List<ActiveRequest> activeRequests)
    {


    }
public class ActiveRequest
{
    public int Id { get; set; }
    public bool IsActive { get; set; } 
}

现在可以将方法签名简化为:

[Route("api/v1/Orders/{orderId}/active")]
    public HttpResponseMessage Put(ActiveRequestModel model)
    {


    }
public class ActiveRequestModel
{
    public Guid OrderId { get; set; }
    public List<ActiveRequest> ActiveRequests {get; set;} 
}

我尝试通过实现 System.Web.Http.ModelBinding.IModelBinder 接口来编写自定义 ModelBinder,但找不到读取请求对象内部的 JSON 数据的方法。 我怀疑有没有一种方法可以将我的模型与来自三个不同地方的数据绑定,即来自 路由数据、json 和表单

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-web-api asp.net-web-api2 model-binding


    【解决方案1】:

    你不能像描述的那样简化参数。

    与 MVC 模型绑定不同,由于 Web API 格式化程序的工作方式,在 Web API 中,您只能有一个从有效负载反序列化的参数,以及来自路由参数或 url 查询字符串的一些简单类型参数。原因是来自负载的参数的创建是在负载的单遍反序列化中完成的。

    因此,对于您的示例,您需要原始版本中的两个参数,即:

    public HttpResponseMessage Put(Guid? orderId, List<ActiveRequest> activeRequests)
    

    如果你想使用ActiveRequestModel,你需要包含一个结构完全相同的payload,所以你应该在payload中包含orderId,因为它不会从url中恢复(即使名称匹配)。

    请阅读这篇解释参数绑定如何在 Web API 中工作的文章:

    如果你仔细阅读它,你会发现你可以创建和注册你自己的模型绑定器,让它像 MVC 控制器一样工作,但我认为这不值得付出努力(所以我只将它包含在这个最后一段),这不是标准的工作方式。

    【讨论】:

    • 感谢@JotaBe,但我的 OrderId 不会成为 JSON 有效负载的一部分。它将来自路线。就像我的 url 会有那个数据 exp:localhost:12345/api/v1/Orders/…
    • @thinkmmk 很抱歉我没听懂你的问题。我现在已经完全编辑了我的答案。你不能做你想做的事,除非你在有效载荷中包含订单 ID,或者定义一个使用你自己的模型绑定器
    • 再次感谢您的澄清,因此自定义模型绑定器可以满足我的要求,还是我必须在 json 中包含 orderid?
    • 这取决于你:如果你认为你可以很容易地实现一个模型绑定器来解决你的大部分绑定,那就去做吧。如果您认为必须创建许多不同的模型绑定器,或者实现起来很困难,请采取简单的方法,并将其包含在 JSON 中,这很容易。我不是不鼓励这样做,而是警告你,如果它变得太复杂,最好按照“通常的方式”来做。
    • 有几个属性可以从请求中获取原始 JSON 数据,例如 Request.Content.ReadAsStringAsync()。然后您可以使用 JSON.NET 对其进行反序列化。实现模型绑定器很复杂,因为您只能访问原始数据和标题以确定要发布的数据类型。您的模型绑定器必须确定它是反序列化为 JSON 的 JSON,还是表单数据,将其作为表单数据读取,或者是任何其他格式来读取它。相当复杂。这就是为什么我评论说这可能不值得付出努力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多