2013-10-03 53 views
0

我有一個在服務器中創建的數據庫,我添加了一行MySql查詢瀏覽器進行測試。該行可以通過PhpMyAdmin或MySql查詢瀏覽器查看。MySqlCommand:沒有行返回

但是,當我想我的計劃之內達到這個表,它說我沒有行(reader.HasRows = false

CS是PublicVariables

這裏連接字符串代碼

public static int checkuser(string myuser, string mypass) 
{ 
     try 
     { 
      using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs)) 
      { 
       string MypassMd5 = MakeMD5(mypass); 
       conn.Open(); 

       if (conn == null) 
        Environment.Exit(0); 

       using (MySqlCommand cmd = 
       new MySqlCommand("SELECT username, password " + "FROM Users WHERE username = 'myuser'" ,conn)) 
       {       
        using (MySqlDataReader reader = cmd.ExecuteReader()) 
        { 
         //DateTime mytime = DateTime.Now ; 
         if (reader.HasRows) 
         { 
          if (Convert.ToString(reader["password"]) != MypassMd5) 
          { 
           reader.Close(); 
           conn.Close(); 
           return -1; 
          } 
          else 
          { 
           PublicVariables.UserId = Convert.ToString(reader["username"]); 
           PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]); 
           conn.Close(); 
           reader.Close(); 
           return 1; 
          } 
         } 
         else 
         { 
          reader.Close(); 
          conn.Close(); 
          return 2; 
         } 
       } 
      }    
     } 
    } 
    catch (MySqlException ex) 
    { 
     MessageBox.Show(ex.ToString()); 
    } 

    return 0; 
} 

我的代碼有什麼問題?

+0

請告訴我你正在使用的東西比MD5更安全的密碼哈希? MD5對此非常脆弱。 –

+0

@Joel我會用另一個加密代替MD5,但是因爲我正在翻譯一個用turbo pascal編寫的舊程序,並且它在我的舊程序中,所以我使用了這個例子,但我認爲使用shasum或Bcrypt,正如您所建議的那樣 –

回答

3

那麼主要的錯誤是在你的命令字符串中,myuser是一個變量,你不能傳遞它的值把變量名放在引號內。

new MySqlCommand("SELECT username, password FROM Users WHERE username = 'myuser'" ,conn) 

,而不是這一行應該轉換爲使用參數化查詢

string commandText = "SELECT username, password, userdegre FROM Users WHERE username = @uname"; 
using (MySqlCommand cmd = new MySqlCommand(commandText ,conn) 
{ 
    cmd.Parameters.AddWithValue("@uname", myuser); 
    .... 

你的代碼看你有另一個錯誤後這一點。您嘗試閱讀userdegre字段,但該字段未由您的查詢檢索,因此您需要將其添加到檢索字段的列表中。
但是,您確實需要知道的唯一字段是userdegre,因爲您已經知道用戶名和密碼,因此您可以刪除數據註冊並使用ExecuteScalar並將用戶名和密碼作爲WHERE子句的參數傳遞。如果您收到任何回報,那麼您確定您的用戶已通過數據庫進行身份驗證。

string commandText = "SELECT userdegre FROM Users WHERE username = @uname AND Password [email protected]"; 
using(MySqlCommand cmd = new MySqlCommand(commandText ,conn)) 
{       
    cmd.Parameters.AddWithValue("@uname", myuser); 
    cmd.Parameters.AddWithValue("@pwd", MypassMd5); 
    var result = cmd.ExecuteScalar(); 
    if(result != null) 
    { 
      PublicVariables.UserId = myuser; 
      PublicVariables.UserDegre = result.ToString(); 
    } 
} 
0

我會嘗試像這樣new MySqlCommand("SELECT username, password, userdegre " + "FROM Users WHERE username = 'myuser'" ,conn)) 在您的select語句中添加userdegre列名。

+0

最後對於c# 2008 net 3.5這個工作副本在@Joel和@ Steve的幫助下是這樣的: –

2

不檢查reader.HasRows。你需要撥打reader.Read(),並檢查結果。

此外,一些枝節問題:

  1. MD5是一個密碼哈希令人難以置信的薄弱。真。只是不要用它。看看bcrypt作爲很多更好的選擇。如果你不是自己編寫認證代碼,那更好。找一個圖書館尋求幫助,讓這些東西正確無誤...編寫認證代碼非常簡單,似乎工作,通過所有測試,但有一個微妙的缺陷,讓你在幾個月後黑客入侵。不需要撥打conn.Close()。這就是你的using塊。他們爲您處理。
  2. 我想刪除try/catch。由於您已經將錯誤條件返回給調用代碼,因此我會將其作爲處理錯誤的地方,以便您的try/catch應該在該級別進行。
  3. 您正在尋找userdegre的結果不在選擇列表中。
  4. 參數化查詢是你的朋友。

把它放在一起,你和你結束了這一點:

public static int checkuser(string myuser, string mypass) 
{ 
    string passHash = BCrypt(mypass); //Need to get bcyrpt library and make the function 
    using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs)) 
    using (MySqlCommand cmd = 
       new MySqlCommand("SELECT username, password, userdegre FROM Users WHERE username = @user" ,conn)) 
    { 
     cmd.Parameters.Add("@user", SqlDbType.NVarChar, 20).Value = myuser; 
     conn.Open(); 

     using (MySqlDataReader reader = cmd.ExecuteReader()) 
     { 
      if (!reader.Read()) return 2; 
      if (Convert.ToString(reader["password"]) != MypassMd5) return -1; 

      PublicVariables.UserId = Convert.ToString(reader["username"]); 
      PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]); 
      return 1; 
     } 
    } 
} 
+0

new MySqlCommand(「SELECT username,password,userdegre」+「FROM Users WHERE username = @user」,conn))//這是不工作 new MySqlCommand(「SELECT username,password,userdegre FROM Users WHERE username = @user」,conn))// This WORKS! @Steve感謝用於重新定義myuser變量的照明。 –

0

最後的C#的這08年淨利潤3.5工作副本@Joel的幫助後,並@史蒂夫是這樣的:

公共靜態INT usertrue(字符串爲myuser,串爲mypass)

{ 
     try 
     { 
      using (MySqlConnection conn = new MySqlConnection(PublicVariables.cs)) 
      { 
       string MypassMd5 = MakeMD5(mypass); 

       using (MySqlCommand cmd = 
       new MySqlCommand("SELECT username, password ,userdegre FROM Users WHERE username = @user",conn)) 
       { 
        cmd.Parameters.Add("@user", MySqlDbType.VarChar, 15).Value = myuser; 
        conn.Open(); 
        using (MySqlDataReader reader = cmd.ExecuteReader()) 
        { 

         if (!reader.Read()) return 2; 
         if (Convert.ToString(reader["password"]) != MypassMd5) return -1;       { 
         PublicVariables.UserId = Convert.ToString(reader["username"]); 
         PublicVariables.UserDegre = Convert.ToInt16(reader["userdegre"]); 
         return 1; 
        } 


       } 
      }    

      } 
     }