Generics 如何在ProducesResponseType Swagger上返回泛型类型?
在下面的代码中,您将在productsResponseType上看到一个T类型(通用),但我无法使它工作,因为它不是特定类型:Generics 如何在ProducesResponseType Swagger上返回泛型类型?,generics,asp.net-core,swagger,swagger-ui,swashbuckle,Generics,Asp.net Core,Swagger,Swagger Ui,Swashbuckle,在下面的代码中,您将在productsResponseType上看到一个T类型(通用),但我无法使它工作,因为它不是特定类型: public class ApiController<T> : ApiBaseController where T : class, IDocument { protected IDataService<T> data = null; [HttpGet("{id}")] **[ProducesRespons
public class ApiController<T> : ApiBaseController where T : class, IDocument
{
protected IDataService<T> data = null;
[HttpGet("{id}")]
**[ProducesResponseType(typeof(T), 201)]**
[ProducesResponseType(typeof(void), 500)]
public async Task<IActionResult> Get(string id)
{
var result = await data.Get(id);
return Ok(result);
}
}
公共类ApicController:ApiBaseController,其中T:class,i文档
{
受保护的IDataService数据=null;
[HttpGet(“{id}”)]
**[产品响应类型(类型(T),201)]**
[产品响应类型(类型(无效),500)]
公共异步任务获取(字符串id)
{
var result=wait data.Get(id);
返回Ok(结果);
}
}
有什么建议吗?仔细观察后,使用操作过滤器似乎是可行的(而且更容易) 类似的东西应该可以工作(未经测试,只是确保没有编译错误)
使用系统;
使用System.Collections.Generic;
使用System.Linq;
运用系统反思;
使用系统文本;
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Mvc.Controllers;
使用swashback.AspNetCore.Swagger;
使用swashback.AspNetCore.SwaggerGen;
命名空间MyCompany.Common.Web.Swagger.OperationFilters
{
公共类GenericOperationFilter:IOperationFilter
{
公共无效应用(操作,操作筛选器上下文)
{
if(context.apiscription.ActionDescriptor是ControllerActionDescriptor controllerDescriptor)
{
var baseType=controllerDescriptor.ControllerTypeInfo.baseType?.GetTypeInfo();
//获取类型并查看它是否是具有单个类型参数的泛型控制器
if(baseType==null | |(!baseType.IsGenericType&&baseType.GenericTypeParameters.Length==1))
返回;
if(context.apiscription.HttpMethod==“GET”&&!operation.Responses.ContainsKey(“200”))
{
var typeParam=baseType.GenericTypeParameters[0];
//获取泛型类型的架构。如果不存在,则必须为该模型创建架构
//您自己,因为Swagger可能没有添加它,因为该类型没有在任何模型上声明
字符串typeParamFriendlyId=typeParam.FriendlyId();
if(!context.SchemaRegistry.Definitions.TryGetValue(typeParamFriendlyId,out Schema typeParamSchema))
{
//架构不存在,您需要自己创建它,即为模型的每个属性添加属性。
//请参阅OpenAPI/Swagger规范
typeParamSchema=context.SchemaRegistry.GetOrRegister(typeParam);
//在此处添加属性,否则将不会有此类型的模型描述
}
//对于文档中尚未存在200响应的任何get操作
操作.响应.添加(“200”,新响应
{
Description=“成功”,
Schema=newschema{Ref=typeParamFriendlyId}
});
}
}
}
}
}
它是干什么的<代码>IOperationFilter为每个操作(Get、Post、Put等)调用。在它里面,检查它是否是ControllerActionDescriptor
,如果是,检查控制器类型
如果愿意,您可以将其缩小为一种特定类型。我刚刚使用了从另一个类继承的每个控制器,它的基类型是泛型的,只有一个泛型参数
最后,它检查是否是“Get”操作(post、put、delete通常不返回模型,只返回状态代码/错误响应),然后检查类型是否已经在Swagger/OpenAPI模式定义中。如果模型存在,请阅读它的模式并在响应中引用它
如果模型没有在模式注册表中注册,它会变得更复杂。您需要使用反射并构建模式文件,将其添加到存储库(在context.SchemaRegistry.GetOrRegister(typeParam)
call期间已经发生),然后像上面那样引用它
当模型没有在任何其他控制器中用作响应或动作参数时,就会发生这种情况
您可以获得有关OpenAPI 2.0规范的更多信息。您不能通过属性。但是,您可以编写自己的
ISchemaFilter
或IDocumentFilter
,在将打开的api文档序列化为之前对其进行修改json@Tseng你们有这个的样品吗?