对于 asp.net 站点,什么是好的错误处理实践?例子?谢谢!
7 回答
与任何 .net 项目一样,我发现最好的方法是仅捕获特定错误类型(如果它们可能发生在给定页面上)。
例如,您可以为给定输入的用户捕获格式异常(以防 JavaScript 验证失败并且您没有使用 tryparse),但始终将顶级异常的捕获留给全局错误处理程序。
try
{
//Code that could error here
}
catch (FormatException ex)
{
//Code to tell user of their error
//all other errors will be handled
//by the global error handler
}
如果需要,您可以使用 ASP.Net 的开源elmah(错误记录模块和处理程序)来为您执行顶级/全局错误捕获。
使用elmah,它可以创建一个错误日志,通过一个简单的配置 Web 界面可以查看。您还可以过滤不同类型的错误,并为不同的错误类型拥有自己的自定义错误页面。
我发现一种特别有用的做法是创建一个通用错误页面,然后将 web.config 的 customErrors 节点上的 defaultRedirect 设置为该错误页面。
然后设置您的 global.asax 以记录所有未处理的异常,然后将它们(未处理的异常)放在某个类的静态属性中(我有一个名为 ErrorUtil 的类,具有静态 LastError 属性)。然后,您的错误页面可以查看此属性以确定要向用户显示的内容。
更多细节在这里: http: //www.codeproject.com/KB/aspnet/JcGlobalErrorHandling.aspx
嗯,这是相当开放的,这非常酷。我给你推荐一个word .doc,你可以从Dot Net Spider下载,它实际上是我小公司代码标准的基础。该标准包括一些非常有用的错误处理技巧。
一个这样的异常示例(我不记得这是文档的原始内容还是我们将其添加到文档中):永远不要“捕获异常并且什么也不做”。如果你隐藏一个异常,你永远不会知道异常是否发生。您应该始终尝试通过以编程方式检查所有错误情况来避免异常。
不该做什么的例子:
try
{
...
}
catch{}
非常顽皮,除非你有充分的理由。
您应该确保可以捕获应用程序生成的大部分错误,并向用户显示友好的消息。但当然,您无法捕获所有错误,因为您可以使用 web.config 和 defaultRedirect 由另一个用户。另一个非常方便的记录错误的工具是 ELMAH。ELMAH 将记录您的应用程序生成的所有错误,并以非常易读的方式显示给您。在您的应用程序中插入 ELMAH 就像在 web.config 文件中添加几行代码并附加程序集一样简单。您绝对应该尝试一下 ELMAH,它确实可以为您节省数小时的痛苦。
在每个页面中针对您预期可能发生的异常进行防御性编码并适当地处理它们,因此不要在每次发生异常时都扰乱用户。
记录所有异常,并提供参考。
为任何未处理的异常提供通用错误页面,该页面提供了用于支持的参考(支持可以从日志中识别详细信息)。不要显示实际的异常,因为大多数用户不会理解它,但它会暴露有关您系统的信息(可能是密码等),因此存在潜在的安全风险。
不要捕获所有异常并且对它们不做任何事情(如上面的答案)。这样做几乎没有充分的理由,有时您可能想要捕获特定异常而不是故意这样做,但这应该明智地使用。
将用户重定向到标准错误页面并不总是一个好主意。如果用户正在处理表单,他们可能不希望被重定向离开正在处理的表单。我将所有可能导致异常的代码放在 try/catch 块中,并在 catch 块中吐出一条警告消息,提醒用户发生错误,并将异常记录在数据库中,包括表单输入、查询字符串等等。不过,我正在开发一个内部站点,所以大多数用户在遇到问题时都会给我打电话。对于公共站点,您可能希望使用 elmah 之类的东西。
public string BookLesson(Customer_Info oCustomerInfo, CustLessonBook_Info oCustLessonBookInfo)
{
string authenticationID = string.Empty;
int customerID = 0;
string message = string.Empty;
DA_Customer oDACustomer = new DA_Customer();
using (TransactionScope scope = new TransactionScope())
{
if (oDACustomer.ValidateCustomerLoginName(oCustomerInfo.CustId, oCustomerInfo.CustLoginName) == "Y")
{
// if a new student
if (oCustomerInfo.CustId == 0)
{
oCustomerInfo.CustPassword = General.GeneratePassword(6, 8);
oCustomerInfo.CustPassword = new DA_InternalUser().GetPassword(oCustomerInfo.CustPassword, false);
authenticationID = oDACustomer.Register(oCustomerInfo, ref customerID);
oCustLessonBookInfo.CustId = customerID;
}
else // if existing student
{
oCustomerInfo.UpdatedByCustomer = "Y";
authenticationID = oDACustomer.CustomerUpdateProfile(oCustomerInfo);
}
message = authenticationID;
// insert lesson booking details
new DA_Lesson().BookLesson(oCustLessonBookInfo);
}
else
{
message = "login exists";
}
scope.Complete();
return message;
}
}