从类运行MySQL查询。值未正确传递给类

时间:2014-05-02 10:03:32

标签: c# mysql wpf

在这里。

- 我有个窗口。我有一节课。

- 该窗口是一个密码登录窗口,因此它有一个用户名,密码框和登录按钮的文本框。

此窗口后面的代码:

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();
    }

- 该类包含将用于检查数据库内用户名和密码的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打开之后,当我编写它时,登录窗口仍保持打开状态关闭因为它完全关闭了一个不同的实例。

即使我的所有这些猜测,我仍然不知道我的这个问题的可行解决方案。我能想到的唯一一个是使用单例模式的静态类,以确保程序在运行时只有一个类和窗口的实例。我不太确定从哪开始。

任何想法?

2 个答案:

答案 0 :(得分: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。< / p>

Here you can read up a little on SQL injection

答案 1 :(得分: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);