WebApi-使用[FromBody]属性和POST方法时,动作参数为null

Lie*_*ero 2 c# model-binding asp.net-mvc-routing asp.net-web-api owin

我有这个控制器,我不知道为什么name参数为null

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

这是我的路线图:

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

    appBuilder.UseWebApi(config);
}
Run Code Online (Sandbox Code Playgroud)

这是我的要求:

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'}
Run Code Online (Sandbox Code Playgroud)

我还尝试将正文更改为纯字符串: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
Run Code Online (Sandbox Code Playgroud)

该请求返回204,这没问题,但是该参数从不映射到发布值。

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

Nko*_*osi 6

在第一个示例中,{'name':'hello'}[FromBody]属性告诉活页夹寻找简单类型时,您正在使用复杂的对象。

在第二个示例中,您在主体中提供的值不能解释为简单类型,因为它缺少引号 "hello"

使用[FromBody]

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

public HttpResponseMessage Post([FromBody] string name) { ... }
Run Code Online (Sandbox Code Playgroud)

在此示例中,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"
Run Code Online (Sandbox Code Playgroud)

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

最多允许一个参数从消息正文中读取。因此,这将不起作用:

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

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

来源:ASP.NET Web API中的参数绑定