Swashbuckle 覆盖响应类型
Swashbuckle override response type
我的控制器中有一个通用的 Result<T>
响应类型,例如
public Result<T> GetSomething()
{
...
}
我还有一个自定义 asp.net 核心过滤器 returns Json T
的表示
为了让 swashbuckle 生成正确的文档,我必须用以下方法修饰每个方法:
[Produces(typeof(T))]
由于这很麻烦、容易被遗忘并且容易出错,所以我一直在寻找一种自动化方法。
现在在 Swashbuckle 中你有一个 MapType
,但我无法通过这些方法获得 T
:
services.AddSwaggerGen(c =>
{
...
c.MapType(typeof(Result<>), () => /*can't get T here*/);
};
我正在查看 IOperationFilter
,但找不到覆盖其中结果类型的方法。
然后还有ISchemaFilter
public class ResultSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (!context.Type.IsGenericType || !context.Type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Result<>)))
{
return;
}
var returnType = context.Type.GetGenericArguments()[0];
//How do I override the schema here ?
var newSchema = context.SchemaGenerator.GenerateSchema(returnType, context.SchemaRepository);
}
}
IOperationFilter
是正确的选择。下面是更改 OData 端点响应类型的示例。
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
//EnableQueryAttribute refers to an OData endpoint.
if (context.ApiDescription.ActionDescriptor.EndpointMetadata.Any(em => em is EnableQueryAttribute))
{
//Fixing the swagger response for Controller style endpoints
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor cad)
{
//If the return type is IQueryable<T>, use ODataResponseValue<T> as the Swagger response type.
var returnType = cad.MethodInfo.ReturnType;
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IQueryable<>))
{
var actualType = returnType.GetGenericArguments()[0];
var responseType = typeof(ODataResponseValue<>).MakeGenericType(actualType);
var schema = context.SchemaGenerator.GenerateSchema(responseType, context.SchemaRepository);
foreach (var item in operation.Responses["200"].Content)
item.Value.Schema = schema;
}
}
}
}
正如您在此处看到的,我正在遍历 operation.Responses["200"].Content
中的所有项目,使用您找到的 GenerateSchema
方法逐一替换它们的架构。
我的控制器中有一个通用的 Result<T>
响应类型,例如
public Result<T> GetSomething()
{
...
}
我还有一个自定义 asp.net 核心过滤器 returns Json T
为了让 swashbuckle 生成正确的文档,我必须用以下方法修饰每个方法:
[Produces(typeof(T))]
由于这很麻烦、容易被遗忘并且容易出错,所以我一直在寻找一种自动化方法。
现在在 Swashbuckle 中你有一个 MapType
,但我无法通过这些方法获得 T
:
services.AddSwaggerGen(c =>
{
...
c.MapType(typeof(Result<>), () => /*can't get T here*/);
};
我正在查看 IOperationFilter
,但找不到覆盖其中结果类型的方法。
然后还有ISchemaFilter
public class ResultSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (!context.Type.IsGenericType || !context.Type.GetGenericTypeDefinition().IsAssignableFrom(typeof(Result<>)))
{
return;
}
var returnType = context.Type.GetGenericArguments()[0];
//How do I override the schema here ?
var newSchema = context.SchemaGenerator.GenerateSchema(returnType, context.SchemaRepository);
}
}
IOperationFilter
是正确的选择。下面是更改 OData 端点响应类型的示例。
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
//EnableQueryAttribute refers to an OData endpoint.
if (context.ApiDescription.ActionDescriptor.EndpointMetadata.Any(em => em is EnableQueryAttribute))
{
//Fixing the swagger response for Controller style endpoints
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor cad)
{
//If the return type is IQueryable<T>, use ODataResponseValue<T> as the Swagger response type.
var returnType = cad.MethodInfo.ReturnType;
if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(IQueryable<>))
{
var actualType = returnType.GetGenericArguments()[0];
var responseType = typeof(ODataResponseValue<>).MakeGenericType(actualType);
var schema = context.SchemaGenerator.GenerateSchema(responseType, context.SchemaRepository);
foreach (var item in operation.Responses["200"].Content)
item.Value.Schema = schema;
}
}
}
}
正如您在此处看到的,我正在遍历 operation.Responses["200"].Content
中的所有项目,使用您找到的 GenerateSchema
方法逐一替换它们的架构。