NSwag Enum 生成从 0 开始

Rad*_*anu 4 web swagger swagger-ui asp.net-core nswag

我在 API 上声明了一个枚举,如下所示:

 public enum Currencies
    {
        RON = 1,
        USD,
        EUR,
        GBP,
        CHF,
        PLN,
        CAD,
        HUF,
        NOK,
        SEK
    }
Run Code Online (Sandbox Code Playgroud)

但是当我使用 NSwag 生成 HttpClient 时,它从 0 开始,我得到:

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,

    }
Run Code Online (Sandbox Code Playgroud)

生成的从 0 开始,而最初的 1 从 1 开始。这会导致我尝试调用 api 时出现验证问题。我怎样才能映射这个?

小智 5

一些解决方案可以在 Stackoverflow 中找到,但我一直在努力解决它们,并且想继续讨论如何从这里的内容传递到解决方案。真正重要的是删除您确实拥有的这段代码:

        services.AddMvc().AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        });
Run Code Online (Sandbox Code Playgroud)

或者可能是你的 swagger 配置中的以下行

c.DescribeAllEnumsAsStrings()
Run Code Online (Sandbox Code Playgroud)

当你这样做时,你生成的代码将如下所示

public enum Currencies
{

    _1 = 1,

    _2 = 2,

    _3 = 3,

    _4 = 4,

    _5 = 5,

    _6 = 6,

    _7 = 7,

    _8 = 8,

    _9 = 9
}
Run Code Online (Sandbox Code Playgroud)

现在您的值是正确的,问题在于名称。因此,您可以使用此处描述的解决方案: https: //stackoverflow.com/a/71526271/9466394 并实现 NSwagEnumExtensionSchemaFilter 和 NSwagEnumOpenApiExtension ,其中添加“x-enumNames”架构详细信息。

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));
    }
}
Run Code Online (Sandbox Code Playgroud)
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);
    }
}
Run Code Online (Sandbox Code Playgroud)
services.AddSwaggerGen(c =>
{
    ...
    c.SchemaFilter<NSwagEnumExtensionSchemaFilter>();
});
Run Code Online (Sandbox Code Playgroud)

现在您生成的代码将如下所示:

    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
  }
Run Code Online (Sandbox Code Playgroud)

如果您希望 swagger 完全干净,您还可以添加 EnumDocumentFilter