检查用户名或用户电子邮件已经存在
我正在一个简单的注册页面中,用户不能input相同的用户名或电子邮件,我做了一个代码,防止用户input用户名,它的工作,但是当我试图阻止用户input相同的用户名或电子邮件没有工作。
而我的问题是,“如何在用户不能input已存在的电子邮件的情况下添加另一个条件?
我试图在这个代码中做,但它没有工作:
protected void Button_Click(object sender, EventArgs e) { SqlConnection con = new SqlConnection( ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString ); SqlCommand cmd1 = new SqlCommand("select 1 from Table where Name =@UserName", con); SqlCommand cmd2 = new SqlCommand("select 1 from Table where Email=@UserEmail", con); con.Open(); cmd1.Parameters.AddWithValue("@UserName", Name_id.Text); cmd2.Parameters.AddWithValue("@UserEmail", Email_id.Text); using (var dr1 = cmd1.ExecuteReader()) { if (dr1.HasRows) { Label1.Text = "user name already exists"; } using (var dr2 = cmd2.ExecuteReader()) { if (dr2.HasRows) { Label1.Text = "email already exists"; } else { dr1.Close(); dr2.Close(); //add new users con.Close(); } } } }
但我得到这个错误:
已经有一个打开的DataReader与这个Command关联,必须先closures它。
就像我在评论中所说的,你的devise很糟糕!
首先你应该有数据访问层。 这应该是在大的解决scheme项目,但在你的情况下,你可以把它像新的目录。 在这个目录下你创buildSqlManager类这里是代码:
public class SqlManager { public static string ConnectionString { get { return ConfigurationManager.ConnectionStrings["DevConnString"].ConnectionString; } } public static SqlConnection GetSqlConnection(SqlCommand cmd) { if (cmd.Connection == null) { SqlConnection conn = new SqlConnection(ConnectionString); conn.Open(); cmd.Connection = conn; return conn; } return cmd.Connection; } public static int ExecuteNonQuery(SqlCommand cmd) { SqlConnection conn = GetSqlConnection(cmd); try { return cmd.ExecuteNonQuery(); } catch { throw; } finally { conn.Close(); } } public static object ExecuteScalar(SqlCommand cmd) { SqlConnection conn = GetSqlConnection(cmd); try { return cmd.ExecuteScalar(); } catch { throw; } finally { conn.Close(); } } public static DataSet GetDataSet(SqlCommand cmd) { return GetDataSet(cmd, "Table"); } public static DataSet GetDataSet(SqlCommand cmd, string defaultTable) { SqlConnection conn = GetSqlConnection(cmd); try { DataSet resultDst = new DataSet(); using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { adapter.Fill(resultDst, defaultTable); } return resultDst; } catch { throw; } finally { conn.Close(); } } public static DataRow GetDataRow(SqlCommand cmd) { return GetDataRow(cmd, "Table"); } public static DataRow GetDataRow(SqlCommand cmd, string defaultTable) { SqlConnection conn = GetSqlConnection(cmd); try { DataSet resultDst = new DataSet(); using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { adapter.Fill(resultDst, defaultTable); } if (resultDst.Tables.Count > 0 && resultDst.Tables[0].Rows.Count > 0) { return resultDst.Tables[0].Rows[0]; } else { return null; } } catch { throw; } finally { conn.Close(); } } }
之后,你应该有业务对象层。 在更大的解决scheme是项目在您的案例目录。 如果您在页面TaxesEdit.aspx中,则应该在BO(业务对象)中添加Tax.cs类。
类的方法的例子,为您的第一个button:
public DataSet GetTaxesByUserName(string userName) { SqlCommand cmd = new SqlCommand(@" select 1 from Table where Name =@UserName"); cmd.Parameters.AddWithValue("@UserName", userName); return DA.SqlManager.GetDataSet(cmd); }
您可以获取数据集中所有需要的数据。 之后,您将执行诸如taxesDst.Tables [0] .Rows.Count> 0(或== 0)
对于插入,你可以有这样的方法:
public virtual void Insert(params object[] colValues) { if (colValues == null || colValues.Length % 2 != 0) throw new ArgumentException("Invalid column values passed in. Expects pairs (ColumnName, ColumnValue)."); SqlCommand cmd = new SqlCommand("INSERT INTO " + TableName + " ( {0} ) VALUES ( {1} )"); string insertCols = string.Empty; string insertParams = string.Empty; for (int i = 0; i < colValues.Length; i += 2) { string separator = ", "; if (i == colValues.Length - 2) separator = ""; string param = "@P" + i; insertCols += colValues[i] + separator; insertParams += param + separator; cmd.Parameters.AddWithValue(param, colValues[i + 1]); } cmd.CommandText = string.Format(cmd.CommandText, insertCols, insertParams); DA.SqlManager.ExecuteNonQuery(cmd); }
为此,您需要在当前BO类中具有属性TableName。
在这种情况下,这个方法可以在任何地方使用,只需要一行代码就可以调用它们,而且不会出现类似你的问题。
你已经打开另一个DataReader里面的第一个,这就是问题..我已经重新安排了一点点检查出来..
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); SqlCommand cmd1 = new SqlCommand("select 1 from Table where Name =@UserName", con), cmd2 = new SqlCommand("select 1 from Table where Email=@UserEmail", con); con.Open(); cmd1.Parameters.AddWithValue("@UserName", Name_id.Text); cmd2.Parameters.AddWithValue("@UserEmail", Email_id.Text); bool userExists = false, mailExists = false; using (var dr1 = cmd1.ExecuteReader()) if (userExists = dr1.HasRows) Label1.Text = "user name already exists"; using (var dr2 = cmd2.ExecuteReader()) if (mailExists = dr2.HasRows) Label1.Text = "email already exists"; if (!(userExists || mailExists)) { //add User }
打开另一个数据库之前,需要closures一个数据库。 虽然不是我该怎么做,但是可以通过在每个IF
之后closures数据读取器来处理运行时错误:
using (var dr1 = cmd1.ExecuteReader()) { if (dr1.HasRows) { string Text = "user name already exists"; } dr1.Close(); } using (var dr2 = cmd2.ExecuteReader()) { if (dr2.HasRows) { string ext = "email already exists"; } else { //add new users } dr2.Close(); } con.Close();
这可能工作,但有几件事我会做不同的…
protected void Button_Click(object sender, EventArgs e) { bool inputIsValid = true; var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); var userNameCmd = new SqlCommand("SELECT 1 FROM Table WHERE Name = @UserName", con); var emailCmd = new SqlCommand("SELECT 1 FROM Table WHERE Email = @UserEmail", con); con.Open(); userNameCmd.Parameters.AddWithValue("@UserName", Name_id.Text); emailCmd.Parameters.AddWithValue("@UserEmail", Email_id.Text); using (var userNameReader = userNameCmd.ExecuteReader()) { if (userNameReader.HasRows) { inputIsValid = false; Label1.Text = "User name already exists"; } } using (var emailReader = emailCmd.ExecuteReader()) { if (emailReader.HasRows) { inputIsValid = false; Label1.Text = "Email address already exists"; } } if (inputIsValid) { // Insert code goes here } con.Close(); }
你为什么不这样做?
[Flags] public enum ValidationStatus { Valid = 0 , UserNameInUse = 1 , EmailInUse = 2 , } public ValidationStatus ValidateUser( string userName , string emailAddr ) { ValidationStatus status ; string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString ; using ( SqlConnection con = new SqlConnection( connectionString ) ) using ( SqlCommand cmd = con.CreateCommand() ) { cmd.CommandText + @" select status = coalesce( ( select 1 from dbo.myTable t where t.UserName = @UserName ) , 0 ) + coalesce( ( select 2 from dbo.myTable t where t.UserEmail = @UserEmail ) , 0 ) " ; cmd.Parameters.AddWithValue( "@UserName" , userName ) ; cmd.Parameters.AddWithValue( "@emailAddr" , emailAddr ) ; int value = (int) cmd.ExecuteScalar() ; status = (ValidationStatus) value ; } return status ; }
除了其他任何事情,像这样的事情打两次DB是愚蠢的。 这更清楚地expression了意图。
然后你可以在你的button点击处理程序中使用它,如下所示:
protected void Button_Click( object sender , EventArgs e ) { string userName = Name_id.Text ; string emailAddr = Email_id.Text ; ValidationStatus status = ValidateUser( userName , emailAddr ) ; switch ( status ) { case ValidationStatus.Valid : Label1.Text = "" ; break ; case ValidationStatus.EmailInUse : Label1.Text = "Email address in use" ; break ; case ValidationStatus.UserNameInUse : Label1.Text = "User name in use" ; break ; case ValidationStatus.EmailInUse|ValidationStatus.UserNameInUse: Label1.Text = "Both user name and email address in use." ; break ; default : throw new InvalidOperationException() ; } if ( status == ValidationStatus.Valid ) { CreateNewUser() ; } }