Hi. In Swashbuckle.AspNetCore 5.0.0-rc4 method SwaggerGenOptions.DescribeAllEnumsAsStrings() marked as Obsolete. But without it attribute [Newtonsoft.Json.JsonProperty(ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))] is not working properly. See example below.
public class Program
{
public static void Main(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(b => b.UseStartup<Startup>())
.Build()
.Run();
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
=> services
.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "API", Version = "v1" }))
.AddControllers();
public void Configure(IApplicationBuilder app)
=> app
.UseSwagger()
.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"))
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapControllers());
}
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter), true)]
public enum OkEnum
{
Freezing, Bracing, Chilly, Cool
}
public enum BadEnum
{
Freezing, Bracing, Chilly, Cool
}
public class WeatherForecast
{
public DateTime Date { get; set; }
public OkEnum OkValue { get; set; }
[Newtonsoft.Json.JsonProperty(ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public List<BadEnum> BadValues { get; set; }
}
[ApiController]
[Route("weather")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public IEnumerable<WeatherForecast> Get()
=> Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
OkValue = OkEnum.Cool,
BadValues = new List<BadEnum> { BadEnum.Cool }
});
}

With SwaggerGenOptions.DescribeAllEnumsAsStrings()

I have the same problem
@artfulsage can you elaborate a little more on your usecase? I do understand the issue you're reporting but I guess I'm not understanding why you wouldn't just use the JsonConverterAttribute on the enum definition itself (as opposed to the property that uses it) - i.e. as you've demonstrated with OkEnum above.
The only reason I can think of to NOT do this is if you wanted to serialize the enum as a string in some cases (e.g. when part of a certain property) and as an integer in others. However, the DescribeAllEnumsAsStrings is a global setting applied to _all enums_ and therefore wouldn't support this scenario anyway.
I have the same problem (using 5.0.0 RC-5). I have tried adding a global JsonConvert (StringEnumConverter) to json serializer settings along with DescribeAllEnumsAsStrings, just DescribeAllEnumsAsStrings , StringEnumConverter on the enum itself. None of these options seem to work, the enums still return as integers. I am not sure what other information to display for this issue, but let me know.
@artfulsage - You're using Newtonsoft attributes, but Swashbuckle.AspNetCore 5.x uses System.Text.Json by default.
To fix this, either:
Use [JsonConverter(typeof(JsonStringEnumConverter))] from the System.Text.Json.Serialization namespace on your enum declarations
Or to convert all enums to strings, in your ConfigureServices method, add the following after AddControllers():
.AddJsonOptions(options => {
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
});
Swashbuckle.AspNetCore.Newtonsoft Nuget package and call services.AddSwaggerGenNewtonsoftSupport() in Startup.cs -> ConfigureServices@domaindrivendev, @jcoutch thanks for your feedback!
My enum is located in separated database project. And that's why I don't want to put any code for serialization there (JsonConverterAttribute).
Addition of services.AddSwaggerGenNewtonsoftSupport() seems not working in my real project.
But this works fine!
.AddJsonOptions(options => {
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
});
@domaindrivendev it might be helpful to add that to the docs/WIKI (FAQ) : services.AddSwaggerGenNewtonsoftSupport() for future reference, seems like it is a commonly asked question
@ddeisadzevp - I found it right on the main page:
https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/README.md#systemtextjson-stj-vs-newtonsoft
@artfulsage, when you use services.AddSwaggerGenNewtonsoftSupport(), then ensure that you add it _after_ you add services.AddSwaggerGen(...); otherwise, it won't work.
@domaindrivendev @jcoutch @tobyartisan perhaps I do something wrong but this code still does not work
netcoreapp3.1
Newtonsoft.Json 12.0.3
Swashbuckle.AspNetCore 5.2.1
Swashbuckle.AspNetCore.Newtonsoft 5.2.1
public class Program
{
public static void Main(string[] args)
=> Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(b => b.UseStartup<Startup>())
.Build()
.Run();
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson();
services
.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "API", Version = "v1" }))
.AddSwaggerGenNewtonsoftSupport();
}
public void Configure(IApplicationBuilder app)
=> app
.UseSwagger()
.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"))
.UseRouting()
.UseEndpoints(endpoints => endpoints.MapControllers());
}
public enum BadEnum
{
Freezing, Bracing, Chilly, Cool
}
public class WeatherForecast
{
public DateTime Date { get; set; }
[Newtonsoft.Json.JsonProperty(ItemConverterType = typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public List<BadEnum> BadValues { get; set; }
}
[ApiController]
[Route("weather")]
public class WeatherForecastController : ControllerBase
{
[HttpGet]
public IEnumerable<WeatherForecast> Get()
=> Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
BadValues = new List<BadEnum> { BadEnum.Cool }
});
}


@artfulsage Do you need to do this bit?
.AddJsonOptions(options => {
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
});
@artfulsage - unfortunately ItemConverterType isn't currently supported. As mentioned above, if you decorate your enum class directly as follows - the enum will be described correctly.
[JsonConverter(typeof(StringEnumConverter))]
public enum BadEnum
{
Freezing, Bracing, Chilly, Cool
}
However, it seems this may not be feasible for you. As many of the comments in this issue have deviated from the original, I think it would be best to create a new issue that specifically addresses the lack of support for enum serialization behavior that's configured via ItemConverterType
Most helpful comment
@artfulsage - You're using Newtonsoft attributes, but Swashbuckle.AspNetCore 5.x uses System.Text.Json by default.
To fix this, either:
Use
[JsonConverter(typeof(JsonStringEnumConverter))]from theSystem.Text.Json.Serializationnamespace on yourenumdeclarationsOr to convert all enums to strings, in your ConfigureServices method, add the following after
AddControllers():Swashbuckle.AspNetCore.NewtonsoftNuget package and callservices.AddSwaggerGenNewtonsoftSupport()in Startup.cs -> ConfigureServices