例外:System.InvalidOperationException尝试验证登录信息

时间:2015-04-09 18:48:22

标签: c# sql visual-studio sql-server-2014

我正在尝试创建一个登录表单。但是有数据库问题。我创建了一个窗口表单,其中包含用户名和密码以及登录按钮。但我认为声明:

DataAdapterObject.Fill(DataTableObject) 

有一些错误。我正在使用Visual Studio Profesional 2013 Update 4和Sql Server 2014 Enterprise Editon。

守则如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Society_Accounting_Software
{
 public partial class LoginScreen : Form
{
    SqlConnection databaseConnect = new SqlConnection();


    public LoginScreen()
    {
        SqlConnection databaseConnect = new SqlConnection();
        databaseConnect.ConnectionString = "Data Source=GAURAV-PC;Initial Catalog=SocietyAccountingDatabase;Integrated Security=True";
        InitializeComponent();

    }

    private void label1_Click(object sender, EventArgs e)
    {

    }

    private void Form1_Load(object sender, EventArgs e)
    {


        SqlConnection databaseConnect = new SqlConnection("Data Source=GAURAV-PC;Initial Catalog=SocietyAccountingDatabase;Integrated Security=True");

        databaseConnect.Open();

    }
    private void textBox1_TextChanged(object sender, EventArgs e)
    {

    }

    private void label2_Click(object sender, EventArgs e)
    {

    }

    private void textBox1_TextChanged_1(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        string queryString = "select UserId,UserPassword from UserAccounts where UserId='gaurav' AND  UserPassword='test123'";
        SqlConnection databaseConnect = new SqlConnection();
        databaseConnect.ConnectionString = "Data Source=GAURAV-PC;Initial Catalog=SocietyAccountingDatabase;Integrated Security=True";
        databaseConnect.Open();
        string userName = UserNameTextBox.Text;
        string Password = PasswordTextBox.Text;
        SqlCommand SqlCommandObject = new SqlCommand("select UserId,UserPassword from UserAccounts where UserId='"+userName+"' AND  UserPassword='"+Password+"'");
        SqlDataAdapter DataAdapterObject = new SqlDataAdapter(SqlCommandObject);
        DataTable DataTableObject = new DataTable();
        DataAdapterObject.Fill(DataTableObject);



        if (DataTableObject.Rows.Count > 0)
        {
            MessageBox.Show("Login Sucessful");
            AdminConsoleForm AdminConsole= new AdminConsoleForm();
            this.Hide();
            AdminConsole.Show();

        }
        else
        {
            MessageBox.Show("Invalid Login Name And Password Please Try Again!");

        }

        databaseConnect.Close();




        //AdminConsoleForm AdminConsole= new AdminConsoleForm();
        //this.Hide();
        //AdminConsole.Show();





    }
}
}

任何人都可以帮忙吗?

3 个答案:

答案 0 :(得分:0)

只要有可能,您就应该using数据库连接。

using(var connection = new SqlConnection(connectionString))
{
    connection.Open();
    //...
}

目前,您在使用连接字段的各种方法中随机创建连接时,这非常令人困惑。

您不应该连接SQL并且应该使用参数化查询

using(var connection= new SqlConnection(connectionString))
{
    connection.Open();

    var sql = @"SELECT password FROM users WHERE userid = @userid";

    var command = new SqlCommand(sql, connection);
    command.Parameters.Add("@userid", SqlDbType.VarChar);
    command.Parameters["@userid"].Value = username;

    // ....
}

密码永远不应该以明文形式存储,您不应该“直接”查询密码。保护密码的一种简单方法是使用随机盐散列密码,将盐与散列一起存储在数据库中。

你真的不需要DataTable你应该只返回一行,而DataReader就足够了。

using(var connection= new SqlConnection(connectionString))
{
    connection.Open();

    var sql = @"SELECT password, salt FROM users WHERE userid = @userid";

    var command = new SqlCommand(sql, connection);
    command.Parameters.Add("@userid", SqlDbType.VarChar);
    command.Parameters["@userid"].Value = username;

    using(var reader = command.ExecuteReader())
    {
        if (reader.Read())
        {
            var password = reader.GetString(0);
            var salt = reader.GetString(1);

            return CheckPassword(password, salt, PwrdTextBox.Text);
        }

        Debug.WriteLine("The user {0} does not exist", username);
        return false;
    }
}

我建议您阅读CodeProject上的这篇文章Salted Password Hashing - Doing it Right

答案 1 :(得分:0)

首先,作为表单加载,您已经实例化了一个连接字符串并立即打开它。   其次,当用户单击按钮进行登录时,您已实例化相同的连接字符串并再次打开它,这使操作变得多余。因为该数据库的连接状态已经打开,您在按钮单击期间再次尝试打开,这使得操作无法进行或无法处理。

答案 2 :(得分:0)

登录表单的简单代码:

namespace Society_Accounting_Software
{
public partial class LoginScreen : Form
{
    SqlConnection databaseConnect = new SqlConnection();


    public LoginScreen()
    {
        SqlConnection databaseConnect = new SqlConnection();
        databaseConnect.ConnectionString = "Data Source=GAURAV-PC;Initial Catalog=SocietyAccountingDatabase;Integrated Security=True";
        InitializeComponent();

    }

    private void label1_Click(object sender, EventArgs e)
    {

    }

    private void Form1_Load(object sender, EventArgs e)
    {


    }
    private void textBox1_TextChanged(object sender, EventArgs e)
    {

    }

    private void label2_Click(object sender, EventArgs e)
    {

    }

    private void textBox1_TextChanged_1(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)

    {

        try

        {

            if (!(UserNameTextBox.Text == string.Empty))

            {

                if (!(PasswordTextBox.Text== string.Empty))

                {

                   //this represent your connection to database
                    String str = "Data Source=GAURAV-PC;Initial Catalog=SocietyAccountingDatabase;Integrated Security=True";

                    String query = "select * from UserAccounts where userid = '"+UserNameTextBox.Text+"'and password = '"+this.PasswordTextBox.Text+"'";

                    SqlConnection con = new SqlConnection(str);

                    SqlCommand cmd = new SqlCommand(query, con);

                    SqlDataReader dbr;

                    con.Open();

                    dbr = cmd.ExecuteReader();

                    int count = 0;

                    while (dbr.Read())

                    {

                        count = count + 1;

                    }

                    con.Close();

                    if (count == 1)

                    {
                        AdminConsoleForm objmain = new AdminConsoleForm();
                        objmain.Show(); //after login Redirect to second window  
                        this.Hide();//after login hide the  Login window   

                    }

                    else if (count > 1)

                    {

                        MessageBox.Show("Duplicate username and password", "login page");

                    }

                    else

                    {

                        MessageBox.Show(" Username and Password Incorrect", "login page");

                    }

                }

                else

                {

                    MessageBox.Show(" Password Empty", "login page");

                }


            }
            else

            {

                MessageBox.Show(" Username Empty", "login page");

            }




        }

        catch (Exception es)

        {

            MessageBox.Show(es.Message);
        }

    }
}

我保持代码非常简单。如果你想要安全,你可以做盐腌。