所以我习惯用try-catch-finally语句编写代码,不包括using语句,我试图将后者合并到我的代码中。
我已在下面附上原始和修订后的代码。这个修订版是否足够?
另外,关于捕获错误,我已经看到以下代码在这里使用了很多次。应该何时使用/不使用,因为这不会告知用户错误?
catch (Exception ex)
{
throw ex;
}
原始代码:
protected void signIn()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlCommand comm;
comm = new MySqlCommand("Select user_id, username, email, salt, hashed_pw, role, activated FROM users WHERE username=@username", conn);
comm.Parameters.Add("@username", MySqlDbType.VarChar);
comm.Parameters["@username"].Value = txtUsername.Text;
MySqlDataReader reader;
try
{
conn.Open();
reader = comm.ExecuteReader();
if (reader.Read())
{
string saltAndPwd = String.Concat(txtPassword.Text, reader["salt"].ToString());
string hashSaltAndPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
if (hashSaltAndPwd.Equals(reader["hashed_pw"].ToString()))
{
if (reader["activated"].ToString().Equals("Y"))
{
Session["Username"] = reader["username"].ToString();
Session["Role"] = reader["role"].ToString();
Session["UserID"] = reader["user_id"].ToString();
Session["EmailAddress"] = reader["email"].ToString();
if (reader["role"].ToString().Equals("0"))
{
Session["PermanentRole"] = "admin";
}
else if (reader["role"].ToString().Equals("2"))
{
Session["PermanentRole"] = "tutor";
}
Response.Redirect("~/portal.aspx");
}
else
{
lblError.Text = "Your account has not been activated. Please check your inbox and activate your account or reset your password by clicking the link above.";
}
}
else
{
lblError.Text = "Incorrect password.";
}
}
else
{
lblError.Text = "Username does not exist.";
}
reader.Close();
}
catch
{
lblError.Text = "Database connection error. Please try again.";
}
finally
{
conn.Close();
}
}
修改后的代码:
protected void signIn()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using (MySqlConnection conn = new MySqlConnection(connStr))
{
using (MySqlCommand cmd = conn.CreateCommand())
{
string cmdText = "Select user_id, username, email, salt, hashed_pw, role, activated FROM users WHERE username=@username";
cmd.CommandText = cmdText;
cmd.Parameters.Add("@username", MySqlDbType.VarChar);
cmd.Parameters["@username"].Value = txtUsername.Text;
try
{
conn.Open();
reader = cmd.ExecuteReader();
if (reader.Read())
{
string saltAndPwd = String.Concat(txtPassword.Text, reader["salt"].ToString());
string hashSaltAndPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
if (hashSaltAndPwd.Equals(reader["hashed_pw"].ToString()))
{
if (reader["activated"].ToString().Equals("Y"))
{
Session["Username"] = reader["username"].ToString();
Session["Role"] = reader["role"].ToString();
Session["UserID"] = reader["user_id"].ToString();
Session["EmailAddress"] = reader["email"].ToString();
if (reader["role"].ToString().Equals("0"))
{
Session["PermanentRole"] = "admin";
}
else if (reader["role"].ToString().Equals("2"))
{
Session["PermanentRole"] = "tutor";
}
Response.Redirect("~/portal.aspx");
}
else
{
lblError.Text = "Your account has not been activated. Please check your inbox and activate your account or reset your password by clicking the link above.";
}
}
else
{
lblError.Text = "Incorrect password.";
}
}
else
{
lblError.Text = "Username does not exist.";
}
reader.Close();
}
catch
{
lblError.Text = "Database connection error. Please try again.";
}
finally
{
conn.Close();
}
}
}
答案 0 :(得分:2)
1)conn.Close();
不是必需的,因为using语句将为您调用close
。它相当于
MySqlConnection conn = new MySqlConnection(connStr)
try
{
....
}
finally
{
conn.Close();
}
2)表格的抓取
catch (Exception ex)
{
throw ex;
}
在我能想到的任何情况下都不建议使用。它有2个问题
除了重新抛出异常外,它什么都不做。除非你想对它做些什么,否则你不会捕获异常(例如:记录错误)
重新排除执行throw ex;
的异常会削减堆栈跟踪。任何捕获该异常的人都会看到该行生成的错误,丢失了有用的信息
答案 1 :(得分:1)
您不需要finally { ...}
因为using
将处置连接。
您的问题:
catch (Exception ex)
{
throw ex;
}
当您想要记录异常但仍然抛出它时很常见,只是捕捉和重新投掷没有任何意义。
但应该这样做:
catch (Exception ex)
{
LogManager.Log(ex);
throw; //rethrow
}