如何解决如何在服务层处理不成功的请求?
假设我有以下使用服务层的rest api端点:
[HttpGet("id")]
public async Task<IActionResult> GetById(int id)
{
var entity = _someService.GetById(id);
return Ok(entity);
}
在服务方法中,结果表明用户没有访问该实体的特权:
public Entity GetById(int id)
{
var entity = _repository.Get(id)
if(entity.OwnerId != CurrentUserId) // true
{
...
}
}
或者它根本不存在:
public Entity GetById(int id)
{
var entity = _repository.Get(id)
if(entity is null) // true
{
...
}
}
处理此类情况并通过在响应上设置合适的状态代码让用户知道出了什么问题的最佳方法是什么?
我能想到的是定义结果类,其中也包含如下请求结果:
public class RequestResult<T>
{
public T Result {get; set;}
public int StatusCode {get; set;} // 200,404,403 ...
}
或(我个人更喜欢)或定义并抛出ForbiddenException或NotFoundException并通过设置适当的响应状态代码在ExceptionHandlingMiddleware中处理它们。
解决方法
处理此类情况并返回403或404的最佳方法是什么?
每个hTTO定义404-未找到。
403被禁止-就一般的安全性和读取操作而言,这没有任何意义。基本上:如果您不被允许阅读它,通常也不允许您知道它的存在与否。这些天这是标准的-我不告诉您密码错误,我告诉您用户名或密码错误。我从不提供与安全相关的信息。
因此,如果允许读取但禁止更新(或删除),则隔离403以更新操作。出于安全问题,不允许读取变成404(找不到)。
,您的服务层不是定义HTTP响应的正确位置;这是您的控制器的责任。
ControllerBase
定义了多种生成各种HTTP响应的方法,在您的示例中包括Ok
,该方法返回200。
还有Forbid
和NotFound
,它们应该满足您的要求。
例如,如果找不到该实体,请让您的服务返回null:
[HttpGet("id")]
public async Task<IActionResult> GetById(int id)
{
var entity = _someService.GetById(id);
if (entity == null) return NotFound();
return Ok(entity);
}
如果服务确定用户没有访问权限,则可能适合使用异常:
public Entity GetById(int id)
{
var entity = _repository.Get(id)
if (entity.OwnerId != CurrentUserId) // true
{
throw new UnauthorizedAccessException();
}
}
然后在您的控制器中:
[HttpGet("id")]
public async Task<IActionResult> GetById(int id)
{
Entity entity;
try
{
entity = _someService.GetById(id);
}
catch (UnauthorizedAccessException)
{
return Forbid();
}
if (entity == null) return NotFound();
return Ok(entity);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。