如何在 ServiceStack 中 return 不同的 Http 状态码

How to return different Http Status Code in ServiceStack

您好,我是 Service Stack 的新手,想知道如何 return 不同的 http 状态代码。

我需要return的是:

  1. 204 - 已处理但没有内容
  2. 400 - 错误请求
  3. 404 - 未找到
  4. 422 - 验证问题
  5. 500 - 内部服务器错误

有人可以帮忙吗?

如果您的服务没有 return 响应,例如有一个 void 方法或 returns null,ServiceStack 自动 returns 一个 204 No Content 响应状态。

此行为可以恢复为空的 200 OK 响应:

SetConfig(new HostConfig {
    Return204NoContentForEmptyResponse = false
});

Request DTOs returning empty responses should implement the IReturnVoid marker interface

自定义错误代码

所有其他状态代码都是错误状态代码,记录在 ServiceStack 的 Error Handling docs 中。

例如通常建议 return 理想的 C# Exception 并让 ServiceStack 自动 return 理想的 HTTP 错误代码。

默认情况下 C# 异常继承自:

  • ArgumentExceptionSerializationExceptionFormatException returns a 400 BadRequest
  • NotImplementedExceptionNotSupportedException returns a 405 MethodNotAllowed
  • FileNotFoundException 是 return 作为 404 NotFound
  • AuthenticationException 被 return 编辑为 401 未经授权
  • UnauthorizedAccessException 被 return 编辑为 403 禁止
  • OptimisticConcurrencyException 被 return 编辑为 409 冲突
  • 所有其他正常的 C# 异常被 return 编辑为 500 InternalServerError

所以任何继承 ArgumentException 的异常,其中包括大部分 Fluent Validation Exceptions 将自动 return 首选 400 BadRequest.

自定义 HTTP 错误状态的其他方法包括:

C# 异常到 HTTP 错误状态的自定义映射

您可以为不同的异常类型更改 returned 的 HTTP 错误状态,方法是:

SetConfig(new HostConfig { 
    MapExceptionToStatusCode = {
        { typeof(CustomUnprocessableEntityException), 422 },
        { typeof(CustomerNotFoundException), 404 },
    }
});

实施 IHasStatusCode

除了自定义 C# 异常的 HTTP 响应主体之外 IResponseStatusConvertible, 您还可以通过实现 IHasStatusCode:

来自定义 HTTP 状态代码
public class Custom401Exception : Exception, IHasStatusCode
{
    public int StatusCode => 401;
}

返回一个 HttpError

如果你想更细粒度地控制你的 HTTP 错误,你可以 throwreturn an HttpError 让你自定义 Http HeadersStatus Code 和 HTTP Response body 在线获得您想要的内容:

public object Get(User request) 
{
    throw HttpError.NotFound($"User {request.Name} does not exist");
}

上面的 return 是 404 NotFound StatusCode,是以下内容的简写形式:

new HttpError(HttpStatusCode.NotFound, $"User {request.Name} does not exist");

带有自定义响应 DTO 的 HttpError

HttpError 也可用于 return 更结构化的错误响应:

var responseDto = new ErrorResponse { 
    ResponseStatus = new ResponseStatus {
        ErrorCode = typeof(ArgumentException).Name,
        Message = "Invalid Request",
        Errors = new List<ResponseError> {
            new ResponseError {
                ErrorCode = "NotEmpty",
                FieldName = "Company",
                Message = "'Company' should not be empty."
            }
        }
    }
};

throw new HttpError(HttpStatusCode.BadRequest, "ArgumentException") {
    Response = responseDto,
};