I have an Enum declared on a API like this :
public enum Currencies
{
RON = 1,
USD,
EUR,
GBP,
CHF,
PLN,
CAD,
HUF,
NOK,
SEK
}
but when I use NSwag to generate a HttpClient, it starts from 0 and I obtain this:
public enum Currencies
{
[System.Runtime.Serialization.EnumMember(Value = @"RON")]
RON = 0,
[System.Runtime.Serialization.EnumMember(Value = @"USD")]
USD = 1,
[System.Runtime.Serialization.EnumMember(Value = @"EUR")]
EUR = 2,
[System.Runtime.Serialization.EnumMember(Value = @"GBP")]
GBP = 3,
[System.Runtime.Serialization.EnumMember(Value = @"CHF")]
CHF = 4,
[System.Runtime.Serialization.EnumMember(Value = @"PLN")]
PLN = 5,
[System.Runtime.Serialization.EnumMember(Value = @"CAD")]
CAD = 6,
[System.Runtime.Serialization.EnumMember(Value = @"HUF")]
HUF = 7,
[System.Runtime.Serialization.EnumMember(Value = @"NOK")]
NOK = 8,
[System.Runtime.Serialization.EnumMember(Value = @"SEK")]
SEK = 9,
}
the generated one starts from 0, while the initial one stars from 1. This leads to validation problems when I try to call the api. how can I map this ?
Some solutions can be found in Stackoverflow, but I had struggle with them and will like to resume how to pass from what you have here to the solution. What is really important, it's to remove this code you certainly have:
services.AddMvc().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
Or may be the following line in your swagger config
c.DescribeAllEnumsAsStrings()
When you do that, your generated code will look like that
public enum Currencies
{
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
_5 = 5,
_6 = 6,
_7 = 7,
_8 = 8,
_9 = 9
}
Now your values are correct, the issue is about the name. So you can use the solution describe here : https://stackoverflow.com/a/71526271/9466394 and implement the NSwagEnumExtensionSchemaFilter and the NSwagEnumOpenApiExtension whitch add the "x-enumNames" schema details.
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
/// <summary>
/// Adds extra schema details for an enum in the swagger.json i.e. x-enumNames (used by NSwag to generate Enums for C# client)
/// https://github.com/RicoSuter/NSwag/issues/1234
/// </summary>
public class NSwagEnumExtensionSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (schema is null)
throw new ArgumentNullException(nameof(schema));
if (context is null)
throw new ArgumentNullException(nameof(context));
if (context.Type.IsEnum)
schema.Extensions.Add("x-enumNames", new NSwagEnumOpenApiExtension(context));
}
}
using System.Text.Json;
using Microsoft.OpenApi;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Writers;
using Swashbuckle.AspNetCore.SwaggerGen;
public class NSwagEnumOpenApiExtension : IOpenApiExtension
{
private readonly SchemaFilterContext _context;
public NSwagEnumOpenApiExtension(SchemaFilterContext context)
{
_context = context;
}
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
{
string[] enums = Enum.GetNames(_context.Type);
JsonSerializerOptions options = new() { WriteIndented = true };
string value = JsonSerializer.Serialize(enums, options);
writer.WriteRaw(value);
}
}
services.AddSwaggerGen(c =>
{
...
c.SchemaFilter<NSwagEnumExtensionSchemaFilter>();
});
Now your generated code will look like:
public enum Currencies
{
[System.Runtime.Serialization.EnumMember(Value = @"RON")]
RON = 1,
[System.Runtime.Serialization.EnumMember(Value = @"USD")]
USD = 2,
[System.Runtime.Serialization.EnumMember(Value = @"EUR")]
EUR = 3,
[System.Runtime.Serialization.EnumMember(Value = @"GBP")]
GBP = 4,
[System.Runtime.Serialization.EnumMember(Value = @"CHF")]
CHF = 5,
[System.Runtime.Serialization.EnumMember(Value = @"PLN")]
PLN = 6,
[System.Runtime.Serialization.EnumMember(Value = @"CAD")]
CAD = 7,
[System.Runtime.Serialization.EnumMember(Value = @"HUF")]
HUF = 8,
[System.Runtime.Serialization.EnumMember(Value = @"NOK")]
NOK = 9,
[System.Runtime.Serialization.EnumMember(Value = @"SEK")]
SEK = 10
}
You can also add the EnumDocumentFilter if you want your swagger totally clean