使用MVC绑定POST主体中的单个值

时间:2015-01-04 01:19:20

标签: c# asp.net asp.net-mvc http model-binding

我正在ASP.NET MVC中实现一个协议,我需要能够绑定来自这样的请求的数据:

curl -H "Content-Type: application/json" -d 'true' http://example.com/operation/some_id

我尝试在控制器中使用[FromBody]属性,如下所示:

public ActionResult Operation(string id, [FromBody] bool setSomething)

上述代码不起作用,因为它在MVC尝试将setSomething设置为null时抛出异常。如果我将setSomething更改为字符串,则它始终设置为null,因此我无法将其解析为操作中的bool。

我没有把'true'更改为'=true'的奢侈品,正如我在其他地方读到类似问题时所读到的那样。从上面的curl命令生成的POST是一成不变的。我需要的是从POST的主体获取值true(有效的json,即使没有键)并将其分配给setSomething。我还需要以不会阻止我将some_id分配给id的方式执行此操作,因为我已经使用自定义路由。

有谁知道如何在MVC或Web API中实现这一目标?

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

我找到了一个解决方案,但它更像是一种解决方法。

如果POST的正文只是truefalse,但仅此而已,没有键将此值绑定到。因此,除了通过JSON反序列化器运行该值之外,MVC并没有真正做任何其他事情,JSON反序列化器成功而不在动作中设置任何参数。

最后,我必须直接从Request中读取值,如MVC controller : get JSON object from HTTP body?中所述。

我最终使用了类似的代码:

public ActionResult Operation(string id)
{
    var req = Request.InputStream;
    req.Seek(0, SeekOrigin.Begin);
    string rawBody = new StreamReader(req).ReadToEnd();

    bool setSomething = false;

    if(bool.TryParse(rawBody, out setSomething))
    {
        // Do something with 'setSomething'
        return Json(new { id = id, status = setSomething });
    }
    throw new ArgumentException(string.Format("{0} is not a valid boolean value", rawBody));
}

如您所见,我完全从参数列表中删除了setSomething,并依赖于读取请求的原始输入流以获取值。这绝不是优雅的,并没有利用我们从MVC框架中获得的所有好东西,但它确实有效。