2016-02-28 41 views
0

我有一個註冊形式爲我的新用戶:已經有一個開放的DataReader

enter image description here

然後,它也有一個按鈕:

enter image description here

當按鈕Register點擊,我設置命令來檢查電子郵件是否已經存在。

它會檢查值並能夠在調試過程中找到值。

但是時出現錯誤,說

已經有一個用此命令,必須先關閉相關聯的打開的DataReader。

這裏是我的ASP.NET標記:

<div id="success" runat="server" class="alert alert-success" visible="false"> 
      Account registration success! 
      <br /> 
      Account sent for approval. Thank you. 
</div> 

<div id="emailavail" runat="server" class="alert alert-success" visible="false"> 
      Email is Available. 
</div> 

<div id="error" runat="server" class="alert alert-danger" visible="false"> 
      Email is already in use 
      <br /> 
      Please choose another email/Login if already registered 
</div> 

<div class="form-group"> 
     <br /> 
      <label class="control-label col-lg-4">User Type</label> 
      <div class="col-lg-8"> 
       <asp:Label ID="UserType" runat="server" class="form-control" text="Customer" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Email</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtEmail" runat="server" class="form-control" type="email" 
        MaxLength="80" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Password</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtPassword" runat="server" class="form-control" TextMode="Password" MaxLength="20" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">First Name</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtFN" runat="server" class="form-control" MaxLength="80" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Last Name</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtLN" runat="server" class="form-control" MaxLength="50" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Company Name</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtCName" runat="server" class="form-control" MaxLength="50" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Street</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtStreet" runat="server" class="form-control" MaxLength="50" required /> 
      </div> 
</div> 

<div class="form-group"> 
      <label class="control-label col-lg-4">Municipality</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtMunicipality" runat="server" class="form-control" MaxLength="100" required /> 
      </div> 
</div> 

     <div class="form-group"> 
      <label class="control-label col-lg-4">City</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtCity" runat="server" class="form-control" MaxLength="50" required /> 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label col-lg-4">Company Phone</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtCPhone" runat="server" class="form-control" MaxLength="12" type="number" required /> 
      </div> 
     </div> 

     <div class="form-group"> 
      <label class="control-label col-lg-4">Mobile</label> 
      <div class="col-lg-8"> 
       <asp:TextBox ID="txtMobile" runat="server" class="form-control" MaxLength="12" type="number" required /> 
      </div> 
     </div> 
    </div> 
    <div class="col-lg-10"> 
     <span class="pull-right"> 
     <asp:Button ID="btnCancel" runat="server" class="btn" style="color:White" text="Cancel" PostBackUrl="~/Default.aspx" BackColor="Black" /> 
      <asp:Button ID="btnRegister" runat="server" class="btn btn-success" 
      Text="Register" style="color:White" onclick="btnRegister_Click" /> 

     </span> 
    </div> 

這裏是後臺代碼:

protected void btnRegister_Click(object sender, EventArgs e) 
{ 
    con.Open(); 

    SqlCommand cmd = new SqlCommand(); 
    cmd.Connection = con; 

    cmd.CommandText = "SELECT Email FROM Registration WHERE [email protected]"; 
    cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 

    SqlDataReader dr = cmd.ExecuteReader(); 

    if (dr.HasRows) 
    { 
     error.Visible = true; 
     emailavail.Visible = false; 
     success.Visible = false; 

     con.Close(); 
    } 
    else 
    { 
     cmd.Connection = con; 
     cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " + 
      "@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, @CompanyPhone, @Mobile, " + 
      "@Status, @DateAdded, @DateModified)"; 

     cmd.Parameters.AddWithValue("@TypeID", "2"); 
     cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 
     cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text)); 
     cmd.Parameters.AddWithValue("@FirstName", txtFN.Text); 
     cmd.Parameters.AddWithValue("@LastName", txtLN.Text); 
     cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text); 
     cmd.Parameters.AddWithValue("@Street", txtStreet.Text); 
     cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text); 
     cmd.Parameters.AddWithValue("@City", txtCity.Text); 
     cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text); 
     cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text); 
     cmd.Parameters.AddWithValue("@Status", "Pending"); 
     cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now); 
     cmd.Parameters.AddWithValue("@DateModified", DBNull.Value); 
    } 

    cmd.ExecuteNonQuery(); 
    con.Close(); 
} 

我曾嘗試:

  1. 刪除我selectedindexchanged爲標籤名稱,因爲它確實再次選擇來自用戶的電子郵件。
  2. 我試着移動con.close,因爲正如我研究過的,它在那裏有一些事情要做。

請幫我忙這個小時。

預先感謝您!

我還是新的C#

+0

你打開閱讀器,但你嘗試發送新的命令。始終關閉第一個連接,併爲INSERT打開一個新連接。 –

+0

或者,使用「IF NOT EXISTS」語法在一個SQL命令中檢查並插入操作。 –

+0

您需要啓用[MultipleActiveResultSets](https://msdn.microsoft.com/en-us/library/cfa084cz(v = vs.110).aspx) – Steve

回答

2

這只是搞砸了這麼多層次

  • dr.HasRows是假的
    就跳轉到別的
    沒有搞錯,你仍然有開放
    然後你重複cmd.Connection一個DataReader =精讀;
  • dr.HasRows是真的
    關閉
    然後跳到過去別的
    的連接,那麼你嘗試cmd.ExecuteNonQuery();您已關閉的連接和select語句甚至不是一個有效的ExecuteNonQuery

上沒有任何目的,首先DataReader的
只是不要指望「SELECT COUNT(*)FROM註冊WHERE電子郵件= @Email」
檢查次數,如果0做插入
然後關閉連接

cmd.CommandText = "SELECT count(*) FROM Registration WHERE [email protected]"; 
    cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 
    if ((Int32)cmd.ExecuteScalar() > 0) 
    { 
     error.Visible = true; 
     emailavail.Visible = false; 
     success.Visible = false; 
    } 
    else 
    { 
     cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " + 
      "@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, " + 
      "@CompanyPhone, @Mobile, @Status, @DateAdded, @DateModified)"; 
     cmd.Parameters.AddWithValue("@TypeID", "2"); 
     cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 
     cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text)); 
     cmd.Parameters.AddWithValue("@FirstName", txtFN.Text); 
     cmd.Parameters.AddWithValue("@LastName", txtLN.Text); 
     cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text); 
     cmd.Parameters.AddWithValue("@Street", txtStreet.Text); 
     cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text); 
     cmd.Parameters.AddWithValue("@City", txtCity.Text); 
     cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text); 
     cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text); 
     cmd.Parameters.AddWithValue("@Status", "Pending"); 
     cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now); 
     cmd.Parameters.AddWithValue("@DateModified", DBNull.Value); 
     cmd.ExecuteNonQuery(); 
    } 
    con.Close(); 

也能做到這一點在一次旅行,但我不積極,將與參數

工作210個
IF NOT EXISTS(SELECT ...); 
BEGIN 
    INSERT INTO ...; 
END; 
+0

謝謝!我做到了,但我決定將它們分開。 –

4

讓我們重新再讀你的異常消息:

已經有使用此命令這 必須先關閉相關聯的打開的DataReader

您有幾個選項。

您可以手動配置你的讀者後con.Close()線像

dr.Dispose(); 

,或者您可以使用using語句來自動配置你的讀者瞭解(我推薦)。

using(SqlDataReader dr = cmd.ExecuteReader()) 
{ 
    ... 
} // <-- On this line your dr will disposed 

,或者您可以爲您的INSERT語句像一個新的SqlCommand對象;

cmd = new SqlCommand(); 
cmd.Connection = con; 
... 

而且realated:There is already an open DataReader associated with this Command which must be closed first

+0

它會工作,如果我將有新的SQL命令插入? –

+0

@PaulineGailMallariChan你爲什麼不試試看? –

4

雖然Soner格尼爾已經給了,造成這種情況有效的解決方案,我想給另一個角度看,讓你的整個問題沒有實際意義(答案也太長評論)。

你在這裏做什麼對學習是有好處的,但是你在這裏重新發明了輪子。三種主要的基於網絡的語言(PHP,Java和.NET)都具有靈活且經過驗證的用戶管理系統。

鑑於這是ASP.NET,我強烈建議您使用默認的ASP.NET成員資格提供程序。成員資格提供程序將所有用戶管理抽象出來,因此您不需要手動配置SQL命令。例如,我可以在您的代碼中看到2個明顯的缺陷:

  1. 您不會醃製您的密碼散列;
  2. 您在SHA中使用過時的散列算法。它應該是bcrypt,Scrypt,PBKDF2或新的Argon2函數。

如果您使用ASP.NET成員資格提供程序解決這兩個問題。

+0

它是參數化的,因此不容易受到SQL注入漏洞利用 – Paparazzi

+0

@Frisbee我的其他觀點仍然存在。他沒有妥善保存密碼,也沒有嘶嘶作響。這兩個都由會員提供商處理。會員提供商還提供其他好處。 – Nzall

+0

我沒有對其他觀點發表評論。爲什麼不只是糾正你的答案? – Paparazzi

0

感謝您的幫助和關照@Soner @Frisbee

我所做的就是將它們分開,因爲我曾經想過,我得到了答案,更容易爲我,當我回到相同的情況瞭解。

protected void btnRegister_Click(object sender, EventArgs e) 
    { 
     con.Open(); 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = con; 

     cmd.CommandText = "SELECT Email FROM Users WHERE [email protected]"; 
     cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 
     SqlDataReader dr = cmd.ExecuteReader(); 

     if (dr.HasRows) 
     { 
       error.Visible = true; 
       emailavail.Visible = false; 
       success.Visible = false; 
       con.Close(); 
     } 

     else 
     { 

      success.Visible = false; 
      con.Close(); 
      RegisterUser(); 
     } 



    } 

    void RegisterUser() 
    { 
     con.Open(); 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = con; 
     cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " + 
      "@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, @CompanyPhone, @Mobile, " + 
      "@Status, @DateAdded, @DateModified)"; 
     cmd.Parameters.AddWithValue("@TypeID", "2"); 
     cmd.Parameters.AddWithValue("@Email", txtEmail.Text); 
     cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text)); 
     cmd.Parameters.AddWithValue("@FirstName", txtFN.Text); 
     cmd.Parameters.AddWithValue("@LastName", txtLN.Text); 
     cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text); 
     cmd.Parameters.AddWithValue("@Street", txtStreet.Text); 
     cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text); 
     cmd.Parameters.AddWithValue("@City", txtCity.Text); 
     cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text); 
     cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text); 
     cmd.Parameters.AddWithValue("@Status", "Pending"); 
     cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now); 
     cmd.Parameters.AddWithValue("@DateModified", DBNull.Value); 
     cmd.ExecuteNonQuery(); 
     con.Close(); 

    } 

感謝您再次傢伙

相關問題