2009-12-04 103 views
0

我有一个棘手的问题要问,所以请与我比较。异常和Linq到实体

在下面的代码中,这是有效的,因为程序员有兴趣只将物理数据层引起的特定错误投影到事件日志。其余的被推到堆栈的更远处。这是因为他能够捕获OdbcException(s)。

我正在实施我自己的MembershipProvider。然而,我使用Linq to Entities,但是我想只发送事件日志的低级/物理级异常。有没有例外,我可以捕捉使用Linq的实体,这将允许我赶上该级别?

正如您在下面看到的,即使在try块内抛出的异常也不会被捕获,因此不会被发送到事件日志。

Linq to Entities如何做到这一点?

代码:

public override string ResetPassword(string username, string answer) 
{ 
if (!EnablePasswordReset) 
{ 
    throw new NotSupportedException("Password reset is not enabled."); 
} 

if (answer == null && RequiresQuestionAndAnswer) 
{ 
    UpdateFailureCount(username, "passwordAnswer"); 

    throw new ProviderException("Password answer required for password reset."); 
} 

string newPassword = 
    System.Web.Security.Membership.GeneratePassword(newPasswordLength, MinRequiredNonAlphanumericCharacters); 


ValidatePasswordEventArgs args = 
    new ValidatePasswordEventArgs(username, newPassword, true); 

OnValidatingPassword(args); 

if (args.Cancel) 
    if (args.FailureInformation != null) 
    throw args.FailureInformation; 
    else 
    throw new MembershipPasswordException("Reset password canceled due to password validation failure."); 


OdbcConnection conn = new OdbcConnection(connectionString); 
OdbcCommand cmd = new OdbcCommand("SELECT PasswordAnswer, IsLockedOut FROM Users " + 
    " WHERE Username = ? AND ApplicationName = ?", conn); 

cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username; 
cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName; 

int rowsAffected = 0; 
string passwordAnswer = ""; 
OdbcDataReader reader = null; 

try 
{ 
    conn.Open(); 

    reader = cmd.ExecuteReader(CommandBehavior.SingleRow); 

    if (reader.HasRows) 
    { 
    reader.Read(); 

    if (reader.GetBoolean(1)) 
    throw new MembershipPasswordException("The supplied user is locked out."); 

    passwordAnswer = reader.GetString(0); 
    } 
    else 
    { 
    throw new MembershipPasswordException("The supplied user name is not found."); 
    } 

    if (RequiresQuestionAndAnswer && !CheckPassword(answer, passwordAnswer)) 
    { 
    UpdateFailureCount(username, "passwordAnswer"); 

    throw new MembershipPasswordException("Incorrect password answer."); 
    } 

    OdbcCommand updateCmd = new OdbcCommand("UPDATE Users " + 
    " SET Password = ?, LastPasswordChangedDate = ?" + 
    " WHERE Username = ? AND ApplicationName = ? AND IsLockedOut = False", conn); 

    updateCmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(newPassword); 
    updateCmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = DateTime.Now; 
    updateCmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username; 
    updateCmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName; 

    rowsAffected = updateCmd.ExecuteNonQuery(); 
} 
catch (OdbcException e) 
{ 
    if (WriteExceptionsToEventLog) 
    { 
    WriteToEventLog(e, "ResetPassword"); 

    throw new ProviderException(exceptionMessage); 
    } 
    else 
    { 
    throw e; 
    } 
} 
finally 
{ 
    if (reader != null) { reader.Close(); } 
    conn.Close(); 
} 

if (rowsAffected > 0) 
{ 
    return newPassword; 
} 
else 
{ 
    throw new MembershipPasswordException("User not found, or user is locked out. Password not Reset."); 
} 
} 

回答

1

我想我已经想通了。通过Linq to Entities,你可以捕获EntityException。这将是上述代码中的OdbcException的等价类。

感谢任何花时间在此的人。