Net Core API:ProducesResponseType 的用途

Posted

技术标签:

【中文标题】Net Core API:ProducesResponseType 的用途【英文标题】:Net Core API: Purpose of ProducesResponseType 【发布时间】:2019-12-31 21:05:54 【问题描述】:

我想了解ProducesResponseType.的目的

微软定义为a filter that specifies the type of the value and status code returned by the action.

所以我很好奇如果发生什么后果

一个人没有放置ProductResponseType? 系统如何处于劣势,或者是否有负面后果? Microsoft API 不是已经自动知道返回的状态代码的类型/值吗?
[ProducesResponseType(typeof(DepartmentDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]

来自 Microsoft 的文档:ProducesResponseTypeAttribute Class

【问题讨论】:

据我所知,这纯粹是文档。如果您使用 NSwag 或 Swashbuckle 之类的工具,它将根据此属性显示对端点的可能响应。我不知道它在生成 API 文档之外有什么影响。 @ChrisPratt 随意发布作为答案,我可以发送积分,谢谢! 我不确定这是 的答案。别人可能知道一些我不知道的事情。在任何不涉及 API 文档的讨论中,我从未见过该属性。这并不意味着它实际上没有其他用途。 【参考方案1】:

虽然正确答案已经提交,但我想提供一个例子。假设您已将 Swashbuckle.AspNetCore 包添加到您的项目中,并已在 Startup.Configure(...) 中使用它,如下所示:

app.UseSwagger();
app.UseSwaggerUI(options =>

    options.SwaggerEndpoint("/swagger/v1/swagger.json", "My Web Service API V1");
    options.RoutePrefix = "api/docs";  

);

有一个像这样的测试控制器动作端点:

[HttpGet]        
public ActionResult GetAllItems()

    if ((new Random()).Next() % 2 == 0)
    
        return Ok(new string[]  "value1", "value2" );
    
    else
    
        return Problem(detail: "No Items Found, Don't Try Again!");
    

将产生一个像这样的招摇 UI 卡/部分(运行项目并导航到 /api/docs/index.html):

如您所见,没有为端点提供“元数据”。

现在,将端点更新为:

[HttpGet]
[ProducesResponseType(typeof(IEnumerable<string>), 200)]
[ProducesResponseType(404)]
public ActionResult GetAllItems()

    if ((new Random()).Next() % 2 == 0)
    
        return Ok(new string[]  "value1", "value2" );
    
    else
    
        return Problem(detail: "No Items Found, Don't Try Again!");
    

这根本不会改变端点的行为,但现在招摇页面看起来像这样:

这样更好,因为现在客户端可以看到可能的响应状态代码是什么,并且对于每个响应状态,返回数据的类型/结构是什么。 请注意,虽然我没有为 404 定义返回类型,但是 ASP.NET Core(我使用的是 .NET 5)足够聪明,可以将返回类型设置为 ProblemDetails。

如果这是您要采用的路径,最好将Web API Analyzer 添加到您的项目中,以接收一些有用的警告。

附言我还想在 app.UseSwaggerUI(...) 配置中使用 options.DisplayOperationId(); 。通过这样做,swagger UI 将显示映射到每个端点的实际 .NET 方法的名称。例如,上述端点是对 /api/sample 的 GET,但实际的 .NET 方法称为 GetAllItems()

【讨论】:

对于返回普通类型而不是 ActionResult 的控制器,是否可以/应该有办法让 Swagger 自动推断 C# 返回类型用于成功/200,因此不必添加这些每个控制器方法都有多余的[ProducesResponseType(typeof(...), 200)] 属性? @PatrickSzalapski 我相信您可以使用编译时代码注入器,例如github.com/Fody/Fody,以避免使用重复属性使代码臃肿。我几乎可以肯定有一些 Roslyn 编译服务/代码生成功能,能够实现类似的东西,例如将控制器类和操作方法标记为“部分”,然后为它生成一个带有部分方法声明的部分类,该部分方法声明装饰有所有必需的属性。 (我自己没有这样做,只是大声思考!大声笑)【参考方案2】:

我认为它对于非成功(200)返回码会派上用场。 假设如果其中一个失败状态代码返回一个描述问题的模型,您可以指定在这种情况下的状态代码产生与成功案例不同的东西。 您可以阅读更多相关信息并在此处找到示例:https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.2

【讨论】:

引用该链接页面“此属性为 Swagger 等工具生成的 Web API 帮助页面生成更多描述性响应详细信息。”所以我猜它是出于文档目的(并且可能用于静态代码分析)。 看起来更笨拙。如果样板 XML cmets 没有将您的代码弄乱到您喜欢的程度,那么现在就是这个。男孩,不过,它在文本编辑器中看起来确实很聪明!【参考方案3】:

它用于为 API 探索/可视化工具(如 Swagger (https://swagger.io/))生成开放 API 元数据,以在文档中指明控制器可能返回的内容。

【讨论】:

以上是关于Net Core API:ProducesResponseType 的用途的主要内容,如果未能解决你的问题,请参考以下文章

[Asp.Net Core]ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了

将 OpenID Connect 与 .NET Core 3.0 ASP.NET Core API 服务一起使用时出错

《ASP.NET Core 6框架揭秘》实例演示[27]:ASP.NET Core 6 Minimal API的模拟实现

如何将 .NET Core 2.2 Web API 迁移到 .NET Core 3.0?

将 .Net Core Identity 和 OIDC 与多个 .Net Core Web API 结合使用

.Net Core003第一个API