I want to use Application_Error with my MVC project, but i can't get it to work. I add the following to my Global.asax file:
我想在我的MVC项目中使用Application_Error,但是我不能让它工作。我在全局中添加了以下内容。asax文件:
protected void Application_Error(object sender, EventArgs e)
{
Exception objErr = Server.GetLastError().GetBaseException();
Session["Test"] = "Message:" + objErr.Message.ToString();
}
(The Session is only for tests. Im gonna use a database to log error, if i get this to work.) Then i try to throw an exception from my HomeController and my Home/Index View, but it only triggers Debug.
(会话仅用于测试。我将使用数据库来记录错误,如果我让它工作的话。然后我尝试从我的HomeController和我的Home/Index视图中抛出一个异常,但它只触发Debug。
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
throw (new Exception());
return View();
}
In my Webconfig file i set a defaulterror page but it doesn't redirect to the view:
在我的Webconfig文件中,我设置了一个默认恐怖页面,但它不会重定向到视图:
<customErrors defaultRedirect="Home/Error">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
2 个解决方案
#1
16
So firstly remember that global error handling should be a last resort, and controller classes have a specific error method for errors;
首先要记住,全局错误处理应该是最后的手段,而控制器类有针对错误的特定错误方法;
protected virtual bool OnError(string actionName,
System.Reflection.MethodInfo methodInfo, Exception exception)
Within this you can redirect to the standard shared error view;
在这个范围内,您可以重定向到标准的共享错误视图;
protected override bool OnError(string actionName,
System.Reflection.MethodInfo methodInfo, Exception exception)
{
RenderView("Error", exception);
return false;
}
The problem you have in the global application error is that it has no concept of views or controllers, so if you want to redirect in there then you must use a known URL
您在全局应用程序错误中遇到的问题是它没有视图或控制器的概念,因此如果您想重定向到那里,那么必须使用已知的URL。
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
System.Diagnostics.Debug.WriteLine(exception);
Response.Redirect("/Home/Error");
}
but you don't need to do this. If you set the default error page in web.config then you don't need that redirect
但你不需要这样做。如果您在web中设置了默认的错误页面。然后你不需要重定向。
<customErrors defaultRedirect="Home/Error" />
However, unless you've added an error view to your Home controller that doesn't exist, so add the following to the home controller
但是,除非您向您的主控制器添加了一个不存在的错误视图,所以将以下内容添加到主控制器中。
public ActionResult Error()
{
return View();
}
Then (if you're sensible) you'd put the error handling code in the Error() method, as that's where all unhandled errors will end up.
然后(如果您是明智的),您应该将错误处理代码放入error()方法中,因为所有未处理的错误将在此结束。
public ActionResult Error()
{
Exception exception = Server.GetLastError();
System.Diagnostics.Debug.WriteLine(exception);
return View();
}
And finally remember that by default you don't see custom errors if you are connecting to localhost! So you need to change that behaviour
最后记住,默认情况下,如果连接到本地主机,就不会看到自定义错误!所以你需要改变这种行为。
<customErrors mode="On" defaultRedirect="/Home/Error" />
#2
1
- Do you have a Session set up in the first place? If the error is triggered from an
IHttpHandler
not marked withIRequiresSessionState
, then accessingSession
will fail. - 你是否在一开始就设置了一个会话?如果在IHttpHandler中触发的错误没有以IRequiresSessionState标记,那么访问会话将会失败。
- What are you doing with
Session["Test"]
? Are you sure your code is actually not working? You could try a File.Open and simply output some text (say, the current time) toC:\my-log.txt
, which is slightly more likely to succeed than usingSession
. - 会话["测试"]你在做什么?你确定你的代码没有工作吗?你可以尝试一个文件。打开并简单地输出一些文本(例如,当前时间)到C:\my-log。txt比使用会话更容易成功。
-
GetBaseException
isn't useful in this case (nor generally for logging) as far as I can tell. - 就我所知,在这种情况下,GetBaseException并不是很有用(通常也不是用于日志记录)。
-
Message
is of typestring
- calling.ToString()
isn't necessary. In general, I'd strongly recommend avoidingToString()
where possible - if you're using it because you're unsure of the type of the object, that should be a red flag; doing an end-run around the type system can hide subtle bugs (for instance,DBNull.Value.ToString() == ""
). For GUI's the builtin types provide a.ToString(IFormatProvider)
overload which is culture-sensitive and avoid portability issues. Since that overload is also not present onobject
it's also a safeguard to avoid the very weakly typed.ToString
calls. - 消息的类型为string - call . tostring()不是必需的。一般来说,我强烈建议避免使用ToString(),如果您使用它,因为您不确定对象的类型,那应该是一个危险信号;在类型系统周围进行最终运行可以隐藏一些细微的错误(例如,DBNull.Value.ToString() == ")。对于GUI来说,构建类型提供了一个. tostring (IFormatProvider)重载,它对文化敏感,并且避免了可移植性问题。由于该重载也不存在于对象上,因此它也是避免非常弱类型的. tostring调用的保护。
#1
16
So firstly remember that global error handling should be a last resort, and controller classes have a specific error method for errors;
首先要记住,全局错误处理应该是最后的手段,而控制器类有针对错误的特定错误方法;
protected virtual bool OnError(string actionName,
System.Reflection.MethodInfo methodInfo, Exception exception)
Within this you can redirect to the standard shared error view;
在这个范围内,您可以重定向到标准的共享错误视图;
protected override bool OnError(string actionName,
System.Reflection.MethodInfo methodInfo, Exception exception)
{
RenderView("Error", exception);
return false;
}
The problem you have in the global application error is that it has no concept of views or controllers, so if you want to redirect in there then you must use a known URL
您在全局应用程序错误中遇到的问题是它没有视图或控制器的概念,因此如果您想重定向到那里,那么必须使用已知的URL。
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
System.Diagnostics.Debug.WriteLine(exception);
Response.Redirect("/Home/Error");
}
but you don't need to do this. If you set the default error page in web.config then you don't need that redirect
但你不需要这样做。如果您在web中设置了默认的错误页面。然后你不需要重定向。
<customErrors defaultRedirect="Home/Error" />
However, unless you've added an error view to your Home controller that doesn't exist, so add the following to the home controller
但是,除非您向您的主控制器添加了一个不存在的错误视图,所以将以下内容添加到主控制器中。
public ActionResult Error()
{
return View();
}
Then (if you're sensible) you'd put the error handling code in the Error() method, as that's where all unhandled errors will end up.
然后(如果您是明智的),您应该将错误处理代码放入error()方法中,因为所有未处理的错误将在此结束。
public ActionResult Error()
{
Exception exception = Server.GetLastError();
System.Diagnostics.Debug.WriteLine(exception);
return View();
}
And finally remember that by default you don't see custom errors if you are connecting to localhost! So you need to change that behaviour
最后记住,默认情况下,如果连接到本地主机,就不会看到自定义错误!所以你需要改变这种行为。
<customErrors mode="On" defaultRedirect="/Home/Error" />
#2
1
- Do you have a Session set up in the first place? If the error is triggered from an
IHttpHandler
not marked withIRequiresSessionState
, then accessingSession
will fail. - 你是否在一开始就设置了一个会话?如果在IHttpHandler中触发的错误没有以IRequiresSessionState标记,那么访问会话将会失败。
- What are you doing with
Session["Test"]
? Are you sure your code is actually not working? You could try a File.Open and simply output some text (say, the current time) toC:\my-log.txt
, which is slightly more likely to succeed than usingSession
. - 会话["测试"]你在做什么?你确定你的代码没有工作吗?你可以尝试一个文件。打开并简单地输出一些文本(例如,当前时间)到C:\my-log。txt比使用会话更容易成功。
-
GetBaseException
isn't useful in this case (nor generally for logging) as far as I can tell. - 就我所知,在这种情况下,GetBaseException并不是很有用(通常也不是用于日志记录)。
-
Message
is of typestring
- calling.ToString()
isn't necessary. In general, I'd strongly recommend avoidingToString()
where possible - if you're using it because you're unsure of the type of the object, that should be a red flag; doing an end-run around the type system can hide subtle bugs (for instance,DBNull.Value.ToString() == ""
). For GUI's the builtin types provide a.ToString(IFormatProvider)
overload which is culture-sensitive and avoid portability issues. Since that overload is also not present onobject
it's also a safeguard to avoid the very weakly typed.ToString
calls. - 消息的类型为string - call . tostring()不是必需的。一般来说,我强烈建议避免使用ToString(),如果您使用它,因为您不确定对象的类型,那应该是一个危险信号;在类型系统周围进行最终运行可以隐藏一些细微的错误(例如,DBNull.Value.ToString() == ")。对于GUI来说,构建类型提供了一个. tostring (IFormatProvider)重载,它对文化敏感,并且避免了可移植性问题。由于该重载也不存在于对象上,因此它也是避免非常弱类型的. tostring调用的保护。