Swashbuckle.webapi: x-enumNames

Created on 23 Dec 2018  路  1Comment  路  Source: domaindrivendev/Swashbuckle.WebApi

VERSION:

Swashbuckle.AspNetCore -Version 3.0.0

STEPS TO REPRODUCE:

 public enum Currency
    {
        Unknown = 0,
        Usd,
        Euro,
    }

EXPECTED RESULT:

"currency": {
  "format": "int32",          
  "enum": [
    0,
    1,
    2
  ],
  "type": "integer",
  "x-enumNames": [
    "Unknown",            
    "Usd",
    "Euro"
  ]
}

ACTUAL RESULT:

"currency": {
  "format": "int32",          
  "enum": [
    0,
    1,
    2
  ],
  "type": "integer"
}

ADDITIONAL DETAILS

Please add x-enumNames attribute
It is very useful for NSwag integration and auto-generating client code
(see https://github.com/RSuter/NSwag/issues/1234 and https://stackoverflow.com/questions/36452468/swagger-ui-web-api-documentation-present-enums-as-strings)

It can be like

public class SwaggerAddEnumDescriptions : IDocumentFilter
    {
        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);
                        property.Extensions.Add("x-enumNames", GetStringMapping(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 string[] GetStringMapping(IList<object> enums)
        {
            var enumDescriptions = new List<string>();
            Type type = null;
            foreach (var enumOption in enums)
            {
                if (type == null) type = enumOption.GetType();
                enumDescriptions.Add(Enum.GetName(type, enumOption));
            }

            return enumDescriptions.ToArray();
        }

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

            foreach (var param in parameters)
            {
                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)}";
        }
    }

and usage

options.DocumentFilter<SwaggerAddEnumDescriptions>();
//options.DescribeAllEnumsAsStrings();

Most helpful comment

Currently you can do it as easy as:

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)));
            schema.Extensions.Add("x-enumNames", array);
        }
    }
}

And when configuring:

options.SchemaFilter<EnumSchemaFilter>();

>All comments

Currently you can do it as easy as:

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)));
            schema.Extensions.Add("x-enumNames", array);
        }
    }
}

And when configuring:

options.SchemaFilter<EnumSchemaFilter>();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

niemyjski picture niemyjski  路  3Comments

nf17 picture nf17  路  4Comments

Misiu picture Misiu  路  3Comments

kongres picture kongres  路  4Comments

joseph-ortiz picture joseph-ortiz  路  4Comments