Minimal API:将逗号分隔的多值参数转为字符串数组
实现直接接收逗号分隔的查询参数为字符串数组
在ASP.NET Core中,默认的查询参数数组是通过重复键(如/api/items?sizes=m&sizes=l)来绑定的,但要直接接收逗号分隔的/api/items?sizes=m,l,xxl为string[]类型,需要自定义模型绑定逻辑,以下是几种可行方案:
方案一:全局注册TypeConverter处理逗号分隔数组
1. 实现自定义TypeConverter
创建转换器,将逗号分隔的字符串转换为string[]:
using System.ComponentModel; using System.Globalization; public class StringArrayConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string str) { return string.IsNullOrEmpty(str) ? Array.Empty<string>() : str.Split(',', StringSplitOptions.RemoveEmptyEntries); } return base.ConvertFrom(context, culture, value); } }
2. 全局注册转换器
在Program.cs中注册转换器,让框架自动识别并处理string[]类型的查询参数:
builder.Services.AddControllers(options => { options.ModelBinderProviders.Insert(0, new TypeConverterModelBinderProvider()); }) .AddMvcOptions(options => { TypeDescriptor.AddAttributes(typeof(string[]), new TypeConverterAttribute(typeof(StringArrayConverter))); });
3. 直接使用参数
之后在控制器方法中可以直接接收参数:
[HttpGet("api/items")] public IActionResult GetItems([FromQuery] string[] sizes) { // sizes已经是分割后的字符串数组 return Ok(sizes); }
方案二:自定义模型绑定器(更灵活的控制)
1. 实现模型绑定器
using Microsoft.AspNetCore.Mvc.ModelBinding; public class CommaSeparatedArrayBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var value = valueProviderResult.FirstValue; var array = string.IsNullOrEmpty(value) ? Array.Empty<string>() : value.Split(',', StringSplitOptions.RemoveEmptyEntries); bindingContext.Result = ModelBindingResult.Success(array); return Task.CompletedTask; } }
2. 注册绑定器提供者
public class CommaSeparatedArrayBinderProvider : IModelBinderProvider { public IModelBinder GetBinder(ModelBinderProviderContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); if (context.Metadata.ModelType == typeof(string[])) return new CommaSeparatedArrayBinder(); return null; } }
3. 注册到服务
在Program.cs中添加绑定器:
builder.Services.AddControllers(options => { options.ModelBinderProviders.Insert(0, new CommaSeparatedArrayBinderProvider()); });
4. 使用方式
和方案一一样,直接在控制器中使用[FromQuery] string[] sizes即可。
方案三:局部使用TypeConverter(无需全局注册)
如果只需要在特定DTO或参数上生效,可在DTO的属性上添加转换器特性:
using System.ComponentModel; public class ItemQueryParams { [TypeConverter(typeof(StringArrayConverter))] public string[] Sizes { get; set; } }
控制器方法接收DTO:
[HttpGet("api/items")] public IActionResult GetItems([FromQuery] ItemQueryParams queryParams) { // 直接使用queryParams.Sizes return Ok(queryParams.Sizes); }
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

