如何正确捕获ASP.Net MVC 5项目中视图甚至控制器引发的异常

时间:2017-04-23 09:20:36

标签: c# asp.net asp.net-mvc exception asp.net-mvc-5

好的,我是ASP.Net MVC 5中的新手,正在开展一个小型already existing项目,所以请耐心等待。我发现很难理解/处理/解码我的代码中引发的异常。

以下是在项目中处理异常的方式:

public class BaseController : Controller
{
    protected override void OnException(ExceptionContext filterContext)
    {
        if (!filterContext.ExceptionHandled)
        {
            filterContext.ExceptionHandled = true;
            Response.StatusCode = 500;    
            Response.StatusDescription = Constants.DISPLAYED_ERROR_MESSAGE_SHARED;

            if (filterContext.Exception.GetType() == typeof(ValidationException))
            { Response.StatusDescription += Constants.ADDITIONAL_DETAIL_ERROR_MESSAGE + filterContext.Exception.Message; }
            else
            { Response.StatusDescription += Constants.GENERIC_ERROR_MESSAGE; }
        }
    }
}

public static string DISPLAYED_ERROR_MESSAGE_SHARED = "We apologize for the inconvenience, but an error has occurred. <br />";
public static string GENERIC_ERROR_MESSAGE = "Please retry your previous action. If the issues persist, please contact the facility.";
public static string ADDITIONAL_DETAIL_ERROR_MESSAGE = "<br />Additional Details: ";

Error.cshtml

@model HandleErrorInfo
@{ 
    Layout = "~/Views/Shared/_ErrorLayout.cshtml";
}

<h2 style="color:darkred">An Error Has Occurred</h2>
<div style="color:black; font-size:110%;">
    @Html.Raw(Constants.DISPLAYED_ERROR_MESSAGE_SHARED)
    <br />
    @Constants.GENERIC_ERROR_MESSAGE

    <br />

    @if (Model.Exception.GetType() == typeof(ValidationException))
    {
        <div style="font-size:90%;">
            @Html.Raw(Constants.ADDITIONAL_DETAIL_ERROR_MESSAGE)
            @Model.Exception.Message
        </div>
    }
</div>

在学习之后我知道现在控制器中引发的任何异常都会被上面的方法捕获,从而保护我免受代码中try catch的多余使用。公平够了。

问题无论我的项目中出现什么异常。我总是在浏览器中看到以下消息 enter image description here

调试结果 每次引发异常时,filterContext.handled的值都会变为true,因此代码永远不会进入onException逻辑内部并直接呈现Error.cshtml视图。另外,我注意到当我检查filterContext.Exception的值时,我看到了异常的确切reason/issue

问题1:当引发异常时我可以在调试期间看到filterContext.Exception正在告诉我确切的问题,那么为什么我在浏览器中看不到它。为什么我必须一直调试并通过将鼠标悬停在filterContext上来检查Exeception。

问题2:我每次调试时都会发现filterContext.Exceptionhandled为true。在什么情况下它会是假的?

问题3:我错误地在视图中为属性添加了HtmlHelper文本框。但与该观点相关的模型没有该属性。现在,当我调试时,我可以看到filterContext.Exception告诉我确切的问题。但是因为我filterContext.Exception已经知道我做了什么错误。我无法在我的UI中显示它而不是一直显示通用消息。

问题4 除了徘徊并了解我的错误/异常原因之外,我还可以从filterContet.Exception中获得什么好处。当代码为graceful mannerin development时,我无法以某种方式在UI的not in production中看到我的错误。

修改 全球Asax

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }
    }

强文 Global.asax.cs的Application_Start方法中,我有这一行:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

1 个答案:

答案 0 :(得分:1)

ExceptionHandled属性设置为true,因为在到达控制器中定义的ActionFilter方法之前已经设置了OnException

您可以从 Global.asax.cs 文件中删除HandleErrorAttribute的全局注册,以便在执行OnException控制器方法时ExceptionHandled属性为false,您必须在退出此方法之前将其设置为true

我认为使用的正确解决方案是创建一个新类,将其命名为CustomHandleErrorAttribute,派生自HandleErrorAttribute并覆盖该派生类的OnException方法。

之后你可以改变这一行:

filters.Add(new HandleErrorAttribute());

到这一行:

filters.Add(new CustomHandleErrorAttribute());