首页 > 解决方案 > HTTP 状态码 - 401/NotAuthorized vs 404/NotFound vs 400/BadRequest

问题描述

我有属于公司实体的小部件实体。公司和小部件之间存在一对多的关系。

这是我第一次使用 Get 方法:

[Route("MyApi/Companies/{companyId}/WidgetAdministration/[controller]")]
[HttpGet("{widgetId}")]
public async Task<ActionResult<WidgetDTO>> GetWidget([FromRoute] int companyId, [FromRoute]int widgetId)
{
    WidgetDTO widgetDto = await _myContext.Widgets
        .Where(w => w.CompanyId == companyId && w.WidgetId == widgetId)
        .AsNoTracking()
        .ProjectTo<WidgetDTO>(_mapper.ConfigurationProvider)
        .FirstOrDefaultAsync();

    if (widgetDto == null)
    {
        return NotFound();
    }
    else
    {
        return Ok(widgetDto);
    }
}

如果与“公司 1”关联的用户请求“公司 1 Widget 55”,但“Widget 55”属于“公司 2”,我应该返回什么?

404/NotFound - 由于“Widget 55”属于“Company 2”,即使“Widget 55”确实存在,上述 LINQ 语句也找不到任何内容。

401/NotAuthorized - 由于“Widget 55”不属于“Company 1”,“Company 1”无权查看它。

400/BadRequest - 这只是一个错误的请求,因为 Widget 和 Company 不匹配。

顺便说一句,任何人都可以推荐一个好的资源来帮助我解决其他类似的情况吗?

标签: c#getapi-designhttp-status-codes

解决方案


我会返回 404 有两个原因:

  1. 在我看来, 404 不是指Widget/55,而是指整个资源 URI: Company/1/Widget/55。该资源不存在。
  2. 403 阻止公司 1 查看公司 2 的小部件,但它确实暴露了存在的事实Widget/55。这可能会或可能不会被您接受。根据万维网联盟 (W3C) 的说法,“如果服务器不希望向客户端提供此信息,则可以使用状态代码 404(未找到)来代替。”

推荐阅读