2014-05-02 90 views
0

這是。從類運行MySQL查詢。沒有正確傳遞給班級的數值

- 我有一個窗口。我有一堂課。

- 該窗口是一個密碼登錄窗口,因此它有一個用戶名,密碼箱和登錄按鈕的文本框。這個窗口後面

代碼:

using MySql.Data.MySqlClient; 

namespace Masca 
{ 
/// <summary> 
/// Interaction logic for Login.xaml 
/// </summary> 
public partial class Login : Elysium.Controls.Window 
{ 

    InvalidLogin secondForm; 

    // This window now knows that the loginc class exists. The class hold all MySQL related code 
    public loginc loginc; 

    // THis window now knows about the MainWindow. This is the window that will be opened after authetication checks are successful. 
    MainWindow window; 

    // The login window is now publically available to other windows. 
    public Login() 
    { 
     InitializeComponent(); 
    } 

    //This is the event that is carried out when the user clicks 'Login' 
    public void Logon_Click(object sender, RoutedEventArgs e) 
    { 
     // instantiate the class 
     loginc = new loginc(); 

     //Check to see if the username is blank 
     if (username.Text == "") 
     { 
      //If it is, show the custom dialogue box "nousername" 
      new nousername().ShowDialog(); 
     } 
     //Then check to see if the password is blank 
     else if (password.Password == "") 
     { 
      //If it is, show the custom dialogue box "nopassword" 
      new nopassword().ShowDialog(); 
     } 
     // However if they both have content.. 
     else if (username.Text != "" && password.Password != "") 
     { 
      // Trigger this method in the loginc class. 
      loginc.Login(); 
     } 
    } 

    // This method is triggered by the login method in the loginc class if the credentials are valid 
    public void login() 
    { 
     window = new MainWindow(username.Text); 
     window.Show(); 
     this.Close(); 
    } 

    // This method is also triggered by the login method in the loginc class but only if the credentials are not valid 
    public void failLogin() 
    { 
     //If the entered username and password does not matchup with any record in the database, show the error messagebox 'InvalidLogin'; 
     secondForm = new InvalidLogin(); 

     //The form that opened the dialoge box is 'Login', the login window; 
     secondForm.setCreatingForm = this; 

     // Keep that in mind when you show the dialogue box; 
     secondForm.ShowDialog(); 
    } 

-The類認爲,將用於檢查數據庫中的用戶名和密碼的MySQL的代碼。

using MySql.Data.MySqlClient; 

namespace Masca 
{ 
public class loginc 
{ 
    //This class now knows about the login window. 
    public Login login; 

    // Constructor 
    public loginc() 
    { 

    } 

    // This method is triggered by the 'Logon_Click' event in the Login window 
    public void Login() 
    { 
     //instantiate the Login window 
     login = new Login(); 

     //Database connection parameters 
     string sqlcon = "datasource=localhost;port=3306;username = root; password = root"; 
     //Query to excecute 
     string query = "SELECT * FROM logon.login where username = '"+login.username.Text+"' and password = '"+login.password.Password+"';"; 

     //Declarations 
     MySqlConnection con = new MySqlConnection(sqlcon); 
     MySqlCommand cmd = new MySqlCommand (query,con); 
     MySqlDataReader rdr; 

     // Excecution 
     con.Open(); 
     rdr = cmd.ExecuteReader(); 
     int count = 0; 
     while (rdr.Read()) 
     { 
      count = count + 1; 
     } 

     // If the username and password matches a record in the database table.. 
     if (count == 1) 
     { 
      //Trigger the login method in the login window 
      login.login(); 
     } 

     // Otherwise... 
     else 
     { 
      //Trigger the failLogin method in the login window 
      login.failLogin(); 
     } 

     con.Close(); 
    } 

那麼這個問題呢?每次輸入正確或錯誤的憑證登錄時,我都會收到無效憑證對話框。

我猜(我可能是錯的)這很可能是因爲我實例化的類。我所引用的(在查詢中)+ login.username.Text +和+ login.password.Password +的詳細信息是從登錄窗口的另一個實例收集的,而不是我輸入的那個實例。因此,它收集的詳細信息是空白。

這也可以解釋爲什麼當我使用登錄表中的實際憑證替換+ login.username.Text +和+ login.password.Password +時,登錄窗口保持打開狀態,即使在MainWindow打開後,當我編程時它關閉。因爲它完全關閉了一個不同的實例。

即使有我所有的猜測,我仍然不知道這個問題的可行解決方案。我能想到的唯一一個是使用單例模式的靜態類來確保程序在運行時只有一個類和窗口的實例。我不太確定該從哪一個開始。

任何想法?

+0

你熟悉傳遞參數的概念並從函數返回值? –

+0

我聞到SQL注入。 – Yahya

回答

1

只要讓您的loginc.Login()方法將Login窗口作爲參數,並使用該窗口而不是創建新窗口;

也就是說,改變;

public void Login() 
{ 
    //instantiate the Login window 
    login = new Login(); 

public void Login (Login login) 
{ 
    // you now have the existing login window as "login". 

並調用它作爲;

loginc.Login(this); // pass this object (the Login window) as a parameter 

另一個(可能更好)的方式是作爲字符串的登錄名和密碼傳遞給loginc.Login(),這樣的loginc類並不需要知道在Login類中的字段都沒有。

你也應該真的看看參數化查詢,在登錄框將打破你的查詢,並允許有人來寫自己的SQL對數據庫之一'

Here you can read up a little on SQL injection

+0

我去了你的第一個建議,它的工作就像一個魅力。非常感謝。看看鏈接了。 – Offer

0

的首先,你的SQL語句暴露注入你在你的查詢中使用參數更重要。保存creadentials靜態瓦爾在登錄表單的將它們作爲參數:

在第一形式:

public partial class Login : Elysium.Controls.Window 
{ 
.... 
.... 
else if (username.Text != "" && password.Password != "") 
{ 
// Trigger this method in the login class. 
loginc.Login();   
loginc.username=username.Text; 
loginc.pass=password.Password; 
} 
.... 
在第二形態

public class loginc 
{ 
    public static username; 
    public static pass; 
... 
... 
string query = "SELECT * FROM logon.login where username = @user and password = @pass"; 
cmd.Parameters.AddWithValue(@user,username); 
cmd.Parameters.AddWithValue(@pass,pass); 
+0

哇,這很快。嘗試一下。 – Offer

+0

好像我在「公共靜態用戶名**; **」和「公共靜態傳遞**; **」無效標記';'在類,結構或接口成員聲明中。不太確定如何解決這個問題...我錯過了什麼? – Offer