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