使用 openapi 3.0.1 和 .Net Core 3.1 和 Swashbucle.AspNetCore.SwaggerGen 在 swagger.json 中为数组查询参数生成 explode: false

Generating explode: false for array query parameters in swagger.json using openapi 3.0.1 and .Net Core 3.1 and Swashbucle.AspNetCore.SwaggerGen

我正在使用 Swashbuckle.AspNetCore.Swagger 和 SwaggerGen v6.1.4 开发一些带有 .Net Core 3.1 的 Openapi 3.0.1 APIs。我想构建一个接收数组查询参数的 API;在 ASP.NET 核心中,像这样的 API 的默认调用类似于

https://someUrl/?values=valore1&values=valore2

但由于来电者的需要,我想接受一些更简单的东西,比如

https://someUrl/?values=valore1,valore2

换句话说,我想生成一个 swagger.json 有一个 explode: false 节点

  parameters:
    - name: values
      in: query
      explode: false
      schema:
        type: array
        items:
          type: string

而默认值是 explode: true。

我该怎么做? 谢谢!

经过一番研究,我设法使用了自定义 QueryStringValueProvider:

public class QueryStringCommaSeparatedValueProvider : QueryStringValueProvider
{
    public QueryStringCommaSeparatedValueProvider(
      BindingSource bindingSource,
      IQueryCollection values,
      CultureInfo culture) : base(bindingSource, values, culture)
    { }

    public override ValueProviderResult GetValue(string key)
    {
        var result = base.GetValue(key);

        if (result == ValueProviderResult.None)
        {
            return result;
        }

        var values = result.SelectMany(r => r.Split(","));

        return new ValueProviderResult(
          new StringValues(values.ToArray()),
          Culture);
    }
}

相关厂家:

public class QueryStringCommaSeparatedValueProviderFactory : IValueProviderFactory
{
    public Task CreateValueProviderAsync(ValueProviderFactoryContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var query = context.ActionContext.HttpContext.Request.Query;
        if (query != null && query.Count > 0)
        {
            var valueProvider = new QueryStringCommaSeparatedValueProvider(
              BindingSource.Query,
              query,
              CultureInfo.InvariantCulture);

            context.ValueProviders.Add(valueProvider);
        }

        return Task.CompletedTask;
    }
}

... 必须在 Startup.cs 中的 Mvc 选项中插入:

services.AddMvc(options =>
        {
            options.ValueProviderFactories.Insert(0,
              new QueryStringCommaSeparatedValueProviderFactory());
        });