ASP.NET Core 3.1中QueryString字符串参数的自定义模型绑定器?

问题描述 投票:2回答:1

我想为某些数据类型实现一些any自定义行为,如 DateTimeint.

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

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

我读过关于创建和实现我自己的自定义模型绑定器的文章,但从外观上看,那些都是针对复杂类型的,所以我有点迷茫,不知道到底如何才能修改一个传入的查询字符串参数,或者如果不可能的话--获得对整个查询字符串的访问权,搜索我想修改的参数,然后修改这些参数。(与 Action 方法,类似于过滤器之类的)。)

谢谢你!我想为一些数据类型实现一些自定义行为,例如DateTime或int。

c# parsing asp.net-core model-view-controller model-binding
1个回答
2
投票

创建并实现我自己的自定义模型绑定器,但从外观上看,这些都是针对复杂类型的,所以我对如何准确地修改一个传入的查询字符串参数有点迷茫。

你可以创建并应用自定义模型绑定器到简单类型的参数,就像下面这样。

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

与Action方法解耦,类似于过滤器什么的。

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

Param2ModelBinder类

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类

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());
});

测试结果

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.