You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:35:20