虚张声势覆盖响应类型

RVa*_*een 7 swashbuckle asp.net-core swashbuckle.aspnetcore

我的控制器中有一个通用Result<T>响应类型,例如

public Result<T> GetSomething()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

我还有一个自定义的 asp.net core 过滤器,它返回 Json 表示形式T

为了让 swashbuckle 生成正确的文档,我必须用以下内容装饰每个方法:

[Produces(typeof(T))]
Run Code Online (Sandbox Code Playgroud)

由于这很麻烦、容易忘记并且容易出错,所以我一直在寻找一种自动化的方法。

现在在 Swashbuckle 中你有一个,但我无法在这些方法中MapType找到:T

services.AddSwaggerGen(c =>
{
    ...
    c.MapType(typeof(Result<>), () => /*can't get T here*/);
};
Run Code Online (Sandbox Code Playgroud)

我正在查看,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);

        }
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*len 8

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在此处所看到的,我正在循环遍历 中的所有项目operation.Responses["200"].Content,并使用您找到的方法一一替换它们的架构GenerateSchema。