c# - 如何在 ServiceStack 中返回不同的 Http Status Code

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

我需要能够返回的是:

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

有人可以帮忙吗?

最佳答案

如果您的服务没有返回响应,例如有一个void方法或返回null,ServiceStack自动返回一个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 中.

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

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

  • ArgumentExceptionSerializationExceptionFormatException 返回 400 BadRequest
  • NotImplementedExceptionNotSupportedException 返回一个 405 MethodNotAllowed
  • FileNotFoundException 返回为 404 NotFound
  • AuthenticationException 返回为 401 Unauthorized
  • UnauthorizedAccessException 返回为 403 Forbidden
  • OptimisticConcurrencyException 返回为 409 Conflict
  • 所有其他正常的 C# 异常返回为 500 InternalServerError

因此任何继承 ArgumentException 的异常都包含 Fluent Validation Exceptions 的大部分将自动返回首选的 400 BadRequest

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

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

您可以更改为不同的异常类型返回的 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 错误,您可以抛出返回 一个HttpError,让您自定义 Http HeadersStatus Code 以及 HTTP Response body 以准确获取您想要的信息:

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

上面的代码返回了一个 404 NotFound StatusCode 并且是以下内容的简写:

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

带有自定义响应 DTO 的 HttpError

HttpError 也可用于返回一个更结构化的错误响应:

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,
}; 

https://stackoverflow.com/questions/59870825/

相关文章:

php - 如何在php中将一个元素添加到子数组中

arduino - ESP32 - 软件序列库

c# - 如何将包含错误的土耳其语字符的字符串转换为显示正确的字符?

ruby-on-rails - 如何在转换后的字符串不充满反斜杠的情况下将哈希转换为 JSON

firebase - 从 Admin SDK 调用 Firebase Callable Cloud

c - 我如何在进行分区作业时转换?

sql - Oracle 12c - 插入到选择查询中的列不明确,ORA-00918

python - 如何使自定义状态discord.py

r - 渲染为 PDF 时 Markdown 中的 kableExtra 错误?

node.js - 使用具有 root 访问权限的 nodejs 执行 shell 命令