3

StackOverflowで質問するのは初めてなので、不適切な質問をしていたら、あらかじめお詫びします。過去数日間、これを調査している間、私を助けるものを見つけることができませんでしたので、助けようとする人に前もって感謝します.

人々が登録してログインできるようにするデータベースを作成しています。VS2012 で C# を使用しています。以下は私のログインコードで、テスト中に問題が発生しています。データベース内のすべての人を反復処理し、適切なユーザーに到達するまでログインが失敗したことを通知します。

    private void button1_Click_1(object sender, EventArgs e)
    {
        try
        {
            cn.Open();
        }
        catch (Exception)
        {
            MessageBox.Show("Did not connect");
        }


        SqlCommand cmd = new SqlCommand("SELECT * FROM [Users]", cn);
        cmd.Connection = cn;
        SqlDataReader reader = null;
        reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            if (textBox1.Text == (reader["Username"].ToString()) && textBox2.Text == (reader["Password"].ToString()))
            {
                MessageBox.Show("Logged in");
            }
            else
            {
                MessageBox.Show("Login has failed. Please check your Username and Password.");
            }
        }
        cn.Close();
    }

私の登録部分に関しては、それがVS2012のものなのかどうかはわかりませんが、デバッグを終了してから再びデバッグに戻ると、情報がデータベースに保存されません。

    private void button1_Click_1(object sender, EventArgs e)
    {
        cn.Open();
        SqlCommand cm1 = new SqlCommand("INSERT INTO Users (Username, Password) VALUES (@Username, @Password)", cn);
        SqlCommand cm2 = new SqlCommand("INSERT INTO Contact(Name, Address, City, State, PostalCode, Email, PhoneNumber) VALUES(@Name, @Address, @City, @State, @PostalCode, @Email, @PhoneNumber)", cn);



        cm1.Parameters.AddWithValue("@Username", textBox1.Text);
        cm1.Parameters.AddWithValue("@Password", textBox2.Text);
        cm2.Parameters.AddWithValue("@Name", textBox3);
        cm2.Parameters.AddWithValue("@Address", textBox4);
        cm2.Parameters.AddWithValue("@City", textBox5);
        cm2.Parameters.AddWithValue("@State", textBox6);
        cm2.Parameters.AddWithValue("@PostalCode", textBox7);
        cm2.Parameters.AddWithValue("@Email", textBox8);
        cm2.Parameters.AddWithValue("@PhoneNumber", textBox9);

        try
        {
            int affectedRows =  cm1.ExecuteNonQuery(); //+cm2.ExecuteNonQuery();

            if (affectedRows > 0)
            {
                MessageBox.Show("Insert Sucsess!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                MessageBox.Show("Insert Failed!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        cn.Close();
    }
4

2 に答える 2

4

プロジェクトにデータベース ファイルがあり、プロジェクトをビルドすると、データベース ファイルをルート プロジェクト フォルダーから出力 (bin\debug または bin\release) フォルダーにコピーできます。
この動作はCopy To Output Directory、データベース ファイルのプロパティによって制御されます。

このプロパティをCopy Alwaysthen に設定すると、プロジェクトをビルドするたびに、データベース ファイルの新しいコピーがルート プロジェクト フォルダーから出力ディレクトリにコピーされ、既存のディレクトリが上書きされ、以前のデバッグ セッションで行った変更が破棄されます。 .

推奨される修正は、このプロパティをCopy Neverまたはに変更することです。Copy if Newer

このページでMSDNの詳細な説明を参照してください

質問の最初の部分では、SQL テキストに WHERE 句を追加するすべてのユーザーをループすることを避けることができます。文字列連結を使用して SQL 文字列を作成しないでください。代わりに、ALWAYS パラメータを使用してください。(なぜですか?SQLインジェクションとテキストの一重引用符の解析/二重化を避けます)

string sqlText = "SELECT * FROM [Users] WHERE Username = @usr AND [Password] = @psw";
SqlCommand cmd = new SqlCommand(sqlText, cn);
cmd.Parameters.AddWithValue("@usr", textbox1.Text);
cmd.Parameters.AddWithValue("@psw", textbox2.Text);
SqlDataReader reader = cmd.ExecuteReader();
if(reader.HasRows)
    // You have found the user....

もう一つアドバイス。パスワードをクリア テキストでデータベース内に保存しないでください。常にこの文字列のハッシュを保存し、検索時にハッシュ値を計算して、クリア パスワードの代わりに検索します。

于 2012-12-04T23:46:12.443 に答える
2

これを機能させるにWHEREは、SELECT. ただし、使用はお勧めしません

SqlCommand cmd = new SqlCommand("SELECT * FROM [Users] WHERE Username='" + textBox1.Text + "'", cn);

SQL インジェクションの可能性があるためです。

ストアド プロシージャの使用方法とC# コードから実行する方法を学んでください。

于 2012-12-04T23:46:28.417 に答える