【问题标题】:Syntactic sugar in Web Api - how to omit [FromBody]Web Api 中的语法糖 - 如何省略 [FromBody]
【发布时间】:2015-06-02 17:51:16
【问题描述】:

可以省略写[FromBody]吗?

[HttpPost]
public string SomeMethod([FromBody]SomeModel model)
{
    return "OK";
}

我应该应用一些全局属性吗?如何做到这一点?

【问题讨论】:

    标签: c# asp.net-core-mvc syntactic-sugar


    【解决方案1】:

    MVC 5 中的模型绑定属性为动作的每个参数指定一个“BindingSource”,也可以为控制器上的每个属性指定一个“BindingSource”。您可以在BodyModelBinder 中特别看到它为FromBody 属性选择它的代码

    首先我要说的是,您应该注意,从 beta6 开始(我认为 beta5 中的某个点),不允许使用 BindingSource.Body 的多个参数/属性,您将不会如果您有多个默认参数,则可以使用您的操作。如果您想注释更多,这实际上可能是可取的;我猜你没有。

    可以在DefaultApiDescriptionProvider中看到设置了默认源的地方;不幸的是,此时没有钩子可以绑定,并且方法本身是私有的而不是虚拟的;你需要重新实现整个类。

    不过,一旦你拥有它,就可以很容易地在你的 ConfigureServices 中注册它来代替使用它:

    services.TryAdd(ServiceDescriptor.Transient<IApiDescriptionProvider, YourApiDescriptionProvider>());
    

    你也可以看到the default being registered in the source

    【讨论】:

    • 问题是关于 web api.. 不是 mvc。
    • WebApi 与 MVC 6 合并 - 它们不再是分开的。
    【解决方案2】:

    可能不止一种方法可以实现这一点。这里有一种方法:自定义 ActionValueBinder..

    1. 编写一个自定义类以从 DefaultActionValueBinder 扩展。

      公共类 FromBodyParameterBindingActionValueBinder : DefaultActionValueBinder

    2. 重写 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 作为默认参数绑定方法。

    1. 一旦我们有了自定义活页夹,就可以全局注册。

      GlobalConfiguration.Services.Replace(typeof(IActionValueBinder), new FromBodyParameterBindingActionValueBinder());

    这样做的是,对于每个 POST/PUT 请求,Web API 将尝试从请求正文创建模型。您无需明确提供[FromBody] 属性。


    话虽如此,您需要了解您所要求的内容的含义..

    Web API 有一些关于模型绑定的默认规则。 (可以更改)

    1. 原始动作参数是第一位的,查看查询字符串
    2. 然后请求正文。
    3. 先是复杂的动作参数,查看请求正文。
    4. 然后查询字符串。

    另外,web api 只能读取第一个[FromBody] 动作参数.. 后面的参数不能从正文中读取。

    我列举上述规则的原因是,当您期望创建某些模型时,您会意识到该行为,但 web api 似乎并未从主体中创建它。

    对我来说,明确提供 [FromBody] 更具可读性和可预测性。但如果您完全控制 Http Verbs 方面的 API 并期望所有请求都通过 Body,这是一个完美的选择有效的事情。

    【讨论】:

    • 从您对 GlobalConfigurationDefaultActionValueBinder 的使用看来,您使用的是 MVC 5,而不是 MVC 6。
    • 有人可以解释对答案的反对意见吗.. 很高兴知道它的原因。
    猜你喜欢
    • 2015-08-07
    • 2015-02-08
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多