【问题标题】:Null response returns a 204空响应返回 204
【发布时间】:2020-04-02 15:06:27
【问题描述】:

当我执行 GET 请求但我没有找到任何数据时,我的控制器返回 204。

[Route("user/v1/[controller]")]
public class UserLoginController : Controller
{
    [HttpGet]
    public async Task<UserLogin> Get(int userId)
    {
        var userLoginLogic = new UserLoginLogic();

        return await userLoginLogic.GetUserLogin(userId);
    }
}

这仅适用于 GET 请求,POST、PUT、DELETE 返回 200 空响应。这与我为 200 响应定义的响应定义的招摇定义混淆了,我宁愿保持一致。

如果我从这个控制器中提供 HTML,那么 204 会很好,但它是用于 REST API。

如何让它返回 200?

【问题讨论】:

  • 您运行的是 v2.0 还是 v2.1?
  • 我正在运行 2.1
  • “HTTP 204 NO CONTENT:服务器已成功完成请求,并且响应负载正文中没有其他内容要发送”。对于不返回数据的 GET 返回 204 是完全有意义的。对于 Web 应用程序 (MVC) 返回 204 是没有意义的。
  • 如果协议是 HTTP 并且 GET 不返回内容,那么 204 实际上是正确的成功代码 - 2xx 范围内的任何内容都是成功的。您可能会收到 204,因为实际上您并没有返回内容。
  • 您是说您希望它在找不到用户时返回 200 吗? 404 不是更有意义吗?

标签: c# asp.net-core asp.net-core-2.1


【解决方案1】:

使用 v2.1+ 中的新 ActionResult&lt;T&gt;,您还可以重构以专门告诉控制器使用 Ok() 辅助方法返回 Ok 200

[Route("user/v1/[controller]")]
public class UserLoginController : Controller {
    [HttpGet]
    public async Task<ActionResult<UserLogin>> Get(int userId) {
        var userLoginLogic = new UserLoginLogic();
        var model = await userLoginLogic.GetUserLogin(userId);
        return Ok(model);
    }
}

但是,如果实际上没有要返回的内容,这可能会产生误导。考虑使用适当的响应状态

[Route("user/v1/[controller]")]
public class UserLoginController : Controller {
    [HttpGet]
    public async Task<ActionResult<UserLogin>> Get(int userId) {
        var userLoginLogic = new UserLoginLogic();
        var model = await userLoginLogic.GetUserLogin(userId);
        if(model == null) return NotFound(); //404
        return Ok(model); //200
    }
}

如果打算返回没有内容的 200 Ok,请使用 ControllerBase.Ok() 方法

创建一个 OkResult 对象,该对象产生一个空的 Status200OK 响应。

[Route("user/v1/[controller]")]
public class UserLoginController : Controller {
    [HttpGet]
    public async Task<ActionResult<UserLogin>> Get(int userId) {
        var userLoginLogic = new UserLoginLogic();
        var model = await userLoginLogic.GetUserLogin(userId);
        if(model == null) return Ok(); //200 with no content
        return Ok(model); //200
    }
}

参考Controller action return types in ASP.NET Core Web API:

【讨论】:

  • 这就是我询问使用v2.1的原因,它也有可爱的新ActionResult&lt;T&gt;
  • 使用返回类型 Task> 当模型为 null 时返回 204。 public async Task Get(int userId) return Ok(await userLoginLogic.GetUserLogin(userId));这也仍然返回 204
  • Ok(null) 生成 204。相反,如果您坚持使用 200 而不是此答案建议的 404,则需要明确检查 null 并使用简单的 Ok() 代替:只是意味着在此答案的第二个示例中将NotFound() 切换为Ok()
  • 在我认为 404 不合适的问题中添加了 cmets。
  • @Nkosi 如果您添加一个空模型导致 200 返回的示例,那么我可以将问题标记为已回答
【解决方案2】:

见:


services.AddControllers(opt =>  // or AddMvc()
{
    // remove formatter that turns nulls into 204 - No Content responses
    // this formatter breaks Angular's Http response JSON parsing
    opt.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
})

【讨论】:

    猜你喜欢
    • 2022-01-03
    • 2016-09-04
    • 2012-03-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 2022-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多