无响应返回204状态码。

16

当我进行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个空响应。这会影响我的Swagger定义,其中为200个响应定义了响应,我更希望保持一致。

如果我从控制器中提供HTML,则204就可以了,但它是为REST API服务的。

如何使其返回200?


4
HTTP 204 NO CONTENT:服务器已成功处理请求,响应负载体中没有额外的内容可发送。如果一个GET请求没有返回任何数据,那么返回204是非常合理的。但对于Web应用程序(MVC)来说,返回204则没有意义。 - Camilo Terevinto
2
如果协议是HTTP并且GET请求没有返回内容,则204实际上是正确的成功代码 - 任何2xx范围内的代码都表示成功。你可能会得到一个204,因为实际上你没有返回内容。 - RamblinRose
@CamiloTerevinto,你最后一句话与你的评论相矛盾。 - Cale
@Cale 不是很准确,Web应用程序永远不应该返回“无内容”(用户如何在没有内容的情况下导航到页面?)。除非你的意思是我没有明确说明“针对Web API中的GET请求”。 - Camilo Terevinto
1
你是说当它找不到用户时要返回200吗?使用404会更合理,不是吗? - Brad
显示剩余7条评论
2个回答

14

在v2.1+中,使用新的ActionResult<T>,你还可以重构代码并特别指定控制器使用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
    }
}

ASP.NET Core Web API中的控制器操作返回类型:参考


4
所以我问是否可以使用v2.1,因为它也有可爱的新ActionResult<T> - DavidG
使用返回类型Task<ActionResult<UserLogin>>,当模型为空时返回204。public async Task<IActionResult> Get(int userId) return Ok(await userLoginLogic.GetUserLogin(userId));这仍然返回204。 - Cale
3
如果你坚持使用200状态码而不是此答案建议的404状态码,那么当Ok(null)时会生成204状态码。为了解决这个问题,你需要显式地检查null并使用简单的Ok()代替NotFound(),也就是在此答案的第二个示例中将NotFound()替换为Ok() - Kirk Larkin
在问题中添加了评论,解释为什么我认为404不合适。 - Cale
@Nkosi 如果您添加一个示例,其中空模型导致返回200,则我可以将问题标记为已回答。 - Cale
@Cale,你可以直接使用return Ok();,它会返回状态码200,但没有内容。 - Nkosi

7

See:


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>();
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接