了解 ASP .NET (WebForms) 中的错误处理
Understanding error handling in ASP .NET (WebForms)
我有一个 Web 表单 (.NET 4.0) Web 应用程序构建为:
MyApp.Portal(包含页面、WCF AJAX 服务、脚本等的主门户)
MyApp.BusinessLayer(Class库调用DataAccess获取数据)
MyApp.Services(Class 库包含用于服务器端代码的 WCF 服务器)
MyApp.DataAccess(ADO 甲骨文)
我正在尝试遵循一些关于错误处理的教程,但到目前为止我得到的结果不一致。
我的问题是我应该如何处理应用程序中的错误?
我应该将所有方法包装在 try/catch 中吗?
我应该只用 try/catch 包装业务层中的方法吗?
我将如何使用 WCF Ajax 方法处理 PortalLayer 中发生的错误?
例如,我将以下内容添加到我的 Global.asax 文件中:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception exc = Server.GetLastError();
if (exc is HttpUnhandledException)
{
if (exc.InnerException != null)
{
exc = new Exception(exc.InnerException.Message);
Server.Transfer(@"\Pages\Error.aspx?handler=Application_Error%20-%20Global.asax", true);
}
}
}
但是大多数时候这不会被调用。我只是看到错误消息显示在屏幕上(就像一个美化的警报)。
或者,如果调用此方法,则 exc 不是 HttpUnhandledException,因此传输永远不会发生。
我也在我的 web.config 中尝试过这个,但我没有看到它有任何作用。 (如果我将其注释掉,我会得到相同的结果)
<customErrors mode="On" defaultRedirect="Error.aspx?handler=customErrors%20section%20-%20Web.config">
<error statusCode="404" redirect="ErrorPage.aspx?msg=404&handler=customErrors%20section%20-%20Web.config"/>
</customErrors>
最终目标是将用户重定向到一个页面(或者可能只是很好地显示错误),同时将其记录在文件中或将错误写入数据库。
当服务器处理页面(请求 .aspx、.ashx 资源)时,主线程中发生的异常将调用 void Application_Error(object sender, EventArgs e)
。
在两种情况下不会被调用:
- 您在处理 .aspx 资源时触发了新线程,异常将在该新线程中发生
- 在网络服务方法、wcf 方法等中(即非 .aspx 资源)
- 异常是 "bad ass" 异常 - 破坏应用程序域的那种 -
WhosebugException
或 OutOfMemoryException
因此对于 WCF、WebServices 来说,将所有入口点包装在
中是有意义的
try {}
catch(Exception e) {
Logger.Log(e);
throw;
}
声明(请注意,如果您有很多这样的声明,请花时间研究更通用的解决方案)。
另请注意 - 如果您的错误页面上有错误,您将看到黄屏死机(很明显)。所以我更喜欢将静态 html 页面显示为错误页面(出错的可能性最低)。
在您的错误处理代码中,您没有清除错误状态,而且我更喜欢 Redirect
而不是 Server.Transfer
来进行错误处理。最终剪辑看起来像:
var ex = Server.GetLastError();
Logger.Log(ex);
Server.ClearError();
Response.Redirect("/error.aspx");
最后说明 - 无需自己进行错误记录(优秀的程序员很懒惰 - 就“不要重新发明轮子”而言) - 有很多很棒的日志记录模块,如 Elmah、Microsoft Enterprise Library 或 log4net。
我有一个 Web 表单 (.NET 4.0) Web 应用程序构建为:
我正在尝试遵循一些关于错误处理的教程,但到目前为止我得到的结果不一致。
我的问题是我应该如何处理应用程序中的错误?
我应该将所有方法包装在 try/catch 中吗?
我应该只用 try/catch 包装业务层中的方法吗?
我将如何使用 WCF Ajax 方法处理 PortalLayer 中发生的错误?
例如,我将以下内容添加到我的 Global.asax 文件中:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception exc = Server.GetLastError();
if (exc is HttpUnhandledException)
{
if (exc.InnerException != null)
{
exc = new Exception(exc.InnerException.Message);
Server.Transfer(@"\Pages\Error.aspx?handler=Application_Error%20-%20Global.asax", true);
}
}
}
但是大多数时候这不会被调用。我只是看到错误消息显示在屏幕上(就像一个美化的警报)。
或者,如果调用此方法,则 exc 不是 HttpUnhandledException,因此传输永远不会发生。
我也在我的 web.config 中尝试过这个,但我没有看到它有任何作用。 (如果我将其注释掉,我会得到相同的结果)
<customErrors mode="On" defaultRedirect="Error.aspx?handler=customErrors%20section%20-%20Web.config">
<error statusCode="404" redirect="ErrorPage.aspx?msg=404&handler=customErrors%20section%20-%20Web.config"/>
</customErrors>
最终目标是将用户重定向到一个页面(或者可能只是很好地显示错误),同时将其记录在文件中或将错误写入数据库。
当服务器处理页面(请求 .aspx、.ashx 资源)时,主线程中发生的异常将调用 void Application_Error(object sender, EventArgs e)
。
在两种情况下不会被调用:
- 您在处理 .aspx 资源时触发了新线程,异常将在该新线程中发生
- 在网络服务方法、wcf 方法等中(即非 .aspx 资源)
- 异常是 "bad ass" 异常 - 破坏应用程序域的那种 -
WhosebugException
或OutOfMemoryException
因此对于 WCF、WebServices 来说,将所有入口点包装在
中是有意义的try {}
catch(Exception e) {
Logger.Log(e);
throw;
}
声明(请注意,如果您有很多这样的声明,请花时间研究更通用的解决方案)。
另请注意 - 如果您的错误页面上有错误,您将看到黄屏死机(很明显)。所以我更喜欢将静态 html 页面显示为错误页面(出错的可能性最低)。
在您的错误处理代码中,您没有清除错误状态,而且我更喜欢 Redirect
而不是 Server.Transfer
来进行错误处理。最终剪辑看起来像:
var ex = Server.GetLastError();
Logger.Log(ex);
Server.ClearError();
Response.Redirect("/error.aspx");
最后说明 - 无需自己进行错误记录(优秀的程序员很懒惰 - 就“不要重新发明轮子”而言) - 有很多很棒的日志记录模块,如 Elmah、Microsoft Enterprise Library 或 log4net。