Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 登录页面中遇到问题3-轮胎架构_C#_Database Connection_3 Tier - Fatal编程技术网

C# 登录页面中遇到问题3-轮胎架构

C# 登录页面中遇到问题3-轮胎架构,c#,database-connection,3-tier,C#,Database Connection,3 Tier,业务接入层: public static int login(string userlogin, string pwdlogin) { SqlConnection con = new SqlConnection(); con.ConnectionString = GetConnectionString(); con.Open(); int id = 0; string selectstr = "SEL

业务接入层:

    public static int login(string userlogin, string pwdlogin)
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = GetConnectionString();
        con.Open();
        int id = 0;
        string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = selectstr;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Connection = con;
        id = cmd.ExecuteNonQuery();
        cmd = null;
        con.Close();
        return id;
    }
Login.cs

 protected void Button1_Click(object sender, EventArgs e)
    {
        int id = BusinessAccessLayer.login(userlogin.Text.Trim(), pwdlogin.Text.Trim());
        if (id > 0)
        {
            message.Text = " valid";
        }
        else
        {
            message.Text = "in valid";
        }   
    }

如果需要结果,则不能使用.ExecuteOnQuery。使用.ExecuteReader

public static int login(string userlogin, string pwdlogin)
{
    SqlConnection con = new SqlConnection();
    con.ConnectionString = GetConnectionString();
    con.Open();
    int id = 0;
    string selectstr = "SELECT UserId FROM Registration WHERE UserName = '" +    userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = selectstr;
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.Connection = con;

    SqlDataReader reader = cmd.ExecuteReader();
    reader.Read();
    id = reader.GetInt32("UserId");

    reader.Close();
    con.Close();

    return id;
}

好吧,这里有很多错误:

1) 您应该使用
using
语句来确保即使抛出异常也关闭连接和命令

2) 应该使用参数化SQL,而不是将值直接放入SQL语句中,以避免SQL注入攻击

3) 您似乎正在以纯文本形式存储密码不要这样做。使用盐哈希或类似的方法(最好是计算速度较慢的方法)

4) 您忽略了.NET命名约定;方法应使用PascalCase

5) 您的SQL从不查看任何似乎与用户ID相关的字段。不清楚您希望
ExecuteNonQuery
返回什么,但如果您想要实际ID,则需要在SQL中引用它。(即使最初您只想知道用户的密码是否有效,但我强烈怀疑在某个时候您会想使用真实的用户ID,因此您应该让您的代码返回它。如果您真的只想知道密码是否有效,您应该将方法的返回类型更改为
bool

6) 当您的命令显然是查询时,您正在使用
ExecuteNonQuery
。要么使用,要么取而代之。(
ExecuteNonQuery
用于插入、删除和更新语句,并返回受命令影响的行数。)

比如:

public static int Login(string user, string password)
{
    using (var conn = new SqlConnection(GetConnectionString()))
    {
        conn.Open();
        string sql = "select Id, PasswordHash from logins where Username=@Username";
        using (var command = new SqlCommand(sql))
        {
            command.Parameters.Add("@Username", SqlDbType.NVarChar).Value = user;

            using (var reader = command.ExecuteRead())
            {
                if (reader.Read())
                {
                    int id = reader.GetInt32(0);
                    string hash = reader.GetString(1);
                    // TODO: Hash provided password with the same salt and compare
                    // results
                    if (CheckPassword(password, hash))
                    {
                        return id;
                    }
                }
                return 0; // Or use an int? return type and return null
            }
        }
    }
}
用于UPDATE、INSERT和DELETE语句。 对于SELECT语句,使用


你的问题是什么?你已经向我们展示了代码,但没有告诉我们出了什么问题。请阅读。(无可否认,我在浏览时可以看到四个重要问题,但我不知道这些问题是否与您看到的相关…)每次显示无效用户时,都会返回“使用给定用户名和密码的用户数”,而不是正确用户的ID。它也没有解决代码中其他任何可怕的问题。@JonSkeet:OP提供的if语句只是检查
id>0
与否……如果
id>0
那么它是有效的,所以我只需使用
id++
@IswantoSan编写代码:这就是他们目前正在做的事情-但是考虑到名称是
id
它显然是用户的ID,而不仅仅是一个布尔决策。我怀疑OP最初只是测试登录代码,稍后将使用实际的用户ID。@yash:您真的不想要用户ID吗?如果是这样,您不应该将其称为变量名
id
。让你的代码说出它的意思-如果你只是在寻找一个布尔结果,你应该声明返回
bool
的方法,而不是
int
@IswantoSan:好吧,SQL注入和他似乎在以纯文本存储密码的事实。(以及缺少使用语句的
)有关更多详细信息,请参阅我的答案。
public static int login(string userlogin, string pwdlogin)
{
        SqlConnection con = new SqlConnection();
        con.ConnectionString = GetConnectionString();
        con.Open();
        int id = 0;
        string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = selectstr;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Connection = con;
        SqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
               id++; 
        }
        cmd = null;
        reader.Close();
        con.Close();
        return id;
}