前言
有网友在交流群中询问,如何让 ASP.NET Core 支持绑定查询字符串中的数组:
据说,在 .NET 7 中已经支持了:
但是,在这之前的 .NET 版本能实现相同功能吗?
ByteArrayModelBinder
这时,群里的网友提供了一个思路,使用 base64 编码:
查看官方文档,确实可以实现:
缺点是只支持byte[]
,不能使用int[]
:
[HttpGet]
public string Get([FromQuery]byte[] values)
{return string.Join(" ", values.Select(p => p.ToString()));
}
但是,我们可以借鉴ByteArrayModelBinder
的实现思路,实现我们自己的IntArrayModelBinder
。
IntArrayModelBinder
查看ByteArrayModelBinder
的源码,关键代码如下:
public class ByteArrayModelBinder : IModelBinder
{public Task BindModelAsync(ModelBindingContext bindingContext){//获取传入的值var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);var value = valueProviderResult.FirstValue;//Base64 转 byte[]var model = Convert.FromBase64String(value);//绑定到参数bindingContext.Result = ModelBindingResult.Success(model);return Task.CompletedTask;}
}
我们依葫芦画瓢,实现IntArrayModelBinder
:
public class IntArrayModelBinder : IModelBinder
{public Task BindModelAsync(ModelBindingContext bindingContext){//获取传入的值var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);var value = valueProviderResult.FirstValue;//string 转 int[]var model = value.Trim('[',']').Split(',').Select(str=>int.Parse(str)).ToArray(); //绑定到参数bindingContext.Result = ModelBindingResult.Success(model);return Task.CompletedTask;}
}
测试一下使用IntArrayModelBinder
,执行成功:
[HttpGet]
public string Get([FromQuery][ModelBinder(BinderType = typeof(IntArrayModelBinder))] int[] values)
{return string.Join(" ", values.Select(p => p.ToString()));
}
结论
可能你已经注意到,在使用byte[]
时,我们并没有显示指定ModelBinder
。那ASP.NET Core 是如何实现自动使用ByteArrayModelBinder
的呢?我们下回分解。
添加微信号【MyIO666】,邀你加入技术交流群