Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 如何在ProducesResponseType Swagger上返回泛型类型?_Generics_Asp.net Core_Swagger_Swagger Ui_Swashbuckle - Fatal编程技术网

Generics 如何在ProducesResponseType Swagger上返回泛型类型?

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

在下面的代码中,您将在productsResponseType上看到一个T类型(通用),但我无法使它工作,因为它不是特定类型:

 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你们有这个的样品吗?