Как я могу заставить Swagger работать, используя перечисление типа short? - PullRequest
0 голосов
/ 20 октября 2018

В настоящее время я работаю над 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();
    }

Сбой при добавленииновое свойство для CustomerModel, если и только если Enum имеет тип short.

Спасибо за помощь!

1 Ответ

0 голосов
/ 20 октября 2018

Некоторое время назад я включил 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>();
...