193

有没有办法将所有枚举显示为它们的字符串值,而不是它们的 int 值?

我希望能够提交 POST 操作并根据其字符串值放置枚举,而不必每次都查看枚举。

我尝试过DescribeAllEnumsAsStrings,但服务器随后接收字符串而不是我们正在寻找的枚举值。

有没有人解决这个问题?

编辑:

public class Letter 
{
    [Required]
    public string Content {get; set;}

    [Required]
    [EnumDataType(typeof(Priority))]
    public Priority Priority {get; set;}
}


public class LettersController : ApiController
{
    [HttpPost]
    public IHttpActionResult SendLetter(Letter letter)
    {
        // Validation not passing when using DescribeEnumsAsStrings
        if (!ModelState.IsValid)
            return BadRequest("Not valid")

        ..
    }

    // In the documentation for this request I want to see the string values of the enum before submitting: Low, Medium, High. Instead of 0, 1, 2
    [HttpGet]
    public IHttpActionResult GetByPriority (Priority priority)
    {

    }
}


public enum Priority
{
    Low, 
    Medium,
    High
}
4

24 回答 24

253

全局启用

文档

httpConfiguration
    .EnableSwagger(c => 
        {
            c.SingleApiVersion("v1", "A title for your API");
            
            c.DescribeAllEnumsAsStrings(); // this will do the trick
        });

特定属性的枚举/字符串转换

此外,如果您只想在特定类型和属性上使用此行为,请使用 StringEnumConverter:

public class Letter 
{
    [Required]
    public string Content {get; set;}

    [Required]
    [EnumDataType(typeof(Priority))]
    [JsonConverter(typeof(StringEnumConverter))]
    public Priority Priority {get; set;}
}

如果您使用 Newtonsoft 和 Swashbuckle v5.0.0 或更高版本

你还需要这个包:

Swashbuckle.AspNetCore.Newtonsoft

这在你的启动中:

services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()

这里有文档:https ://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj-vs-newtonsoft

于 2016-06-06T13:26:11.227 回答
237

对于带有 Microsoft JSON 库 (System.Text.Json) 的 ASP.NET Core 3

在 Startup.cs/ConfigureServices() 中:

services
    .AddControllersWithViews(...) // or AddControllers() in a Web API
    .AddJsonOptions(options => 
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

对于带有 Json.NET (Newtonsoft.Json) 库的 ASP.NET Core 3

安装Swashbuckle.AspNetCore.Newtonsoft软件包。

在 Startup.cs/ConfigureServices() 中:

services
    .AddControllersWithViews(...)
    .AddNewtonsoftJson(options => 
        options.SerializerSettings.Converters.Add(new StringEnumConverter()));
// order is vital, this *must* be called *after* AddNewtonsoftJson()
services.AddSwaggerGenNewtonsoftSupport();

对于 ASP.NET Core 2

在 Startup.cs/ConfigureServices() 中:

services
    .AddMvc(...)
    .AddJsonOptions(options => 
        options.SerializerSettings.Converters.Add(new StringEnumConverter()));

预 ASP.NET Core

httpConfiguration
    .EnableSwagger(c => 
        {
            c.DescribeAllEnumsAsStrings();
        });
于 2019-04-05T18:55:00.633 回答
51

所以我想我也有类似的问题。我正在寻找 swagger 来生成枚举以及 int -> 字符串映射。API 必须接受 int。swagger-ui 没那么重要,我真正想要的是代码生成在另一边有一个“真正的”枚举(在这种情况下,android 应用程序使用改造)。

所以从我的研究来看,这最终似乎是 Swagger 使用的 OpenAPI 规范的一个限制。无法为枚举指定名称和编号。

我发现要遵循的最佳问题是https://github.com/OAI/OpenAPI-Specification/issues/681看起来像“可能很快”但随后必须更新 Swagger,在我的情况下 Swashbuckle 为出色地。

现在我的解决方法是实现一个文档过滤器,它查找枚举并使用枚举的内容填充相关描述。

        GlobalConfiguration.Configuration
            .EnableSwagger(c =>
                {
                    c.DocumentFilter<SwaggerAddEnumDescriptions>();

                    //disable this
                    //c.DescribeAllEnumsAsStrings()

SwaggerAddEnumDescriptions.cs:

using System;
using System.Web.Http.Description;
using Swashbuckle.Swagger;
using System.Collections.Generic;

public class SwaggerAddEnumDescriptions : IDocumentFilter
{
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
    {
        // add enum descriptions to result models
        foreach (KeyValuePair<string, Schema> schemaDictionaryItem in swaggerDoc.definitions)
        {
            Schema schema = schemaDictionaryItem.Value;
            foreach (KeyValuePair<string, Schema> propertyDictionaryItem in schema.properties)
            {
                Schema property = propertyDictionaryItem.Value;
                IList<object> propertyEnums = property.@enum;
                if (propertyEnums != null && propertyEnums.Count > 0)
                {
                    property.description += DescribeEnum(propertyEnums);
                }
            }
        }

        // add enum descriptions to input parameters
        if (swaggerDoc.paths.Count > 0)
        {
            foreach (PathItem pathItem in swaggerDoc.paths.Values)
            {
                DescribeEnumParameters(pathItem.parameters);

                // head, patch, options, delete left out
                List<Operation> possibleParameterisedOperations = new List<Operation> { pathItem.get, pathItem.post, pathItem.put };
                possibleParameterisedOperations.FindAll(x => x != null).ForEach(x => DescribeEnumParameters(x.parameters));
            }
        }
    }

    private void DescribeEnumParameters(IList<Parameter> parameters)
    {
        if (parameters != null)
        {
            foreach (Parameter param in parameters)
            {
                IList<object> paramEnums = param.@enum;
                if (paramEnums != null && paramEnums.Count > 0)
                {
                    param.description += DescribeEnum(paramEnums);
                }
            }
        }
    }

    private string DescribeEnum(IList<object> enums)
    {
        List<string> enumDescriptions = new List<string>();
        foreach (object enumOption in enums)
        {
            enumDescriptions.Add(string.Format("{0} = {1}", (int)enumOption, Enum.GetName(enumOption.GetType(), enumOption)));
        }
        return string.Join(", ", enumDescriptions.ToArray());
    }

}

这会在您的 swagger-ui 上产生类似以下内容,因此至少您可以“看到您在做什么”: 在此处输入图像描述

于 2017-03-28T15:42:58.650 回答
40

ASP.NET 核心 3.1

要使用 Newtonsoft JSON 将枚举生成为字符串,您必须通过添加AddSwaggerGenNewtonsoftSupport()以下内容显式添加 Newtonsoft 支持:

services.AddMvc()
    ...
    .AddNewtonsoftJson(opts =>
    {
        opts.SerializerSettings.Converters.Add(new StringEnumConverter());
    });


services.AddSwaggerGen(...);
services.AddSwaggerGenNewtonsoftSupport(); //

这可以通过一个新的包Swashbuckle.AspNetCore.Newtonsoft. 看起来除了枚举转换器支持之外,如果没有这个包,其他一切都可以正常工作。

于 2020-01-21T01:55:00.960 回答
29

.NET CORE 3.1 和 SWAGGER 5

如果您需要一个简单的解决方案来选择性地将枚举作为字符串传递:

using System.Text.Json.Serialization;


[JsonConverter(typeof(JsonStringEnumConverter))]
public enum MyEnum
{
    A, B
}

注意,我们使用System.Text.Json.Serialization命名空间,而不是Newtonsoft.Json!

于 2020-02-12T05:19:37.213 回答
24

我想在 .NET Core 应用程序中使用 rory_za 的答案,但我必须对其进行一些修改才能使其正常工作。这是我为 .NET Core 提出的实现。

我还对其进行了更改,因此它不假定基础类型为int,并在值之间使用新行以便于阅读。

/// <summary>
/// Add enum value descriptions to Swagger
/// </summary>
public class EnumDocumentFilter : IDocumentFilter {
    /// <inheritdoc />
    public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) {
        // add enum descriptions to result models
        foreach (var schemaDictionaryItem in swaggerDoc.Definitions) {
            var schema = schemaDictionaryItem.Value;
            foreach (var propertyDictionaryItem in schema.Properties) {
                var property = propertyDictionaryItem.Value;
                var propertyEnums = property.Enum;
                if (propertyEnums != null && propertyEnums.Count > 0) {
                    property.Description += DescribeEnum(propertyEnums);
                }
            }
        }

        if (swaggerDoc.Paths.Count <= 0) return;

        // add enum descriptions to input parameters
        foreach (var pathItem in swaggerDoc.Paths.Values) {
            DescribeEnumParameters(pathItem.Parameters);

            // head, patch, options, delete left out
            var possibleParameterisedOperations = new List<Operation> {pathItem.Get, pathItem.Post, pathItem.Put};
            possibleParameterisedOperations.FindAll(x => x != null)
                .ForEach(x => DescribeEnumParameters(x.Parameters));
        }
    }

    private static void DescribeEnumParameters(IList<IParameter> parameters) {
        if (parameters == null) return;

        foreach (var param in parameters) {
            if (param is NonBodyParameter nbParam && nbParam.Enum?.Any() == true) {
                param.Description += DescribeEnum(nbParam.Enum);
            } else if (param.Extensions.ContainsKey("enum") && param.Extensions["enum"] is IList<object> paramEnums &&
                paramEnums.Count > 0) {
                param.Description += DescribeEnum(paramEnums);
            }
        }
    }

    private static string DescribeEnum(IEnumerable<object> enums) {
        var enumDescriptions = new List<string>();
        Type type = null;
        foreach (var enumOption in enums) {
            if (type == null) type = enumOption.GetType();
            enumDescriptions.Add($"{Convert.ChangeType(enumOption, type.GetEnumUnderlyingType())} = {Enum.GetName(type, enumOption)}");
        }

        return $"{Environment.NewLine}{string.Join(Environment.NewLine, enumDescriptions)}";
    }
}

ConfigureServices然后在 Startup.cs中将其添加到您的方法中:

c.DocumentFilter<EnumDocumentFilter>();
于 2018-04-20T12:35:06.170 回答
21

如果有人有兴趣,我已经修改了代码以使用

.NET CORE 3Swagger V5

    public class SwaggerAddEnumDescriptions : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // add enum descriptions to result models
        foreach (var property in swaggerDoc.Components.Schemas.Where(x => x.Value?.Enum?.Count > 0))
        {
            IList<IOpenApiAny> propertyEnums = property.Value.Enum;
            if (propertyEnums != null && propertyEnums.Count > 0)
            {
                property.Value.Description += DescribeEnum(propertyEnums, property.Key);
            }
        }

        // add enum descriptions to input parameters
        foreach (var pathItem in swaggerDoc.Paths.Values)
        {
            DescribeEnumParameters(pathItem.Operations, swaggerDoc);
        }
    }

    private void DescribeEnumParameters(IDictionary<OperationType, OpenApiOperation> operations, OpenApiDocument swaggerDoc)
    {
        if (operations != null)
        {
            foreach (var oper in operations)
            {
                foreach (var param in oper.Value.Parameters)
                {
                    var paramEnum = swaggerDoc.Components.Schemas.FirstOrDefault(x => x.Key == param.Name);
                    if (paramEnum.Value != null)
                    {
                        param.Description += DescribeEnum(paramEnum.Value.Enum, paramEnum.Key);
                    }
                }
            }
        }
    }

    private Type GetEnumTypeByName(string enumTypeName)
    {
        return AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .FirstOrDefault(x => x.Name == enumTypeName);
    }

    private string DescribeEnum(IList<IOpenApiAny> enums, string proprtyTypeName)
    {
        List<string> enumDescriptions = new List<string>();
        var enumType = GetEnumTypeByName(proprtyTypeName);
        if (enumType == null)
            return null;

        foreach (IOpenApiAny enumOption in enums)
        {
            if (enumOption is OpenApiString @string)
            {
                string enumString = @string.Value;

                enumDescriptions.Add(string.Format("{0} = {1}", (int)Enum.Parse(enumType, enumString), enumString));
            }
            else if (enumOption is OpenApiInteger integer)
            {
                int enumInt = integer.Value;

                enumDescriptions.Add(string.Format("{0} = {1}", enumInt, Enum.GetName(enumType, enumInt)));
            }
        }

        return string.Join(", ", enumDescriptions.ToArray());
    }
}
于 2019-12-25T12:09:58.220 回答
18

我的枚举变量带有值:

在此处输入图像描述

配置服务:

services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "web server api", Version = "v1" });
                c.SchemaFilter<EnumSchemaFilter>();
            });

筛选:

public class EnumSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema model, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                model.Enum.Clear();
                Enum.GetNames(context.Type)
                    .ToList()
                    .ForEach(name => model.Enum.Add(new OpenApiString($"{Convert.ToInt64(Enum.Parse(context.Type, name))} - {name}")));
            }
        }
    }
于 2020-05-20T05:56:07.080 回答
14

用 asp.net 核心 3

using System.Text.Json.Serialization;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
         services.AddControllers().AddJsonOptions(options =>
             options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

但似乎 Swashbuckle 版本 5.0.0-rc4 还没有准备好支持它。所以我们需要在 Swashbuckle 配置文件中使用一个选项(不推荐使用),直到它像 Newtonsoft 库一样支持和反映它。

public void ConfigureServices(IServiceCollection services)
{ 
      services.AddSwaggerGen(c =>
      {
            c.DescribeAllEnumsAsStrings();

此答案与其他答案之间的区别在于仅使用 Microsoft JSON 库而不是 Newtonsoft。

于 2019-10-17T08:37:44.933 回答
12

这对于标准 OpenAPI 是不可能的。枚举只用它们的字符串值来描述。

幸运的是,您可以使用客户端生成器使用的一些非标准扩展来做到这一点。

NSwag 支持x-enumNames

AutoRest 支持x-ms-enum.

Openapi 生成器支持x-enum-varnames

其他生成器可能支持这些扩展之一或拥有自己的扩展。

x-enumNames为 NSwag 生成,请创建以下模式过滤器:

public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            var array = new OpenApiArray();
            array.AddRange(Enum.GetNames(context.Type).Select(n => new OpenApiString(n)));
            // NSwag
            schema.Extensions.Add("x-enumNames", array);
            // Openapi-generator
            schema.Extensions.Add("x-enum-varnames", array);
        }
    }
}

并将其注册为:

services.AddSwaggerGen(options =>
{
    options.SchemaFilter<EnumSchemaFilter>();
});
于 2020-07-07T22:26:13.610 回答
9

对于 .NET core 5 ,它与要添加的 .NET core 3.1 相同

   options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());

例子:

services.AddControllers(options =>
{
    options.ReturnHttpNotAcceptable = true;
    var builder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();
    options.Filters.Add(new AuthorizeFilter(builder.Build()));
 }).AddJsonOptions(options =>
 {
    options.JsonSerializerOptions.IgnoreNullValues = true;
    options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
 });
于 2020-12-29T18:59:25.020 回答
7

我在这里找到了很好的解决方法:

@PauloVetor - 使用 ShemaFilter 解决它,如下所示:

public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            model.Enum.Clear();
            Enum.GetNames(context.Type)
                .ToList()
                .ForEach(n => model.Enum.Add(new OpenApiString(n)));
            }
        }
    }
}

在 Startup.cs 中:

services.AddSwaggerGen(options =>
{
    options.SchemaFilter<EnumSchemaFilter>();
}
于 2020-02-06T08:55:00.903 回答
7

我已经修改了 Hosam Rehani 的答案以使用可空枚举和枚举集合。仅当属性的名称与其类型完全相同时,上一个答案才有效。所有这些问题都在下面的代码中得到解决。

它适用于 .net core 3.x 和 swagger 5.x。

在某些情况下不搜索枚举类型两次可能会更有效。

class SwaggerAddEnumDescriptions : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // add enum descriptions to result models
        foreach (var property in swaggerDoc.Components.Schemas.Where(x => x.Value?.Enum?.Count > 0))
        {
            IList<IOpenApiAny> propertyEnums = property.Value.Enum;
            if (propertyEnums != null && propertyEnums.Count > 0)
            {
                property.Value.Description += DescribeEnum(propertyEnums, property.Key);
            }
        }

        // add enum descriptions to input parameters
        foreach (var pathItem in swaggerDoc.Paths)
        {
            DescribeEnumParameters(pathItem.Value.Operations, swaggerDoc, context.ApiDescriptions, pathItem.Key);
        }
    }

    private void DescribeEnumParameters(IDictionary<OperationType, OpenApiOperation> operations, OpenApiDocument swaggerDoc, IEnumerable<ApiDescription> apiDescriptions, string path)
    {
        path = path.Trim('/');
        if (operations != null)
        {
            var pathDescriptions = apiDescriptions.Where(a => a.RelativePath == path);
            foreach (var oper in operations)
            {
                var operationDescription = pathDescriptions.FirstOrDefault(a => a.HttpMethod.Equals(oper.Key.ToString(), StringComparison.InvariantCultureIgnoreCase));
                foreach (var param in oper.Value.Parameters)
                {
                    var parameterDescription = operationDescription.ParameterDescriptions.FirstOrDefault(a => a.Name == param.Name);
                    if (parameterDescription != null && TryGetEnumType(parameterDescription.Type, out Type enumType))
                    {
                        var paramEnum = swaggerDoc.Components.Schemas.FirstOrDefault(x => x.Key == enumType.Name);
                        if (paramEnum.Value != null)
                        {
                            param.Description += DescribeEnum(paramEnum.Value.Enum, paramEnum.Key);
                        }
                    }
                }
            }
        }
    }

    bool TryGetEnumType(Type type, out Type enumType)
    {
        if (type.IsEnum)
        {
            enumType = type;
            return true;
        }
        else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            var underlyingType = Nullable.GetUnderlyingType(type);
            if (underlyingType != null && underlyingType.IsEnum == true)
            {
                enumType = underlyingType;
                return true;
            }
        }
        else
        {
            Type underlyingType = GetTypeIEnumerableType(type);
            if (underlyingType != null && underlyingType.IsEnum)
            {
                enumType = underlyingType;
                return true;
            }
            else
            {
                var interfaces = type.GetInterfaces();
                foreach (var interfaceType in interfaces)
                {
                    underlyingType = GetTypeIEnumerableType(interfaceType);
                    if (underlyingType != null && underlyingType.IsEnum)
                    {
                        enumType = underlyingType;
                        return true;
                    }
                }
            }
        }

        enumType = null;
        return false;
    }

    Type GetTypeIEnumerableType(Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            var underlyingType = type.GetGenericArguments()[0];
            if (underlyingType.IsEnum)
            {
                return underlyingType;
            }
        }

        return null;
    }

    private Type GetEnumTypeByName(string enumTypeName)
    {
        return AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .FirstOrDefault(x => x.Name == enumTypeName);
    }

    private string DescribeEnum(IList<IOpenApiAny> enums, string proprtyTypeName)
    {
        List<string> enumDescriptions = new List<string>();
        var enumType = GetEnumTypeByName(proprtyTypeName);
        if (enumType == null)
            return null;

        foreach (OpenApiInteger enumOption in enums)
        {
            int enumInt = enumOption.Value;

            enumDescriptions.Add(string.Format("{0} = {1}", enumInt, Enum.GetName(enumType, enumInt)));
        }

        return string.Join(", ", enumDescriptions.ToArray());
    }
}

使用过滤器添加c.DocumentFilter<SwaggerAddEnumDescriptions>();到 swagger 配置中Startup.cs

于 2020-04-20T08:04:40.943 回答
6

简单的解决方案。这个对我有用。

   using System.Text.Json.Serialization;
    
    
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public enum Priority
    {
        Low, 
        Medium,
        High
    }
于 2021-05-11T08:30:44.970 回答
5

如果您使用的是 newtonsof.json 然后使用这个

using Newtonsoft.Json.Converters;


[JsonConverter(typeof(StringEnumConverter))]
public enum MyEnum
{
    A, B
}

如果您使用 System.Text.Json.Serialization

using System.Text.Json.Serialization;


[JsonConverter(typeof(JsonStringEnumConverter))]
public enum MyEnum
{
    A, B
}
于 2020-09-17T12:45:02.500 回答
4

在 .net 核心 3.1 和 swagger 5.0.0 中:

using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace WebFramework.Swagger
{
    public class EnumSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                var enumValues = schema.Enum.ToArray();
                var i = 0;
                schema.Enum.Clear();
                foreach (var n in Enum.GetNames(context.Type).ToList())
                {
                    schema.Enum.Add(new OpenApiString(n + $" = {((OpenApiPrimitive<int>)enumValues[i]).Value}"));
                    i++;
                }
            }
        }
    }

}

在 Startup.cs 中:

services.AddSwaggerGen(options =>
            {
                #region  EnumDesc
                options.SchemaFilter<EnumSchemaFilter>();
                #endregion
            });

结果

于 2020-03-09T08:14:38.770 回答
4

我刚做了这个,效果很好!

启动.cs

services.AddSwaggerGen(c => {
  c.DescribeAllEnumsAsStrings();
});

模型.cs

public enum ColumnType {
  DATE = 0
}

招摇.json

type: {
  enum: ["DATE"],
  type: "string"
}

我希望这对您有所帮助!

于 2019-02-22T15:13:53.217 回答
2

在 Startup.cs 中编写代码

services.AddSwaggerGen(c => {
      c.DescribeAllEnumsAsStrings();
    });
于 2019-04-01T05:05:21.703 回答
2

如果 swagger 的版本是 5.5.x,那么你需要:

  1. 安装:安装包 Swashbuckle.AspNetCore.Newtonsoft -版本 5.5.0

  2. services.AddSwaggerGenNewtonsoftSupport();

参考:https ://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj-vs-newtonsoft

于 2020-08-02T07:50:06.850 回答
1

要在 swagger 中将枚举显示为字符串,请配置 JsonStringEnumConverter,在 ConfigureServices 中添加以下行:

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

如果您想将枚举显示为 stings 和 int 值,您可以尝试创建一个 EnumSchemaFilter 来更改架构。代码如下:

public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            model.Enum.Clear();
            Enum.GetNames(context.Type)
                .ToList()
                .ForEach(name => model.Enum.Add(new OpenApiString($"{Convert.ToInt64(Enum.Parse(context.Type, name))} = {name}")));
        }
    }
}

配置 SwaggerGen 以使用上述 ShemaFilter。

services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Version = "v1",
                Title = "ToDo API",
                Description = "A simple example ASP.NET Core Web API",
                TermsOfService = new Uri("https://example.com/terms"),
                Contact = new OpenApiContact
                {
                    Name = "Shayne Boyer",
                    Email = string.Empty,
                    Url = new Uri("https://twitter.com/spboyer"),
                },
                License = new OpenApiLicense
                {
                    Name = "Use under LICX",
                    Url = new Uri("https://example.com/license"),
                }
            });
              
            c.SchemaFilter<EnumSchemaFilter>();
        });
于 2021-11-29T10:57:25.013 回答
1

我在我们正在寻找的其他答案中发现了许多缺点,所以我想我会对此提供自己的看法。我们将 ASP.NET Core 3.1 与 System.Text.Json 结合使用,但我们的方法与使用的 JSON 序列化程序无关。

我们的目标是在 ASP.NET Core API 以及在 Swagger 中记录相同的文档时,都接受小写的枚举字符串值。我们目前正在使用[DataContract]and [EnumMember],因此该方法是从 EnumMember value 属性中获取小写字母的值并全面使用它。

我们的示例枚举:

[DataContract]
public class enum Colors
{
  [EnumMember(Value="brightPink")]
  BrightPink,
  [EnumMember(Value="blue")]
  Blue
}

我们将通过使用 ISchemaFilter 在 Swashbuckle 中使用 EnumMember 值,如下所示:

public class DescribeEnumMemberValues : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            schema.Enum.Clear();

            //Retrieve each of the values decorated with an EnumMember attribute
            foreach (var member in context.Type.GetMembers())
            {
                var memberAttr = member.GetCustomAttributes(typeof(EnumMemberAttribute), false).FirstOrDefault();
                if (memberAttr != null)
                {
                    var attr = (EnumMemberAttribute) memberAttr;
                    schema.Enum.Add(new OpenApiString(attr.Value));
                }
            }
        }
    }
}

我们正在使用第三方 NuGet 包(GitHub repo ) 以确保在 ASP.NET Core 中也使用此命名方案。在 ConfigureServices 的 Startup.cs 中配置它:

services.AddControllers()
  .AddJsonOptions(opt => opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverterWithAttributeSupport()));

最后,我们需要在 Swashbuckle 中注册我们的 ISchemaFilter,所以还要在 ConfigureServices() 中添加以下内容:

services.AddSwaggerGen(c => {
  c.SchemaFilter<DescribeEnumMemberValues>();
});
于 2020-01-25T18:50:36.687 回答
1

ASP.NET 核心 6

在您的 program.cs 中:

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

另请注意:

DescribeAllEnumsAsStrings 已过时

于 2022-02-19T20:12:22.843 回答
0

.Net Core 3.0

   using Newtonsoft.Json.Converters;

 services
    .AddMvc(options =>
    {
     options.EnableEndpointRouting = false;
     })
    .AddNewtonsoftJson(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()))
于 2019-10-10T21:00:22.817 回答
0

ASP 网络解决方案

在我的 api 文档中,一个枚举仍然显示为 int 尽管属性被标记为StringEnumConverter. 我们无法为上述所有枚举使用全局设置。在 SwaggerConfig 中添加这一行解决了这个问题:

c.MapType<ContactInfoType>(() => new Schema { type = "string", @enum = Enum.GetNames(typeof(ContactInfoType))});
于 2019-12-05T08:44:00.770 回答