Asp.net 使用数据库连接时,何时在ASPX中记录错误?

Asp.net 使用数据库连接时,何时在ASPX中记录错误?,asp.net,sql,exception-handling,Asp.net,Sql,Exception Handling,使用数据库连接时,何时在ASPX中记录错误? 在下面的代码中,C#2008(第三版)中Pro ASP.NET 3.5的作者建议在catch块中记录SQL错误。我的问题是: 这是惯例吗 这是最好的做法吗 简而言之,关闭当前连接并完全单独处理错误是否更好?这两种方法的优缺点是什么 编辑添加:澄清问题不是是否应该登录(该问题已在其他地方讨论),此问题更具体。问题是要在代码中记录的位置。它应该在catch中完成(当连接仍然打开时),还是应该关闭当前连接并完全分开记录?在返回并到达“finally”之前,

使用数据库连接时,何时在ASPX中记录错误? 在下面的代码中,C#2008(第三版)中Pro ASP.NET 3.5的作者建议在catch块中记录SQL错误。我的问题是:

这是惯例吗

这是最好的做法吗

简而言之,关闭当前连接并完全单独处理错误是否更好?这两种方法的优缺点是什么

编辑添加:澄清问题不是是否应该登录(该问题已在其他地方讨论),此问题更具体。问题是要在代码中记录的位置。它应该在catch中完成(当连接仍然打开时),还是应该关闭当前连接并完全分开记录?在返回并到达“finally”之前,不会将日志添加为catch的一部分(即使它调用外部方法,该连接仍保持打开状态)

    public int InsertEmployee(EmployeeDetails emp)
    {
        SqlConnection con = new SqlConnection(connectionString);
        SqlCommand cmd = new SqlCommand("InsertEmployee", con);
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.Add(new SqlParameter("@FirstName", SqlDbType.NVarChar, 10));
        cmd.Parameters["@FirstName"].Value = emp.FirstName;
        cmd.Parameters.Add(new SqlParameter("@LastName", SqlDbType.NVarChar, 20));
        cmd.Parameters["@LastName"].Value = emp.LastName;
        cmd.Parameters.Add(new SqlParameter("@TitleOfCourtesy", SqlDbType.NVarChar, 25));
        cmd.Parameters["@TitleOfCourtesy"].Value = emp.TitleOfCourtesy;
        cmd.Parameters.Add(new SqlParameter("@EmployeeID", SqlDbType.Int, 4));
        cmd.Parameters["@EmployeeID"].Direction = ParameterDirection.Output;

        try 
        {
            con.Open();
            cmd.ExecuteNonQuery();
            return (int)cmd.Parameters["@EmployeeID"].Value;
        }
        catch (SqlException err) 
        {
            // Replace the error with something less specific.
            // You could also log the error now.
            throw new ApplicationException("Data error.");
        }
        finally 
        {
            con.Close();            
        }
    }
我通常采取“一网打尽”的方法,记录真正异常的任何异常,并吞下其余的。:)

编辑:

我想我需要让自己更清楚。。。异常的经验法则是记录任何和所有异常,除非在捕获异常有意义的情况下

例如:

在.NET 1.1中,唯一具有TryParse()的数据类型是Double。因此,对于其他数据类型(如int),这样做是有意义的:

try{
    int.Parse(x)
} catch (FormatException){
    //take care of invalid input
}

我建议。棒极了的日志库。

我觉得这是个糟糕的建议

假设您使用的是原始ADO.NET,您应该将
IDisposable
对象(如
IDbConnection
)包装在using块中


如果发生意外异常(即,您无法执行任何操作),请不要捕获它,并让一些错误处理程序(如日志处理程序)处理它。

简短回答:这取决于

长答覆:

只有当有人检查日志时,日志记录才真正重要。如果这是一个个人网站,那么你可能不会太在意。但是,如果这是一个任务关键型应用程序,那么您应该记录尽可能多的错误。错误日志不仅提供帮助调试的信息,通过显示发生错误的代码,还可以显示错误是否在一天中的特定时间发生(可能与另一个进程冲突)。但是,您需要记住记录小错误所涉及的额外开销。有时,根据错误的程度,只向用户显示错误并让他们决定是否与您联系是件大事,这可能是可以的

我个人已经通过电子邮件向我发送了未处理的例外情况。使用Page_错误事件处理程序处理ASP.NET应用程序非常容易

protected void Page_Error(object sender, EventArgs e)
{
    //Handle Error Here
}
超时异常和我捕获的其他异常通常会记录到某个数据库的某个位置并永久保存。我通常把日常的错误和成功审计记录到一个文本文件中,保存一个月左右

希望这有帮助

更新:
我想我现在更明白你的问题了。要在连接打开时登录catch,还是在连接关闭后登录?如果在关闭连接后登录,可能会有更好的性能。然而,我认为简单的逻辑和可读性是值得权衡的,即登录catch并在finally中关闭连接。

要实现关注点的分离,需要从该方法中提取错误处理。有三种方法可以做到这一点:

1) (最不优雅)使用两种方法:

public void InsertEmployee(EmployeeDetails emp)
{
    ...
}

public void TryInsertEmployee(EmployeeDetails emp)
{
    try
    {
        InsertEmployee(emp);
    }
    catch (Exception e)
    {
        logger.Error(e);
        throw new ApplicationException("Data error.");
    }
}
2) 使用装饰图案

public class ErrorHandlingEmployeeGateway
{
    ...
}
3) 使用AOP


吞咽异常是一种糟糕的做法:@Mauricio仅供参考,这些搜索结果中的第一篇文章讨论了在哪些情况下吞咽异常是合适的。请删除-1:)不,我仍然认为这里不是接受例外的地方。@Mauricio你没有正确阅读我的答案。我指示他记录异常。是的,我确实理解你的答案,但我不同意。一般来说,你不应该在catch块中使用“throw new”。如果您想捕获、记录和重播,只需使用“throw;”。否则,您的代码看起来很好。谢谢您的更新。它有助于澄清问题。考虑到这一点后,我现在要假设,如果代码在服务器上运行,那么命中率可能不足以产生影响。也给你一个投票。谢谢。我同意,性能增益可能微不足道。即使在性能方面,我也倾向于可读性/可维护性。并不是说我不在乎表现,我在乎。但有时这种权衡是值得的。祝你好运
[LogException]
public void InsertEmployee(EmployeeDetails emp)
{
    ...
}