如何让 ASP.NET Core 支持绑定查询字符串中的数组

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何让 ASP.NET Core 支持绑定查询字符串中的数组相关的知识,希望对你有一定的参考价值。

前言

上回说到,我们实现了IntArrayModelBinder,可以让 ASP.NET Core 绑定查询字符串中的数组。但是必须显示指定ModelBinder

public string Get([FromQuery][ModelBinder(BinderType = typeof(IntArrayModelBinder))] int[] values)

而官方提供的ByteArrayModelBinder不需要指定ModelBinder即可生效:

public string Get([FromQuery]byte[] values)

那么,它是如何做到的呢?

ByteArrayModelBinderProvider

在源码中查找ByteArrayModelBinder的所有引用。发现只有一处使用:

public class ByteArrayModelBinderProvider : IModelBinderProvider

    /// <inheritdoc />
    public IModelBinder? GetBinder(ModelBinderProviderContext context)
    
        if (context == null)
        
            throw new ArgumentNullException(nameof(context));
        
 
        if (context.Metadata.ModelType == typeof(byte[]))
        
            var loggerFactory = context.Services.GetRequiredService<ILoggerFactory>();
            return new ByteArrayModelBinder(loggerFactory);
        
 
        return null;
    

MvcCoreMvcOptionsSetup

继续查找ByteArrayModelBinderProvider的所有引用。发现也只有一处使用:

internal class MvcCoreMvcOptionsSetup : IConfigureOptions<MvcOptions>, IPostConfigureOptions<MvcOptions>

    public void Configure(MvcOptions options)
    
        ...

        options.ModelBinderProviders.Add(new ByteArrayModelBinderProvider());

        ...
    

那么,现在的思路就是,实现IntArrayModelBinderProvider,然后调用options.ModelBinderProviders.Add(new IntArrayModelBinderProvider());

现在,关键就在于这个MvcOptions在哪访问?

AddControllers 方法

继续查找MvcOptions的所有引用。发现使用的地方不少,但是,其中有一个扩展方法:

public static IMvcBuilder AddControllers(this IServiceCollection services, Action<MvcOptions>? configure)

IServiceCollection是可以在 Startup.cs 中访问的:

public void ConfigureServices(IServiceCollection services)

实现

接下来就好办了。

  1. 实现IntArrayModelBinderProvider

public class IntArrayModelBinderProvider : IModelBinderProvider
 
    public IModelBinder? GetBinder(ModelBinderProviderContext context)
    
        if (context == null)
        
            throw new ArgumentNullException(nameof(context));
        

        if (context.Metadata.ModelType == typeof(int[]))
        
            return new IntArrayModelBinder();
        

        return null;
    
  1. 修改 Startup.cs:

public void ConfigureServices(IServiceCollection services)

    services.AddControllers(options =>
    
        options.ModelBinderProviders.Insert(0, new IntArrayModelBinderProvider());
    );
  1. 测试一下,执行成功:

[HttpGet]
public string Get([FromQuery]int[] values)

    return string.Join(" ", values.Select(p => p.ToString()));

结论

通过IntArrayModelBinderProvider,我们无需显示指定ModelBinder。即可让 ASP.NET Core 自动使用IntArrayModelBinder

添加微信号【MyIO666】,邀你加入技术交流群

以上是关于如何让 ASP.NET Core 支持绑定查询字符串中的数组的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 中的模型绑定将下划线映射到标题大小写属性名称

如何在 asp.net core web api 中绑定 Json Query 字符串

ASP.Net Core WebApi几种版本控制对比

让ASP.NET Core支持GraphQL - 手写中间件

问:如何在 ASP.NET Core 中执行查询字符串?

如何使用 ASP.NET Core 从查询字符串中读取值?