【问题标题】:MVC 2.0 - Custom handling of all errors to return jsonMVC 2.0 - 自定义处理所有错误以返回 json
【发布时间】:2011-02-21 20:02:32
【问题描述】:

我有一个 MVC 2 应用程序,我希望所有请求都返回 json。我已经覆盖了HandleErrorAttribute 和AuthorizeAttribute。我的目标是所有错误(甚至是 403 和 404)都以 json 格式返回。

这是我的错误处理程序。 ExceptionModel 是一个简单的类,它定义了我的应用程序返回的任何错误。异常处理程序是一个将错误详细信息转换为格式化的电子邮件并将其发送给我的类。

public class HandleErrorJsonAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        context.ExceptionHandled = true;

        RaiseErrorSignal(context.Exception);

        context.RequestContext.HttpContext.Response.ContentType = "application/json";

        JsonSerializer serializer = new JsonSerializer();
        serializer.Serialize(context.HttpContext.Response.Output, new ExceptionModel(context.Exception));
    }

    private static void RaiseErrorSignal(Exception ex)
    {
        IExceptionHandler handler = Resolve();

        handler.HandleError(ex.GetBaseException());
    }

    private static IExceptionHandler Resolve()
    {
        return ServiceLocator.Locate<IExceptionHandler>();
    }
}

这里是澄清的异常模型

public class ExceptionModel
{
    public int ErrorCode { get; set; }
    public string Message { get; set; }

    public ExceptionModel() : this(null)
    {

    }

    public ExceptionModel(Exception exception)
    {
        ErrorCode = 500;
        Message = "An unknown error ocurred";

        if (exception != null)
        {
            if (exception is HttpException)
                ErrorCode = ((HttpException)exception).GetHttpCode();

            Message = exception.Message;
        }
    }

    public ExceptionModel(int errorCode, string message)
    {
        ErrorCode = errorCode;
        Message = message;
    }
}

最后,我的自定义授权属性。我使用表单身份验证,但我不想要任何自动重定向。我只是想让错误显示在屏幕上并停止任何进一步的处理。

public class AuthorizeTokenAttribute : System.Web.Mvc.AuthorizeAttribute
{
    public bool SuperAdminOnly { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = base.AuthorizeCore(httpContext);

        if(!SuperAdminOnly)
            return authorized;

        if(!authorized)
            return authorized;

        return SessionHelper.UserIsSuperAdmin(httpContext.User.Identity.Name);
    }

    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        throw new HttpException(403, "Access Denied");
    }
}

这对大多数错误都很有效,但它缺少一件事。我有一个这样的控制器动作。

[AuthorizeToken]
[HttpPost]
public JsonResult MyAction()
{
    return new JsonResult();
}

当您通过帖子提交时它工作正常,但在获取时我收到未处理的 404 错误。

“/”应用程序中的服务器错误。

找不到资源。

描述:HTTP 404。资源 您正在寻找(或其中之一 依赖项)可能已被删除, 它的名字被改变了,或者是 暂时不可用。请 查看以下 URL 并确保 它拼写正确。

请求的 URL:/MyController/MyAction

版本信息:Microsoft .NET 框架版本:4.0.30319; ASP.NET 版本:4.0.30319.1

这发生在 GET 上,这是预期的默认行为。但是,我该如何处理这种情况,以便我可以像这样返回 json

{"ErrorCode":404,"Message":"Page Not Found"}

【问题讨论】:

    标签: asp.net-mvc-2 exception-handling custom-errors


    【解决方案1】:

    为了亲自处理错误,我更喜欢 Global.asax 中的 Application_Error 事件:

    protected void Application_Error(object sender, EventArgs e)
    {
        var exception = Server.GetLastError();
        Response.Clear();
        Server.ClearError();
    
        var httpException = exception as HttpException;
        var routeData = new RouteData();
        routeData.Values["controller"] = "Errors";
        routeData.Values["action"] = "Index";
        routeData.Values["error"] = exception;
    
        IController errorController = new ErrorsController();
        errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    }
    

    然后有一个ErrorsController:

    public class ErrorsController : Controller
    {
        public ActionResult Index(Exception exception)
        {
            var errorCode = 500;
            var httpException = exception as HttpException;
            if (httpException != null)
            {
                errorCode = httpException.ErrorCode;
            }
    
            return Json(new
            {
                ErrorCode = errorCode,
                Message = exception.Message
            }, JsonRequestBehavior.AllowGet);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-10
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 2010-12-24
      • 2010-09-27
      相关资源
      最近更新 更多