为了账号安全,请及时绑定邮箱和手机立即绑定

Net Core API:ProducesResponseType 的用途

Net Core API:ProducesResponseType 的用途

C#
慕村225694 2023-09-24 15:56:08
我想了解的目的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 类
查看完整描述

4 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

虽然正确答案已经提交,但我想提供一个例子。假设您已将 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!");

    }

}

将产生如下所示的 swagger UI 卡/部分(运行项目并导航到 /api/docs/index.html):

https://img1.sycdn.imooc.com/650febd1000179d814300421.jpg

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


现在,将端点更新为:


[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!");

    }

}

这根本不会改变端点的行为,但现在 swagger 页面如下所示:

https://img1.sycdn.imooc.com/650febe10001e2e214330863.jpg

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

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

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


查看完整回答
反对 回复 2023-09-24
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

我认为它对于不成功(200)返回代码可以派上用场。假设如果其中一个失败状态代码返回描述问题的模型,您可以指定该情况下的状态代码生成与成功情况不同的内容。

查看完整回答
反对 回复 2023-09-24
?
冉冉说

TA贡献1877条经验 获得超1个赞

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



查看完整回答
反对 回复 2023-09-24
?
湖上湖

TA贡献2003条经验 获得超2个赞

3种不同的使用选择

在所有应用程序控制器中:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

{

        app.UseSwaggerResponseCheck();

  //...

}

使用 ValidateStatusCodes 属性的每个控制器操作:

[ApiController]

[Route("[controller]")]

public class ExampleController : ControllerBase

{

    [HttpGet]

    [ValidateStatusCodes] // <-- Use this

    [SwaggerOperation("LoginUser")]

    [SwaggerResponse(statusCode: StatusCodes.Status200OK, type: null, description: "signed user email account")]

    [SwaggerResponse(statusCode: StatusCodes.Status400BadRequest, type: null, description: "wrong email or password")]

    [Route("/users/login")]

    public virtual IActionResult LoginUser([FromQuery][Required()] string email, [FromQuery] string password)

    {

            if (email == "email@gmail.com")

              return Ok("success");

            else if (email == "")

              return BadRequest("email required");

            else

              return NotFound("user not found"); // 500 - InternalServerError because not attributed with SwaggerResponse.

    }

    // ...

    [HttpGet]

    [ValidateStatusCodes] // <-- Use this

    [ProducesResponseType(type: typeof(Account), StatusCodes.Status200OK)]

    [ProducesResponseType(StatusCodes.Status400BadRequest)]

    [Route("/users/login2")]

    public virtual IActionResult LoginUser2([FromQuery][Required()] string email, [FromQuery] string password)

    {

            if (email == "email@gmail.com")

              return Ok("success").Validate();

            else if (email == "")

              return BadRequest("email required").Validate();

            else

              return NotFound("user not found").Validate(); // Throws error in DEBUG or Development.

    }

}

使用 IStatusCodeActionResult.Validate() 的每个结果:

[ApiController]

[Route("[controller]")]

public class ExampleController : ControllerBase

{

    [HttpGet]

    [SwaggerOperation("LoginUser")]

    [SwaggerResponse(statusCode: StatusCodes.Status200OK, type: null, description: "signed user email account")]

    [SwaggerResponse(statusCode: StatusCodes.Status400BadRequest, type: null, description: "wrong email or password")]

    [Route("/users/login")]

    public virtual IActionResult LoginUser([FromQuery][Required()] string email, [FromQuery] string password)

    {

            if (email == "email@gmail.com")

              return Ok("success").Validate();

            else if (email == "")

              return BadRequest("email required").Validate();

            else if (email == "secret")

              return Unauthorized("hello");

                 // Passed, independent of SwaggerResponse attribute.

            else

              return NotFound("user not found").Validate();

                 // 500 - InternalServerError because not attributed with SwaggerResponse.

    }

    // ...

    [HttpGet]

    [ProducesResponseType(type: typeof(Account), StatusCodes.Status200OK)]

    [ProducesResponseType(StatusCodes.Status400BadRequest)]

    [Route("/users/login2")]

    public virtual IActionResult LoginUser2([FromQuery][Required()] string email, [FromQuery] string password)

    {

            if (email == "email@gmail.com")

              return Ok("success").Validate();

            else if (email == "")

              return BadRequest("email required").Validate();

            else

              return NotFound("user not found").Validate(); // Throws error in DEBUG or Development.

    }

}


查看完整回答
反对 回复 2023-09-24
  • 4 回答
  • 0 关注
  • 432 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信