【问题标题】:Two step MVC 3 Error Handling using Custom Error Controller and HandleErrorAttribute使用自定义错误控制器和 HandleErrorAttribute 的两步 MVC 3 错误处理
【发布时间】:2012-06-13 10:34:59
【问题描述】:

我在 MVC3 应用程序中的自定义错误部分中使用了 HandleErrorAttribute 和自定义错误控制器的组合来处理错误。逻辑是通过 HandleErrorAttribute 中的 OnException 处理程序处理任何 Ajax 请求错误,并通过 ErrorController 处理其余错误。下面是代码-

// Handle any ajax error via HandleErrorAttribute 
public class HandleAjaxErrorAttribute : System.Web.Mvc.HandleErrorAttribute
 {
    public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
    {



        filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
        var exception = filterContext.Exception;

        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            //some logic
            filterContext.ExceptionHandled = true;
        }

    }
}

//Handle remaining errors in the Error Controller

public class ErrorController : Controller
{

    protected override void HandleUnknownAction(string actionName)
    {
        var exception = Server.GetLastError(); //Can't get the exception object here.
        //some logic
    }



}

Web.config 设置:

<customErrors mode="On" defaultRedirect="~/Error">
</customErrors>

当任何非 ajax 异常发生时,控制从 OnException 块流向错误控制器中的 HandleUnknownAction。但是我无法获取 Exception 对象。如何在错误控制器中获取异常对象?

另外,您认为这两个步骤的方法是处理 MVC3 中错误的正确方法吗?我曾想过使用 Application_Error 事件处理程序在集中位置处理错误,但根据我的研究,这不是 MVC 应用程序的推荐方法。

【问题讨论】:

  • 为什么不像处理 Ajax 一样简单地处理其他错误?我的意思是,如果是 Ajax 做某事,如果不是,调用视图并给它异常对象(这就是我在 MVC 项目中所做的)。您需要意识到 CustomErrors 只是重定向到给定的 url 并将导致错误的 Url 发送给它。但是,它不存储任何信息,它只是一个 url 重定向。
  • HandleErrorAttribute 无法处理 MVC 管道之外的错误(404、403 等),因此我仍然需要 CustomErrors 并且需要通过 Action 调用它,而不是直接调用 View。此外,我不想在 OnException 处理程序中硬编码视图名称。除了在一个地方处理所有错误更好。
  • @OmerAmsel,如果你能发布一些代码会很有帮助。

标签: asp.net-mvc-3 custom-errors onexception


【解决方案1】:

关于我上面的评论,我在这里粘贴我的代码是为了澄清我做了什么。

此代码位于 BaseController 内部(强烈建议制作一个,请参阅这篇文章:http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx

并且我已经重写了 OnException 方法(我的主要目标是区分 Ajax 调用和常规调用):

protected override void OnException(ExceptionContext filterContext)
    {
        // Set to true or else it'll still propagate
        filterContext.ExceptionHandled = true;

        string message;



        // Check if it's an Ajax request
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // Here I check if the custom error is on, if it isn't I'll paste the
            // stacktrace and the error
            if (!filterContext.HttpContext.IsCustomErrorEnabled)
            {
                message = filterContext.Exception.Message + filterContext.Exception.StackTrace;
            }
            else
            {
                message = "Something went wrong";
            }

            // TODO: Decide what to do if ajax
            filterContext.HttpContext.Response.StatusCode = 401;
            var json = new JsonResult {Data = message};
            json.ExecuteResult(this.ControllerContext);
        }
        else
        {
            // This is basically the same conditional, but instead of sending a JSON
            // I'll redirect to a view and give it the exception
            if (!filterContext.HttpContext.IsCustomErrorEnabled)
            {
                ViewData.Model = filterContext.Exception;
                this.View("Error").ExecuteResult(this.ControllerContext);
            }
            else
            {
               this.View("../Error/ServerError").ExecuteResult(this.ControllerContext);
            }

        }
    }
}

关于我上面的评论需要注意的重要一点是,我并不是说不要使用 CustomError,而是仅在确实发生在管道之外的错误(例如 401)时才考虑它。

【讨论】:

    【解决方案2】:

    我可能错了,但我相信您不必担心控制器中的错误信息,因为 MVC 会自动将其连接到视图中。因此,如果您像这样制作(Razor)视图,它应该可以工作:

    @model System.Web.Mvc.HandleErrorInfo
    

    任何日志记录都可以在您的属性中完成,但如果您需要在错误控制器中进行,请在您的错误控制器上创建一个 LogError 操作,该操作采用 HandleErrorInfo 参数并将其命名为:

    @Html.RenderAction("LogError", 模型)

    PS 我没有对此进行测试,但它应该可以工作。

    【讨论】:

      【解决方案3】:

      我的错误消息没有显示,并且 ErrorController 直到我执行以下设置后才启动

      <customErrors mode="On" defaultRedirect="~/Error">
      </customErrors>
      

      【讨论】:

        猜你喜欢
        • 2014-03-07
        • 2016-11-06
        • 1970-01-01
        • 1970-01-01
        • 2014-12-01
        • 1970-01-01
        • 2010-12-24
        • 2010-09-27
        • 1970-01-01
        相关资源
        最近更新 更多