我有一个自定义泛型类型,大致如下所示:
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
;如果我指定泛型类型参数,它可以正常工作,但不适用于开放泛型类型:
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);
}
}
}
我不确定你想做什么。因为如果我正确理解您的场景,最好的事情就是为 Foo 泛型类型的每个基础类型公开一个架构定义,那么代码将类似于:
public class FooSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsGenericType && context.Type.GetGenericTypeDefinition() == typeof(Foo<>))
{
var argumentType = context.Type.GetGenericArguments().First();
var argumentSchema = context.SchemaGenerator.GenerateSchema(argumentType, context.SchemaRepository);
var baseSchemaName = $"{argumentType.Name}Foo";
var baseSchema = new OpenApiSchema()
{
Required = new SortedSet<string>() { "type" },
Type = "object",
Properties = new Dictionary<string, OpenApiSchema> {
{ "type", argumentSchema }
};
context.SchemaRepository.AddDefinition(baseSchemaName, baseSchema);
schema.Type = "string";
schema.Reference = new OpenApiReference { Id = $"{baseSchemaName}", Type = ReferenceType.Schema };
}
}
}
如果您还需要其他属性,请将它们包含在基本架构中。
这将为每种类型创建一个新架构,但它应该反序列化为您的泛型类型。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)