WebApi - 使用[FromBody]属性和POST方法时,action paramer为null

时间:2016-04-14 11:06:05

标签: c# asp.net-web-api asp.net-mvc-routing owin model-binding

我有这个控制器,我无法弄清楚,为什么name参数为空

public class DeviceController : ApiController
{
    [HttpPost]
    public void Select([FromBody]string name)
    {
        //problem: name is always null
    }
}

这是我的路线映射:

public void Configuration(IAppBuilder appBuilder)
{
    HttpConfiguration config = new HttpConfiguration();
    config.Routes.MapHttpRoute(
        name: "ActionApi",
        routeTemplate: "api/{controller}/{action}"
    );

    appBuilder.UseWebApi(config);
}

这是我的要求:

POST http://localhost:9000/api/device/Select HTTP/1.2
User-Agent: Fiddler
Host: localhost:9000
Content-Length: 16
Content-Type: application/json

{'name':'hello'}

我还尝试将body更改为纯字符串:hello

POST http://localhost:9000/api/device/Select HTTP/1.2
User-Agent: Fiddler
Host: localhost:9000
Content-Length: 5
Content-Type: application/json

hello

请求返回204即可,但参数永远不会映射到发布值。

*我正在使用自托管的owin服务。

1 个答案:

答案 0 :(得分:6)

在第一个示例中,当{'name':'hello'}属性告诉绑定器查找简单类型时,您正在使用复杂对象[FromBody]

在第二个示例中,无法将正文中提供的值解释为简单类型,因为它缺少引号"hello"

使用[FromBody]

要强制Web API从请求正文中读取简单类型,请将[FromBody]属性添加到参数中:

public HttpResponseMessage Post([FromBody] string name) { ... }

在此示例中,Web API将使用媒体类型格式化程序从请求正文中读取name的值。这是一个示例客户端请求。

POST http://localhost:5076/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:5076
Content-Type: application/json
Content-Length: 7

"Alice"

当参数具有[FromBody]时,Web API使用Content-Type标头选择格式化程序。在此示例中,内容类型为“application / json”,请求正文是原始JSON字符串(不是JSON对象)。

最多允许一个参数从邮件正文中读取。所以这不起作用:

// Caution: Will not work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

此规则的原因是请求正文可能存储在只能读取一次的非缓冲流中。

来源:Parameter Binding in ASP.NET Web API