ASP.NET Core 3.1 中 QueryString 字符串参数的自定义模型联编程序?

Custom model binder for QueryString string parameters in ASP.NET Core 3.1?

我想为某些数据类型实现 some/any 自定义行为,例如 DateTimeint

我创建了一个自定义 JsonConverter,其中包含从请求正文接收的数据(除非它被指定为非 json),这让我可以做到这一点。

但是如果数据是在请求的查询字符串中传递的,例如?param1=helloWorld&param2=123",它们的处理方式不同,不在我的自定义范围内JsonConverter

我读过 creating/implementing 我自己的 Custom Model Binder,但是从它的外观来看,这些都是针对复杂类型的,所以我对如何修改传入的查询字符串有点迷茫参数,或者如果那不可能 - 获得对整个查询字符串的访问权限,搜索我想要修改的参数,然后修改它们。 (与 Action 方法分离,类似于过滤器等。)

谢谢!

creating/implementing my own Custom Model Binder, but those from the looks of it are for complex types, so I'm a bit lost on how exactly I can modify an incoming query string parameter

您可以创建自定义模型绑定器并将其应用于简单类型参数,如下所示。

public IActionResult Test(string param1, [ModelBinder(BinderType = typeof(Param2ModelBinder))]int param2)
{

decoupled from Action methods, similar to filters and whatnot.

如果您不想直接将自定义模型绑定器应用于操作参数,您可以实现一个自定义模型绑定器提供程序并指定您的绑定器操作的参数,然后将其添加到 MVC 的提供程序集合中。

Param2ModelBinder class

public class Param2ModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
        {
            throw new ArgumentNullException(nameof(bindingContext));
        }

        // ...
        // implement it based on your actual requirement
        // code logic here
        // ...

        var model = 0;

        if (bindingContext.ValueProvider.GetValue("param2").FirstOrDefault() != null)
        {
            model = JsonSerializer.Deserialize<int>(bindingContext.ValueProvider.GetValue("param2").FirstOrDefault());

            // just for testing purpose
            // if received data > 100
            // set it to 100

            if ((int)model > 100)
            {
                model = 100;
            }
        }


        bindingContext.Result = ModelBindingResult.Success(model);
        return Task.CompletedTask;
    }
}

MyCustomBinderProvider class

public class MyCustomBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder(ModelBinderProviderContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // specify the parameter your binder operates on
        if (context.Metadata.ParameterName == "param2")
        {
            return new BinderTypeModelBinder(typeof(Param2ModelBinder));
        }

        return null;
    }
}

添加自定义模型活页夹提供程序

services.AddControllersWithViews(opt=> {
    opt.ModelBinderProviders.Insert(0, new MyCustomBinderProvider());
});

测试结果