Swagger UI Web Api documentation Present enums as strings?

后端 未结 20 1796
半阙折子戏
半阙折子戏 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:38

    If you are using newtonsof.json then use this

    using Newtonsoft.Json.Converters;
    
    
    [JsonConverter(typeof(StringEnumConverter))]
    public enum MyEnum
    {
        A, B
    }
    

    If you are using System.Text.Json.Serialization

    using System.Text.Json.Serialization;
    
    
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public enum MyEnum
    {
        A, B
    }
    
    0 讨论(0)
  • 2020-11-27 11:38

    ASP NET SOLUTION

    In my api docs one enum was still shown as int despite the property being marked with StringEnumConverter. We couldn't afford using the global setting for all enums mentioned above. Adding this line in SwaggerConfig solved the issue:

    c.MapType<ContactInfoType>(() => new Schema { type = "string", @enum = Enum.GetNames(typeof(ContactInfoType))});
    
    0 讨论(0)
  • 2020-11-27 11:40

    in .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++;
                    }
                }
            }
        }
    
    }
    

    and in Startup.cs :

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

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

    From the docs:

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

    Also, if you want this behavior only on a particular type and property, use the StringEnumConverter:

    public class Letter 
    {
        [Required]
        public string Content {get; set;}
    
        [Required]
        [EnumDataType(typeof(Priority))]
        [JsonConverter(typeof(StringEnumConverter))]
        public Priority Priority {get; set;}
    }
    
    0 讨论(0)
  • 2020-11-27 11:43

    .NET CORE 3.1 and SWAGGER 5

    if you need a simple solution to selectively make enums passed as strings:

    using System.Text.Json.Serialization;
    
    
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public enum MyEnum
    {
        A, B
    }
    

    Note, we use System.Text.Json.Serialization namespace, not the Newtonsoft.Json!

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

    I wanted to use rory_za's answer in a .NET Core application, but I had to modify it a bit to make it work. Here is the implementation I came up with for .NET Core.

    I also changed it so it doesn't assume the underlying type is int, and use new lines between the values for easier reading.

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

    Then add this to your ConfigureServices method in Startup.cs:

    c.DocumentFilter<EnumDocumentFilter>();
    
    0 讨论(0)
提交回复
热议问题