У меня есть собственный обобщенный тип 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);
}
}
}