从API的业务层返回状态代码



我正在制作API框架,在API中,我们将StatusCode和结果一起发送,假设我在数据层中有这个类

public class User
{
public string UserId { get; set; }
public string UserName { get; set; }
}

现在我在业务层中的逻辑如下

public class UserManager : IUser
{
public async Task<User> GetById(string UserId)
{
try
{
//Logic here
List<User> users = Data.GetById(UserId);

If(!users.Any())
throw new Exception("User is not found"); // Status Code 404
Else
Return users.First(); // Status Code 200
}
catch (Exception ex)
{
throw new Exception("Internal Server Error"); // Status Code 500
}
}
}

现在我的问题是,在表示层中,我不知道应该返回的状态代码,因为业务层没有通知他们。另一种方法是,我可以创建这样的类:

public class ApiResponse
{
public HttpStatusCode StatusCode { get; set; }
public object Body { get; set; }

public ApiResponse(HttpStatusCode StatusCode) {
this.StatusCode = StatusCode;
this.Body = null;
}

public ApiResponse(HttpStatusCode StatusCode, object Body) {
this.StatusCode = StatusCode;
this.Body = Body;
}
}

并将我的业务层更改为这个

public class UserManager : IUser
{
public async Task<ApiResponse> GetById(string UserId)
{
try
{
//Logic here
List<User> users = Data.GetById(UserId);

If(!users.Any())
return new ApiResponse(HttpStatusCode.NotFound);
Else
return new ApiResponse(HttpStatusCode.OK, users.First());
}
catch (Exception ex)
{
return new ApiResponse(HttpStatusCode.InternalServerError);
}
}
}

但我不喜欢这种方法,因为有一些顾虑

  • 现在我的所有业务层都需要返回ApiResponse,其他什么都不需要
  • 如果我需要在表示层中处理返回数据(例如:我需要其他东西的UserId(,我需要将对象硬转换为正确的类型,在这种情况下;(用户(数据;这可能会导致未来的混乱

是否有更好的方法将StatusCode返回到表示层?

您应该从业务层抛出更具体的异常,并在ExceptionFilter中捕获它们,将它们转换为任何相关的HttpCode。那么API层就不会充斥着try/catch/exception处理和返回值检查。

public class UserManager : IUser
{
public async Task<User> GetById(string UserId)
{
//Logic here
List<User> users = Data.GetById(UserId);

If(!users.Any())
throw new UserNotFoundException("User is not found"); // Status Code 404
Else
Return users.First(); // Status Code 200
}
}
public class ApiExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(ExceptionContext ec)
{
switch(ec.Exception)
{
case UserNotFoundException enfe:
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
context.Handled = true;
break;
default:
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
break;
}
}
}

我认为您的业务层不应该返回HTTP状态代码
它不需要"意识到"HTTP的存在
它只"知道"用户,并返回或抛出错误。

您是否将UserManager用作API控制器中的用户存储库?

然后在控制器中解释UserManager的返回值,在那里您可以用DTO&htttp状态代码-如果你需要这样做。

最新更新