为什么我们必须指定FromBody和FromUri?
为什么在ASP.NET Web API中需要FromBody和FromUri属性?
使用属性和不使用它们之间有什么区别?
当ASP.NET Web API调用控制器上的方法时,它必须为参数设置值,这个过程称为参数绑定 。
默认情况下,Web API使用以下规则绑定参数:
-
如果参数是“简单”types ,Web API将尝试从URI获取值。 简单的types包括.NET原始types(int,bool,double等等),加上TimeSpan,DateTime,Guid,decimal和string,再加上可以从string转换的types转换器。
-
对于复杂types ,Web API尝试使用媒体格式化程序从消息正文中读取值。
因此,如果您想覆盖上述默认行为并强制Web API从URI读取复杂types,请将[FromUri]属性添加到参数中。 要强制Web API从请求主体读取简单types,请将[FromBody]属性添加到参数中。
因此,为了回答您的问题,Web API中[FromBody]和[FromUri]属性的需要仅仅是在必要时覆盖上述默认行为。 请注意,您可以将这两个属性用于控制器方法,但仅适用于不同的参数,如此处所示。
如果你是谷歌“web api参数绑定”,网上有很多 信息 。
默认行为是:
-
如果参数是
primitive type (int, bool, double, ...),Web API将尝试从HTTP请求的URI获取值。 -
对于
complex types (your own object, for example: Person),Web API会尝试从HTTP请求的body读取值。
如果你在URI有一个primitive type ,或者如果你在body有一个complex type ,那么你不必添加任何属性(不是[FromBody]和[FromUri] )。
但是如果你在本体中有一个primitive type ,那么你必须在你的primitive type参数前面的WebAPI控制器方法中添加[FromBody] (因为默认WebAPI正在HTTP请求的URI中寻找primitive types )或者如果在URI有一个complex type ,那么你必须添加[FromUri] (因为默认情况下WebAPI默认在HTTP请求的body中寻找complex types )。
原始types:
public class UsersController : ApiController { // api/users public HttpResponseMessage Post([FromBody]int id) { } // api/users/id public HttpResponseMessage Post(int id) { } }
复杂types:
public class UsersController : ApiController { // api/users public HttpResponseMessage Post(User user) { } // api/users/user public HttpResponseMessage Post([FromUri]User user) { } }
只要你在HTTP请求中只发送一个参数 ,当你发送多个参数的时候,你就需要创build一个自定义的模型,它的所有参数都是这样的:
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; }
当一个参数有[FromBody]时,Web API使用Content-Type头来select一个格式化程序。 在这个例子中,内容types是“application / json”,请求主体是一个原始的JSONstring(不是JSON对象)。 最多允许一个参数从消息体中读取。
这应该工作:
public HttpResponseMessage Post([FromBody] string name) { ... }这不会工作:
// Caution: Will not work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }这个规则的原因是请求主体可能被存储在只能被读取一次的非缓冲stream中。
来源: https : //docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api#using-frombody
当一个参数有[FromBody]时,Web API使用Content-Type头来select一个格式化程序。 在这个例子中,内容types是“application / json”,请求主体是一个原始的JSONstring(不是JSON对象)。
最多允许一个参数从消息体中读取。 所以这不起作用:
// Caution: Will not work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
这个规则的原因是请求主体可能被存储在只能被读取一次的非缓冲stream中
请通过网站了解更多详情: http : //www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api