C# 这个C登录表单逻辑有什么问题?

C# 这个C登录表单逻辑有什么问题?,c#,sql-server,logic,C#,Sql Server,Logic,我在构建c登录系统时遇到了一个问题,首先我有一个数据库表,其中包含以下列:- UserName(nvarchar(255)), Password(nvarchar(255)), Admin(nvarchar(255)) 以下是存储在表中的信息:- admin, 123, true user, 123, false 我制作了一个名为AuthenticateUsers的c方法来处理SQL Server中的登录存储过程,它工作正常 这是:- public static DataTable Aut

我在构建c登录系统时遇到了一个问题,首先我有一个数据库表,其中包含以下列:-

UserName(nvarchar(255)), 
Password(nvarchar(255)),
Admin(nvarchar(255))
以下是存储在表中的信息:-

admin, 123, true
user, 123, false
我制作了一个名为AuthenticateUsers的c方法来处理SQL Server中的登录存储过程,它工作正常

这是:-

public static DataTable AuthenticateUsers()
        {
            DataTable DT = new DataTable();
            string SqlConnStr = globals.ServerConnStr;
            SqlConnection SqlConn = new SqlConnection(SqlConnStr);
            try
            {
                SqlConn.Open();

                SqlCommand cmd = new SqlCommand("AuthenticateUsers", SqlConn);

                cmd.CommandType = CommandType.StoredProcedure;


                SqlDataAdapter Adpt = new SqlDataAdapter(cmd);
                Adpt.Fill(DT);
                SqlConn.Close();

            }
            finally
            {
                SqlConn.Close();
            }
            return DT;
        }
以下是存储过程:-

ALTER PROCEDURE [dbo].[AuthenticateUsers]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    SELECT * FROM Login
END
以下是登录Windows窗体代码:

private void button1_Click(object sender, EventArgs e)
{
    DataTable dt = GlobalClasses.Data.AuthenticateUsers();
    DataRow dr = dt.Rows[0];
    try
    {
        if (dr["UserName"].ToString() == UsernameTxtBox.Text 
         && dr["Password"].ToString() == PasswordTxtBox.Text 
         && dr["Admin"].ToString() == "true")
        {
            MessageBox.Show("Hello Admin");
        }
        else if (dr["UserName"].ToString() == UsernameTxtBox.Text 
              && dr["Password"].ToString() == PasswordTxtBox.Text 
              && dr["Admin"].ToString() == "false")
        {
            MessageBox.Show("Hello Normal User");
        }
        else
        {
            MessageBox.Show("Get Away");
        }
    }
}
问题是第一个和最后一个if语句工作正常,但是第二个if语句根本不工作,我做了一个断点,它只是从if语句2跳到if语句3的消息框


有什么问题吗?

我认为第二个if在所有3种情况下都不成立

我建议您观察每个条件的布尔答案


您还可以在开始时设置3个布尔变量,然后查看从每个条件中得到的布尔答案。

您得到的是所有行,但只检查查询的第一行

dt.Rows[0]
由于您的第一行是:

admin, 123, true
这种情况:

dr[Admin].ToString==false

这总是错误的。如果要验证用户身份,应仅从数据库中获取管理员身份的用户:

SELECT * FROM Login where Admin = true
假设数据库中只有一个管理员,否则您应该更改逻辑并遍历行或使用常规查询而不是存储过程

private void button1_Click(object sender, EventArgs e)
{
    DataTable dt = GlobalClasses.Data.AuthenticateUsers();
    try
    {
        for(var i=0; i < dt.Rows.Count ; i++){
            var dr = dt.Rows[i]; 
            if (dr["UserName"].ToString() == UsernameTxtBox.Text 
            && dr["Password"].ToString() == PasswordTxtBox.Text ){
                if (dr["Admin"].ToString() == "true"){
                    MessageBox.Show("Hello Admin");
                } 
                else 
                {
                    MessageBox.Show("Hello Normal User");
                }
            } 
            else 
            {
                MessageBox.Show("Get Away");
            }
        }             
    }
}

无意冒犯,但真正的答案是一切

表中的所有内容都使用nvarchar255列。 用户名很少超过15个字符,密码通常在4到6个字符之间。您可以安全地使用nvarchar20作为用户名和密码,使用位列作为管理员。 你的列名不好。用户名、密码和管理员是大多数数据库中的保留字。我的建议是使用表名作为列名的前缀:Login\u UserName、Login\u Password、Login\u Admin。 您正在将密码以纯文本形式保存在数据库中。密码只能加密保存。 您正在使用存储过程将表中的所有数据选择回c代码。您应该做的是将用户的输入作为参数传递给存储过程,并只将所需的数据返回给c程序。 正确的存储过程看起来更像这样:

ALTER PROCEDURE [dbo].[AuthenticateUsers]
(
    @UserName nvarchar(255),
    @Password nvarchar(255)
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SELECT Admin 
FROM Login
WHERE UserName = @UserName
AND Password = @Password

END

这与您当前的表一致

当您使用调试器时,能否告诉我们用户名、密码和管理员行列的内容?打印调试Dt值please@Steve是的,Username的值是user,Password是123,但Admin没有显示值,相反,它是Class.System.string作为旁注,我不确定,因为我看不到AuthenticateUsers方法中发生了什么,但您的代码似乎在数据库中以明文形式存储密码。从安全角度来看,这是一个非常糟糕的做法,因此问题不在这里,而是在无法正确识别Admin列类型的AuthenticateUsers和sub方法中如何检查dt中的所有列。行[0]只是迭代:forvar i=0;i