Search code examples
c#swaggeropenapiswashbuckleminimal-apis

Using enums in routes


When using controllers you can use enums in routes but you have to add the following

builder.Services.AddControllers();
    .AddJsonOptions(options =>
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

or

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

Example controller

public enum Location
{
    London
}

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet("{location}")]
    public IEnumerable<WeatherForecast> Get(Location location)
    {
        ....
    }
}

After that enums resolve correctly in swagger/openapi enter image description here

"parameters": [
  {
    "name": "location",
    "in": "path",
    "required": true,
    "schema": {
      "$ref": "#/components/schemas/Location"
    }
  }
],

But when i do the same in minimal apis

public enum Location
{
    London
}

app.MapGet("/weatherforecast/{location}", (Location location) =>
{
    ...
})
.WithName("GetWeatherForecast")
.WithOpenApi();

And adding the same

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options =>
{
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});

It just treats the route parameter as a string instead of a enum enter image description here

"parameters": [
  {
    "name": "location",
    "in": "path",
    "required": true,
    "style": "simple",
    "schema": {
      "type": "string"
    }
  }
],

Is there someway to configure minimal apis to resolve enums in routes the same way?

The code for both minimal apis and controllers can be found here: https://github.com/AnderssonPeter/EnumInPath


Solution

  • Adding [FromRoute] to your route parameter solves the issue

    public enum Location
    {
        London
    }
    
    app.MapGet("/weatherforecast/{location}", ([FromRoute] Location location) =>
    {
        ...
    })
    .WithName("GetWeatherForecast")
    .WithOpenApi();
    

    You can also use it with [AsParameters]:

    public enum Location
    {
        London
    }
    
    public class Query
    {
        [FromRoute]
        public Location Location { get; set; }
    ]
    
    app.MapGet("/weatherforecast/{location}", ([AsParameters] Query query) =>
    {
        ...
    })
    .WithName("GetWeatherForecast")
    .WithOpenApi();