C# HTTP状态代码-401/NotAuthorized vs 404/NotFound vs 400/BadRequest

C# HTTP状态代码-401/NotAuthorized vs 404/NotFound vs 400/BadRequest,c#,get,api-design,http-status-codes,C#,Get,Api Design,Http Status Codes,我有属于公司实体的小部件实体。公司和widget之间存在一对多的关系 下面是我第一次使用Get方法: [Route("MyApi/Companies/{companyId}/WidgetAdministration/[controller]")] [HttpGet("{widgetId}")] public async Task<ActionResult<WidgetDTO>> GetWidget([FromRoute] int companyId, [FromRoute

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

下面是我第一次使用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);
    }
}
[路由(“MyApi/companys/{companyId}/WidgetAdministration/[controller]”]
[HttpGet(“{widgetId}”)]
公共异步任务GetWidget([FromRoute]int companyId,[FromRoute]int widgetId)
{
WidgetDTO WidgetDTO=await\u myContext.Widgets
.Where(w=>w.CompanyId==CompanyId&&w.WidgetId==WidgetId)
.AsNoTracking()
.ProjectTo(_mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
if(widgetDto==null)
{
返回NotFound();
}
其他的
{
返回Ok(widgetDto);
}
}
如果与“公司1”关联的用户请求“公司1小部件55”,但“小部件55”属于“公司2”,我应该返回什么

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

401/NotAuthorized-由于“小部件55”不属于“公司1”,因此“公司1”无权查看它

400/BadRequest-这只是一个错误的请求,因为小部件和公司不匹配


另外,有人能推荐一个好的资源来帮助我处理其他类似的场景吗

我会返回404,原因有两个:

  • 在我看来,404不是指
    Widget/55
    ,而是指整个资源URI:
    Company/1/Widget/55
    。此资源不存在
  • 403阻止公司1查看公司2的小部件,但它确实暴露了
    Widget/55
    存在的事实。您可能会接受,也可能不会接受,如果服务器不想让客户端使用这些信息,可以使用状态代码404(未找到)

  • 我会返回404,原因有两个:

  • 在我看来,404不是指
    Widget/55
    ,而是指整个资源URI:
    Company/1/Widget/55
    。此资源不存在
  • 403阻止公司1查看公司2的小部件,但它确实暴露了
    Widget/55
    存在的事实。您可能会接受,也可能不会接受,如果服务器不想让客户端使用这些信息,可以使用状态代码404(未找到)

  • 为了安全起见,我想我会让每家公司使用不同的URL。仅当授权失败时,才应返回let URL权限来处理错误。401,这里不是这种情况。所以这显然不是办法。另外两个通常比较难决定:404表示资源不存在,400表示输入格式错误或无效。404似乎是最合理和最具体的一个。另请参见其中的说明,400表示“服务器无法或不会处理请求”,因为例如“请求语法错误、请求消息帧无效或请求路由错误”。404表示“服务器未找到当前表示[…]或者不愿意透露其存在”。从技术上讲,您确实处理了请求,因为您没有发现任何问题,这导致找不到资源的表示形式。@jdweng这主意不错,但对于这些用例,这可能有点过头了。@ckuri感谢您的输入,我认为401/NotAuthorized是因为公司1不应该被授权查看公司2的小部件。由于srk的回答,我认为我们将使用404。出于安全目的,我认为我会让每家公司使用不同的URL。仅当授权失败时,才应返回let URL权限来处理错误。401,这里不是这种情况。所以这显然不是办法。另外两个通常比较难决定:404表示资源不存在,400表示输入格式错误或无效。404似乎是最合理和最具体的一个。另请参见其中的说明,400表示“服务器无法或不会处理请求”,因为例如“请求语法错误、请求消息帧无效或请求路由错误”。404表示“服务器未找到当前表示[…]或者不愿意透露其存在”。从技术上讲,您确实处理了请求,因为您没有发现任何问题,这导致找不到资源的表示形式。@jdweng这主意不错,但对于这些用例,这可能有点过头了。@ckuri感谢您的输入,我认为401/NotAuthorized是因为公司1不应该被授权查看公司2的小部件。由于srk的回答,我认为我们选择404。谢谢,第1点是非常好的一点。另外,使用404而不是403确实增加了一点安全性,但这对于我们的用例来说有点过分了。。。但是它使前端开发人员的工作变得更容易。谢谢,第1点是一个很好的观点。另外,使用404而不是403确实增加了一点安全性,但这对于我们的用例来说有点过分了。。。但它使前端开发人员的工作变得更轻松。