Swagger UI Web Api documentation Present enums as strings?

后端 未结 20 1793
半阙折子戏
半阙折子戏 2020-11-27 11:31

Is there a way to display all enums as their string value in swagger instead of their int value?

I want to be able to submit POST actions and put enums according to

相关标签:
20条回答
  • 2020-11-27 11:32

    There were a number of shortcomings I found in the other answers for what we were looking for, so I thought I'd supply my own take on this. We're using ASP.NET Core 3.1 with System.Text.Json, but our approach works irrespective of the JSON serializer used.

    Our goal was to accept lower-camel-cased enum string values in both the ASP.NET Core API as well as document the same in Swagger. We're currently making use of [DataContract] and [EnumMember], so the approach is to take the lower-camel-cased value from the EnumMember value property and use that across the board.

    Our sample enum:

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

    We'll use the EnumMember values in Swashbuckle by using an ISchemaFilter as in the following:

    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));
                    }
                }
            }
        }
    }
    

    We're using a third-party NuGet package (GitHub repo) to ensure that this naming scheme is also utilized in ASP.NET Core. Configure it in Startup.cs within ConfigureServices with:

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

    Finally, we need to register our ISchemaFilter in Swashbuckle, so also add the following also in ConfigureServices():

    services.AddSwaggerGen(c => {
      c.SchemaFilter<DescribeEnumMemberValues>();
    });
    
    0 讨论(0)
  • 2020-11-27 11:34

    My variant for enum stings with values:

    Configure Services:

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

    Filter:

    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}")));
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-27 11:36

    ASP.NET Core 3.1

    To generate enums as strings using Newtonsoft JSON you must explicitly add Newtonsoft support by adding AddSwaggerGenNewtonsoftSupport() as follows:

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

    This is available via a new package, Swashbuckle.AspNetCore.Newtonsoft. It looks like everything else works fine without this package apart from enum converter support.

    0 讨论(0)
  • 2020-11-27 11:37

    With 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()));
    

    But it seems that Swashbuckle Version 5.0.0-rc4 is not ready to support that. So we need to use an option(deprecated) in the Swashbuckle config file until it supports and reflects it like Newtonsoft library.

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

    The difference between this answer and other answers is using only the Microsoft JSON library instead of Newtonsoft.

    0 讨论(0)
  • 2020-11-27 11:37

    If the version of the swagger were 5.5.x, then you need to:

    1. install: Install-Package Swashbuckle.AspNetCore.Newtonsoft -Version 5.5.0

    2. services.AddSwaggerGenNewtonsoftSupport();

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

    0 讨论(0)
  • 2020-11-27 11:38

    This is not possible with standard OpenAPI. Enums are described only with their string values.

    Fortunately you can do it with some non-standard extensions that are utilized by your client generator.

    NSwag supports x-enumNames

    AutoRest supports x-ms-enum.

    Openapi-generator supports x-enum-varnames

    Other generators might support one of these extensions or have their own.

    To generate x-enumNames for NSwag create the following schema filter:

    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);
            }
        }
    }
    

    And register it as:

    services.AddSwaggerGen(options =>
    {
        options.SchemaFilter<EnumSchemaFilter>();
    });
    
    0 讨论(0)
提交回复
热议问题