【发布时间】:2015-06-02 17:51:16
【问题描述】:
可以省略写[FromBody]吗?
[HttpPost]
public string SomeMethod([FromBody]SomeModel model)
{
return "OK";
}
我应该应用一些全局属性吗?如何做到这一点?
【问题讨论】:
标签: c# asp.net-core-mvc syntactic-sugar
可以省略写[FromBody]吗?
[HttpPost]
public string SomeMethod([FromBody]SomeModel model)
{
return "OK";
}
我应该应用一些全局属性吗?如何做到这一点?
【问题讨论】:
标签: c# asp.net-core-mvc syntactic-sugar
MVC 5 中的模型绑定属性为动作的每个参数指定一个“BindingSource”,也可以为控制器上的每个属性指定一个“BindingSource”。您可以在BodyModelBinder 中特别看到它为FromBody 属性选择它的代码
首先我要说的是,您应该注意,从 beta6 开始(我认为 beta5 中的某个点),不允许使用 BindingSource.Body 的多个参数/属性,您将不会如果您有多个默认参数,则可以使用您的操作。如果您想注释更多,这实际上可能是可取的;我猜你没有。
可以在DefaultApiDescriptionProvider中看到设置了默认源的地方;不幸的是,此时没有钩子可以绑定,并且方法本身是私有的而不是虚拟的;你需要重新实现整个类。
不过,一旦你拥有它,就可以很容易地在你的 ConfigureServices 中注册它来代替使用它:
services.TryAdd(ServiceDescriptor.Transient<IApiDescriptionProvider, YourApiDescriptionProvider>());
【讨论】:
可能不止一种方法可以实现这一点。这里有一种方法:自定义 ActionValueBinder..
编写一个自定义类以从 DefaultActionValueBinder 扩展。
公共类 FromBodyParameterBindingActionValueBinder : 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 将尝试从请求正文创建模型。您无需明确提供[FromBody] 属性。
话虽如此,您需要了解您所要求的内容的含义..
Web API 有一些关于模型绑定的默认规则。 (可以更改)
另外,web api 只能读取第一个[FromBody] 动作参数.. 后面的参数不能从正文中读取。
我列举上述规则的原因是,当您期望创建某些模型时,您会意识到该行为,但 web api 似乎并未从主体中创建它。
对我来说,明确提供 [FromBody] 更具可读性和可预测性。但如果您完全控制 Http Verbs 方面的 API 并期望所有请求都通过 Body,这是一个完美的选择有效的事情。
【讨论】:
GlobalConfiguration 和 DefaultActionValueBinder 的使用看来,您使用的是 MVC 5,而不是 MVC 6。