Web Api 中的语法糖 - 如何省略 [FromBody]
Syntactic sugar in Web Api - how to omit [FromBody]
是否可以省略写[FromBody]
?
[HttpPost]
public string SomeMethod([FromBody]SomeModel model)
{
return "OK";
}
我应该应用一些全局属性吗?如何实现?
实现此目的的方法可能不止一种..这是一种方法:自定义 ActionValueBinder..
编写自定义 class 以扩展 DefaultActionValueBinder
。
public class 来自BodyParameterBindingActionValueBinder : DefaultActionValueBinder
重写 GetParameterBinding 方法。
protected override HttpParameterBinding
GetParameterBinding(HttpParameterDescriptor parameter)
{
return parameter.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Post)
|| parameter.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Put) ?
parameter.BindWithAttribute(new FromBodyAttribute()) :
base.GetParameterBinding(parameter);
}
基本上我们要说的是,如果 Web API 系统收到 POST 或 PUT 调用,请将 FromBody 作为默认参数绑定方法。
一旦我们有了自定义活页夹,就在全球注册它。
GlobalConfiguration.Services.Replace(typeof(IActionValueBinder), new FromBodyParameterBindingActionValueBinder());
这样做的目的是,对于每个 POST/PUT 请求,Web API 将尝试根据请求 Body 创建模型。您不需要显式提供 [FromBody]
属性。
话虽如此,您需要了解您所请求内容的含义..
Web API 有一些关于模型绑定的默认规则。 (可以更改)
- 首先是原始操作参数,查看查询字符串
- 然后请求 body.
- 首先是复杂的操作参数,查看请求 body。
- 然后查询字符串。
此外,web api 只能读取第一个 [FromBody]
操作参数。无法从 body.
读取后续参数
我列举上述规则的原因是,当您希望创建某些模型时,您会意识到这种行为,但网络 api 似乎并没有从 body.
对我来说,明确提供 [FromBody]
更具可读性和可预测性..但是如果你在 Http 动词方面完全控制你的 APIs 并期望所有请求通过 Body,这是一件非常有效的事情。
MVC 5 中的模型绑定属性为操作上的每个参数指定一个“BindingSource
”,也可以为控制器上的每个 属性 指定。您可以具体查看 BodyModelBinder
中的 FromBody
属性的代码
首先让我说,你应该注意从 beta6 开始(我认为 beta5 中的某些点),不允许 parameters/properties 和 BindingSource.Body
,如果您将多个参数保留为默认值,您将无法使用您的操作。如果您想注释更多,这实际上可能是可取的;我猜你不会。
您可以在DefaultApiDescriptionProvider
中看到设置了默认来源;不幸的是,此时没有钩子可以绑定,方法本身是私有的而不是虚拟的;你需要重新实现整个 class.
不过,一旦你拥有它,就可以很容易地在你的 ConfigureServices
中注册它来代替使用它:
services.TryAdd(ServiceDescriptor.Transient<IApiDescriptionProvider, YourApiDescriptionProvider>());
是否可以省略写[FromBody]
?
[HttpPost]
public string SomeMethod([FromBody]SomeModel model)
{
return "OK";
}
我应该应用一些全局属性吗?如何实现?
实现此目的的方法可能不止一种..这是一种方法:自定义 ActionValueBinder..
编写自定义 class 以扩展
DefaultActionValueBinder
。public class 来自BodyParameterBindingActionValueBinder : DefaultActionValueBinder
重写 GetParameterBinding 方法。
protected override HttpParameterBinding GetParameterBinding(HttpParameterDescriptor parameter) { return parameter.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Post) || parameter.ActionDescriptor.SupportedHttpMethods.Contains(HttpMethod.Put) ? parameter.BindWithAttribute(new FromBodyAttribute()) : base.GetParameterBinding(parameter); }
基本上我们要说的是,如果 Web API 系统收到 POST 或 PUT 调用,请将 FromBody 作为默认参数绑定方法。
一旦我们有了自定义活页夹,就在全球注册它。
GlobalConfiguration.Services.Replace(typeof(IActionValueBinder), new FromBodyParameterBindingActionValueBinder());
这样做的目的是,对于每个 POST/PUT 请求,Web API 将尝试根据请求 Body 创建模型。您不需要显式提供 [FromBody]
属性。
话虽如此,您需要了解您所请求内容的含义..
Web API 有一些关于模型绑定的默认规则。 (可以更改)
- 首先是原始操作参数,查看查询字符串
- 然后请求 body.
- 首先是复杂的操作参数,查看请求 body。
- 然后查询字符串。
此外,web api 只能读取第一个 [FromBody]
操作参数。无法从 body.
我列举上述规则的原因是,当您希望创建某些模型时,您会意识到这种行为,但网络 api 似乎并没有从 body.
对我来说,明确提供 [FromBody]
更具可读性和可预测性..但是如果你在 Http 动词方面完全控制你的 APIs 并期望所有请求通过 Body,这是一件非常有效的事情。
MVC 5 中的模型绑定属性为操作上的每个参数指定一个“BindingSource
”,也可以为控制器上的每个 属性 指定。您可以具体查看 BodyModelBinder
FromBody
属性的代码
首先让我说,你应该注意从 beta6 开始(我认为 beta5 中的某些点),不允许 parameters/properties 和 BindingSource.Body
,如果您将多个参数保留为默认值,您将无法使用您的操作。如果您想注释更多,这实际上可能是可取的;我猜你不会。
您可以在DefaultApiDescriptionProvider
中看到设置了默认来源;不幸的是,此时没有钩子可以绑定,方法本身是私有的而不是虚拟的;你需要重新实现整个 class.
不过,一旦你拥有它,就可以很容易地在你的 ConfigureServices
中注册它来代替使用它:
services.TryAdd(ServiceDescriptor.Transient<IApiDescriptionProvider, YourApiDescriptionProvider>());