gpt4 book ai didi

c# - 如何让 ASP.NET Core 2.0 MVC Model Binder 绑定(bind)没有 FromBody 属性的复杂类型

转载 作者:太空狗 更新时间:2023-10-30 01:13:36 27 4
gpt4 key购买 nike

因此,在 ASP.NET Core MVC 中,他们决定我需要在所有复杂类型的操作参数前键入 [FromBody],因为一些似乎没人谈论的传奇 CSRF 问题。我觉得这很荒谬,那么有没有办法让 ASP.NET Core MVC 表现得像旧的 WebAPI,而不需要到处都是 [FromBody],只需将 JSON 的所有内容绑定(bind)到复杂类型参数?如果我能以某种方式选择它适用的 Controller 集,例如以/api 开头的 Controller 或用特定属性装饰的 Controller ,那就太好了。

最佳答案

通过实现自定义模型绑定(bind)约定,您可以避免为每个复杂的 Action 参数使用 FromBody 属性。步骤如下:

  1. 定义将在 Controller 级别指示所有操作应使用来自请求正文的默认绑定(bind)的属性:

    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class DefaultFromBodyAttribute : Attribute
    {
    }
  2. 添加自定义模型绑定(bind)约定的实现:

    public class DefaultFromBodyBindingConvention : IActionModelConvention
    {
    public void Apply(ActionModel action)
    {
    if (action == null)
    {
    throw new ArgumentNullException(nameof(action));
    }

    if (action.Controller.Attributes.Any(a => a is DefaultFromBodyAttribute))
    {
    foreach (var parameter in action.Parameters)
    {
    var paramType = parameter.ParameterInfo.ParameterType;
    var isSimpleType = paramType.IsPrimitive
    || paramType.IsEnum
    || paramType == typeof(string)
    || paramType == typeof(decimal);

    if (!isSimpleType)
    {
    parameter.BindingInfo = parameter.BindingInfo ?? new BindingInfo();
    parameter.BindingInfo.BindingSource = BindingSource.Body;
    }
    }
    }
    }
    }

    实现非常简单。我们检查 Controller 是否标记有必需的属性,检查操作参数是否复杂,如果两个条件都满足 - 我们将绑定(bind)源设置为 BindingSource.Body。我们应该检查底层操作参数类型是否复杂,因为我们不希望从请求正文中绑定(bind) intstring 类型。我从 this answer 借用了复杂类型识别的条件.

    您可以根据需要调整此约定的逻辑,例如如果您想检查 Controller 路由而不是属性,或者要为特定类型设置特殊条件。

  3. Startup.ConfigureServices 方法中注册约定:

    services.AddMvc(options =>
    {
    options.Conventions.Add(new DefaultFromBodyBindingConvention());
    });
  4. 使用 DefaultFromBody 属性标记所需的 Controller :

    [Route("api/[controller]")]
    [DefaultFromBody]
    public class SomeController : Controller

现在,即使您不指定 FromBody 属性,复杂的 Action 参数也会默认从 body 绑定(bind):

[HttpPost]
public void Post(SomeData value)
{
// ...
}

模型约定在应用程序启动期间(针对每个操作)调用一次,因此您不必担心请求执行期间的任何性能损失。

关于c# - 如何让 ASP.NET Core 2.0 MVC Model Binder 绑定(bind)没有 FromBody 属性的复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49396816/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com