Как предоставить пользовательский тип generi c в виде строки в схеме Swagger, используя Swashbuckle.AspNetCore - PullRequest
2 голосов
/ 26 марта 2020

У меня есть собственный обобщенный тип c, который выглядит примерно так:

public struct Foo<T>
{
    public int Value { get; }
    public string Signature { get; }
    public Type Type { get; }
}

Этот тип используется в телах запросов и ответов и в параметрах действий контроллера. Все настроено так, что оно сериализуется как строка, и оно отлично работает с привязкой модели и сериализацией JSON. С типом связан TypeConverter, связанный с преобразованием его в строку и из нее.

Однако схема Swagger по-прежнему представляет его как объект с 3 свойствами. Свойство Type также расширено, в результате чего все типы System.Reflection отображаются прямо или косвенно с помощью Type.

Как можно избежать этого и представить свой тип в виде строки?


Первая попытка решения: с использованием MapType

Я пытался использовать MapType; он работает нормально, если я задаю аргумент типа generi c, но не работает с открытым типом generi c:

c.MapType(typeof(Foo<Something>), () => new OpenApiSchema { Type = "string" }); // Works
c.MapType(typeof(Foo<>), () => new OpenApiSchema { Type = "string" }); // Doesn't work

Как применить сопоставление к Foo<T> для любого T?


Текущий обходной путь

Пока что единственный обходной путь, который у меня есть, довольно уродлив:

class SchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type is Type type &&
            type.IsGenericType &&
            !type.IsGenericTypeDefinition &&
            type.GetGenericTypeDefinition() == typeof(Foo<>))
        {
            schema.Type = "string";
            schema.Properties.Clear();
        }
        else if (context.Type?.FullName.StartsWith("System.", StringComparison.Ordinal) is true
            && context.SchemaRepository.TryGetIdFor(context.Type, out var schemaId))
        {
            DocFilter.SchemaIdsToRemove.Add(schemaId);
        }
    }
}

class DocFilter : IDocumentFilter
{
    public static readonly HashSet<string> SchemaIdsToRemove = new HashSet<string>();

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        foreach (var schemaId in SchemaIdsToRemove)
        {
            swaggerDoc.Components.Schemas.Remove(schemaId);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...