如何正确捕获由ASP.NET MVC 5项目中的视图甚至控制器引发的异常 [英] How to correctly catch exception raised by view or even controller in ASP.Net MVC 5 project
问题描述
这是在项目中处理异常的方式:
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 =由于造成不便,我们深表歉意,但发生错误。
public static string GENERIC_ERROR_MESSAGE =请重试您以前的操作,如果问题仍然存在,请联系设施。
public static string ADDITIONAL_DETAIL_ERROR_MESSAGE =< br />附加详细信息:;
Error.cshtml
@model HandleErrorInfo
@ {
Layout =〜/ Views / Shared / _ErrorLayout.cshtml;
}
< h2 style =color:darkred>发生错误< / 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。公平的。
问题无论我的项目中出现了什么异常。我总是在浏览器中看到以下消息
调试结果
每次出现异常时,code> filterContext.handled 的值出现为 true
,因此代码不会进入逻辑直接 onException
Error.cshtml 视图呈现。另外,我注意到,当我检查 filterContext.Exception
的值时,我会看到确切的原因/问题
例外。
问题1:发生异常时,调试过程中可以看到 filterContext.Exception
告诉我确切的问题,为什么我不会在浏览器中看到它。为什么我必须调试所有的时间,并通过将鼠标悬停在filterContext上检查Exeception。
问题2:每次调试我找到filterContext.Exception处理为true。在哪种情况下将会是假的?
问题3:错误地,我在视图中为属性添加了一个HtmlHelper文本框。但与该视图相关联的模型没有该属性。现在调试我可以看到filterContext.Exception告诉我确切的问题。但是由于我的 filterContext.Exception
已经知道我做了什么错误。我不能在我的UI中显示,而不是一般的消息。
问题4
除了悬停,了解我的错误/异常原因,我可以从filterContet 。例外。在开发中代码和<$ code code code code code code code code code code $ c>不在生产中
。
编辑
全球Asax
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add (new HandleErrorAttribute());
}
}
而在 Application_Start
方法在强文本 Global.asax.cs我有这一行:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
ExceptionHandled
属性设置为 true
,因为已经有 ActionFilter
设置为达到 OnException
方法定义到您的控制器中。
您可以从 Global.asax.cs 中删除 HandleErrorAttribute
的全局注册文件,因此执行 OnException
控制器方法时, ExceptionHandled
属性将为 false
您必须将其设置为 true
,然后再退出此方法。
使用正确的解决方案我认为是创建一个新的类让它命名为 CustomHandleErrorAttribute
,它来源于 HandleErrorAttribute
并覆盖派生类的OnException
方法。
之后,您可以更改此行:
filters.Add(new HandleErrorAttribute());
到这一行:
filters.Add(new CustomHandleErrorAttribute());
Ok, I am newbie in ASP.Net MVC 5 and working on a small already existing
project so bear with me. I am finding it hard to understand/handle/decode exception raised in my code.
Here is the way the exception is getting handled in the project:
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>
After studying I got to know that now any exception raised in the controller will be caught in above method thus protecting me from redundant use of try catch in our code. Fair Enough.
Issue No matter what ever the exception is raised in my project. I always see below message in browser
Debug Results
Everytime an exception is raised the value of filterContext.handled
comes out to be true
and thus the code never enters inside the onException
Logic and directly Error.cshtml
view is rendered. Also, I have noticed that when I check the value of filterContext.Exception
I see the exact reason/issue
for the exception.
Question 1: When an exception is raised and I can see during debugging that filterContext.Exception
is telling me the exact issue then why I do not see it in my browser. Why do I have to debug all the time and check the Exeception by hovering my mouse on filterContext.
Question 2: Everytime I debug I find the filterContext.Exceptionhandled to be true. In what case it will be false?
Question 3: By mistake I added a HtmlHelper textbox for a property in a view. But the model associated with that view did not had that property. Now when I debug I can see that filterContext.Exception is telling me the exact issue. But as my filterContext.Exception
already knows what mistake I did. Can't I display that in my UI rather than a generic message all the time.
Question 4
Apart from hovering over and getting to know my mistake/reason of exception, what benefit can I take from filterContet.Exception. Can't I somehow make my mistake visible in a graceful manner
in UI atleast when code is in development
and not in production
.
EDIT Global Asax
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
And in the Application_Start
method in strong textGlobal.asax.cs I have this line:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
The ExceptionHandled
property is set to true
because there is already ActionFilter
that set that before reaching your OnException
method defined into your controller.
You can remove the global registration of HandleErrorAttribute
from your Global.asax.cs file so when executing your OnException
controller method the ExceptionHandled
property will be false
and you have to set it to true
before you quit this method.
The correct solution to use I think is to create a new class let name it CustomHandleErrorAttribute
that derives from HandleErrorAttribute
and overrides the OnException
method on that derived class.
After that you can change this line:
filters.Add(new HandleErrorAttribute());
to this line:
filters.Add(new CustomHandleErrorAttribute());
这篇关于如何正确捕获由ASP.NET MVC 5项目中的视图甚至控制器引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!