如何使用short类型的枚举使Swagger工作?

时间:2018-10-19 22:47:08

标签: c# enums asp.net-web-api2 swagger swashbuckle

我目前正在使用ASP.NET Web API 2(C#),并且一直使用Swashbuckle直到今天。我在现有模型中添加了一个属性,并中断了整个文档的生成,因此每当我进入 / help / ui / index#!/ 页面时,我现在都会看到以下内容:

500 : {"message":"An error has occurred."} 

下面的枚举是我添加到现有模型中的新属性。如果删除short类型继承,则一切正常。关于如何使用JsonConverter或自定义过滤器以确保Swagger不会中断的任何想法?

public enum TestEnum: short
{
    Unknown = 0,
    Green = 1
}

这是POST请求:

    [Route("{id:int:min(1)}/customers"), HttpPost]
    public IHttpActionResult PostCustomer(int id, [FromBody] CustomerModel customerModel)
    {
        return Ok();
    }

当且仅当枚举类型为short时,将新属性添加到CustomerModel时失败。

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我启用了IDocumentFilter一会儿,该帮助我们显示了Enum的整数和字符串值,以便为客户提供更多有用的详细信息。

问题是,此类仅将Enums强制转换为INT,因此我也必须对其进行更新以接受其他类型。这是我正在使用的课程:

public class SwaggerEnumDescriptions : 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?.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?.Count > 0)
                {
                    param.description += $": {DescribeEnum(paramEnums)}";
                }
            }
        }
    }

    private string DescribeEnum(IList<object> enums)
    {
        List<string> enumDescriptions = new List<string>();
        foreach (object enumOption in enums)
        {
            Type enumType = enumOption.GetType();
            object enumValue =
                Enum.GetUnderlyingType(enumType) == typeof(byte) ? (byte)enumOption :
                Enum.GetUnderlyingType(enumType) == typeof(short) ? (short)enumOption :
                Enum.GetUnderlyingType(enumType) == typeof(long) ? (long)enumOption :
                (int)enumOption;

            enumDescriptions.Add($"{enumValue} = {Enum.GetName(enumType, enumOption)}");
        }
        return string.Join(", ", enumDescriptions.ToArray());
    }
}

为了在您的Api上使用它,您需要将IDocumentFilter添加到Swagger Config:

c.DocumentFilter<SwaggerEnumDescriptions>();