为什么我们必须指定FromBody和FromUri?

Raj*_*esh 140 asp.net-web-api

为什么ASP.NET Web API需要FromBodyFromUri属性?

使用属性和不使用它们之间有什么区别?

dji*_*kay 172

当ASP.NET Web API在控制器上调用方法时,它必须为参数设置值,这个过程称为参数绑定.

默认情况下,Web API使用以下规则绑定参数:

  • 如果参数是"简单"类型,则Web API会尝试从URI获取值.简单类型包括.NET基元类型(int,bool,double等),以及TimeSpan,DateTime,Guid,decimal和string,以及具有可以从字符串转换的类型转换器的任何类型.

  • 对于复杂类型,Web API尝试使用媒体类型格式化程序从邮件正文中读取值.

因此,如果要覆盖上述默认行为并强制Web API从URI中读取复杂类型,请将该[FromUri]属性添加到参数中.要强制Web API从请求正文中读取简单类型,请将该[FromBody]属性添加到参数中.

因此,要回答您的问题,Web API 中的[FromBody][FromUri]属性的需要只是在必要时覆盖如上所述的默认行为.请注意,您可以使用这两个属性的控制器的方法,但仅限于不同的参数,这表现在这里.

还有很多 更多的 信息在网络上,如果你谷歌"的网页API参数绑定".

  • 我想知道是否可以创建一个名为`JustGetIt`的属性,其功能与添加多个属性相同,例如`[FromBody,FromQuery]`等 (4认同)
  • @ user3510527:只要您遵循默认行为,您就不必使用这些属性.如果要更改默认行为,则需要使用它们. (2认同)

Tad*_*dej 82

默认行为是:

  1. 如果该参数是原始类型(int,bool,double,...),网页API试图从获得的价值URI的HTTP请求.

  2. 对于复杂类型(您自己的对象,例如Person:),Web API会尝试从HTTP请求的主体中读取值.

所以,如果你有:

  • URI中的基本类型,
  • 身体中的复杂类型

...那么你不必添加任何属性(既不是[FromBody]也不是[FromUri]).

但是,如果你有一个基本类型体内,那么你必须添加[FromBody]在你的原始类型参数的前面,你的WebAPI控制器的方法.(因为默认情况下,WebAPI正在HTTP请求的URI中查找原始类型.)

或者,如果你有一个复杂的类型在你的URI,那么你就必须添加[FromUri].(因为默认情况下,WebAPI默认在HTTP请求的主体中查找复杂类型.)

原始类型:

public class UsersController : ApiController
{
    // api/users
    public HttpResponseMessage Post([FromBody]int id)
    {

    }
    // api/users/id
    public HttpResponseMessage Post(int id)
    {

    }       
}
Run Code Online (Sandbox Code Playgroud)

复杂类型:

public class UsersController : ApiController
{       
    // api/users
    public HttpResponseMessage Post(User user)
    {

    }

    // api/users/user
    public HttpResponseMessage Post([FromUri]User user)
    {

    }       
}
Run Code Online (Sandbox Code Playgroud)

只要您在HTTP请求中只发送一个参数,这就可以工作.发送多个时,您需要创建一个包含所有参数的自定义模型,如下所示:

public class MyModel
{
    public string MyProperty { get; set; }
    public string MyProperty2 { get; set; }
}

[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
    // model.MyProperty;
    // model.MyProperty2;
}
Run Code Online (Sandbox Code Playgroud)

来自Microsoft的ASP.NET Web API中的参数绑定文档:

当参数具有[FromBody]时,Web API使用Content-Type标头选择格式化程序.在此示例中,内容类型是"application/json",请求正文是原始JSON字符串(不是JSON对象).最多允许一个参数从消息正文中读取.

这应该工作:

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

这不起作用:

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

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

  • “最多允许从邮件正文读取一个参数”是特别有用的信息 (2认同)

小智 11

当参数具有[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)

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

请访问网站了解更多详情:http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api


Utk*_*tel 10

除了以上答案..

[FromUri]也可用于从uri参数绑定复杂类型,而不是从querystring传递参数

对于Ex ..

public class GeoPoint
{
    public double Latitude { get; set; } 
    public double Longitude { get; set; }
}

[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
    [Route("{Latitude}/{Longitude}")]
    public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
Run Code Online (Sandbox Code Playgroud)

可以这样称呼:

http://localhost/api/values/47.678558/-122.130989
Run Code Online (Sandbox Code Playgroud)