是否有一种方法显示所有枚举作为他们的字符串值在swagger而不是他们的int值?

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

我尝试了DescribeAllEnumsAsStrings,但服务器然后接收字符串而不是enum值,这不是我们要寻找的。

有人解决了吗?

编辑:

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
}

当前回答

在。net core 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
            });

其他回答

使全球

从文档中可以看出:

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

特定属性的Enum/字符串转换

另外,如果你想让这种行为只发生在特定的类型和属性上,使用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

在这里搜索答案后,我发现了在模式中显示枚举的问题的部分解决方案[SomeEnumString = 0, AnotherEnumString = 1],但与此相关的所有答案都只是部分正确的,正如@OhWelp在其中一个评论中提到的那样。

下面是。net core的完整解决方案(2、3,目前在6上工作):

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

                var names = Enum.GetNames(context.Type).ToList();

                names.ForEach(name => model.Enum.Add(new OpenApiString($"{GetEnumIntegerValue(name, context)} = {name}")));


                 // the missing piece that will make sure that the new schema will not replace the mock value with a wrong value 
                // this is the default behavior - the first possible enum value as a default "example" value
                model.Example = new OpenApiInteger(GetEnumIntegerValue(names.First(), context));
            }
        }

        private int GetEnumIntegerValue(string name, SchemaFilterContext context) => Convert.ToInt32(Enum.Parse(context.Type, name));
    }

在启动/程序中:

    services.AddSwaggerGen(options =>
        {
            options.SchemaFilter<EnumSchemaFilter>();
        });

编辑:对代码进行了一些重构,如果你想看到原始版本,它与其余的答案更相似,请检查编辑的年表。

在。net core 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
            });

asp.net core 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 Version 5.0.0-rc4似乎还没有准备好支持这个功能。所以我们需要在Swashbuckle配置文件中使用一个选项(已弃用),直到它像Newtonsoft库一样支持和反映它。

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

这个答案和其他答案之间的区别是只使用Microsoft JSON库而不是Newtonsoft。

在Startup.cs中编写代码

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