繁体   English   中英

HTTP 错误的自定义 json 响应正文

[英]Custom json response body for HTTP errors

我想知道 API 控制器中是否有一种方法可以将自定义对象作为响应体返回给诸如BadRequest()NotFound()

例如,对于404错误,我想返回如下内容:

{
  "StatusCode": 404,
  "Error": "Not Found",
  "Message": "Custom message..."
}

相反,我得到了这个:

{
  "Message": "Custom message..."
}

目前要返回复杂的响应主体,我正在使用Ok()这种方式:

return Ok(new
{
    Success = false,
    Message = "Custom message...",
    // other fields...
});

但很明显,我要返回一个意义不大的200状态。

有没有更好的方法来实现这一目标?

很长的路要走

如果您需要快速解决方案,只需跳转到Short Way ,阅读本文即可了解它是如何工作的。 JsonResult派生您自己的JsonErrorResult类:

public sealed JsonErrorResult : JsonResult
{
    public JsonErrorResult(StatusCodes statusCode, object value)
        : base(value)
    {
        _statusCode = statusCode;
    }

    private readonly JsonErrorResult StatusCodes _statusCode;
}

现在覆盖ExecuteResultAsync()方法以更改默认JsonResult实现的状态代码:

public override Task ExecuteResultAsync(ActionContext context)
{
    context.HttpContext.Response.StatusCode = _statusCode;
    return base.ExecuteResultAsync(context);
}

您只需返回调用BadRequest()您只需执行以下操作:

return new JsonErrorResult(StatusCodes.Status400BadRequest, new 
{
    StatusCode = "404",
    Error = "bla bla bla",
    Message = "bla bla bla"
});

当然,如果你经常使用它,你可能想创建自己的辅助方法:

protected static JSonErrorResult JsonError(StatusCodes statusCode,
                                           string error, string message)
{
    return new JsonErrorResult(statusCode, new 
    {
        StatusCode = Convert.ToString((int)statusCode),
        Error = error,
        Message = message
    });
}

像这样使用:

return JsonError(StatusCodes.Status400BadRequest, "bla bla bla", "bla bla bla");

捷径

JsonResult已经有StatusCode属性,那么你的辅助方法可能会变成这样:

protected static JSonResult JsonError(StatusCodes statusCode,
                                           string error, string message)
{
    var result = new JsonResult(new 
    {
        StatusCode = Convert.ToString((int)statusCode),
        Error = error,
        Message = message
    });

    result.StatusCode = (int)statusCode;

    return result;
}

我通常会返回这样的东西:

return Json(new { success = false, data = "" }, JsonRequestBehavior.AllowGet);

然后在我的 AJAX 成功中,我这样做:

if(result.success){
    result.data...
}else{
    //error...
}

如果您不想总是发送 200 代码,那么您可以这样做吗?

//if success...
Response.StatusCode = 200;
return Json(new { responseCode = 200, data = "", message = "..." }, JsonRequestBehavior.AllowGet);

//if failure...
Response.StatusCode = 404;
return Json(new { responseCode = 404, data = "", message = "..." }, JsonRequestBehavior.AllowGet);

创建函数来处理错误。

function AjaxCompletion(xhr) {
    switch (xhr.status) {
        case 200:
            //Your Message
            break;
        case 401: //unauthorize
           //Your desire message
            break;
    }
}

AJAX complete

  complete: function (xhr) {
            AjaxCompletion(xhr);
        }

感谢您的代码,它起作用了(一段时间后)。 看来您编写的是伪代码而不是代码本身。 因此,为了让其他人的生活更轻松,这里是您的完全相同的代码,但有一个运行的类。

public sealed class JsonErrorResult : JsonResult {

    private readonly HttpStatusCode _statusCode;

    public JsonErrorResult(HttpStatusCode sCode, object value) : base(value) {
        _statusCode = sCode;
    }

    public override Task ExecuteResultAsync(ActionContext context) {
        context.HttpContext.Response.StatusCode = (int)_statusCode;
        return base.ExecuteResultAsync(context);
    }

    public static JsonResult JsonError(HttpStatusCode statusCode,
                                               string message, string error = "") {
        var result = new JsonResult(new {
            StatusCode = Convert.ToString((int)statusCode),
            Error = error,
            Message = message
        });

        result.StatusCode = (int)statusCode;

        return result;
    }
}

最后你这样称呼它:

return JsonErrorResult.JsonError(System.Net.HttpStatusCode.Unauthorized,
                                "error msg");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM