0

I am developing some Openapi 3.0.1 APIs with .Net Core 3.1 using Swashbuckle.AspNetCore.Swagger and SwaggerGen v6.1.4. I want to build an API that receives an array query parameter; in ASP.NET Core the default call for an API like this is something like

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

but due to caller needs I want to accept something simpler, like

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

In other words, I want to generate a swagger.json that has an explode: false node

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

while the default is explode: true.

How can I do this? Thank you!

1 Answer 1

1

After some research I managed to use a custom 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);
    }
}

The relative factory:

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;
    }
}

... has to be inserted in Mvc options in Startup.cs:

services.AddMvc(options =>
        {
            options.ValueProviderFactories.Insert(0,
              new QueryStringCommaSeparatedValueProviderFactory());
        });
Sign up to request clarification or add additional context in comments.

1 Comment

This was a great help for me. However, this would cause any parameter (e.g., a string parameter) with a comma to be split. I've found this article that expands on this concept further to allow this to be set for an individual parameter: github.com/filipw/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.