C# ';其他';if/else在应该执行时不执行#
我正在用C#设计一个ATM系统,对于登录功能,我使用SQL server数据库将输入的卡号和PIN与数据库中的卡号和PIN进行比较。当输入正确的卡号和PIN码时,一切正常,但当输入的值不正确时,一切都不会发生,我一直在努力找出答案。有人知道它可能是什么吗?连我的大学讲师都不知道C# ';其他';if/else在应该执行时不执行#,c#,sql,C#,Sql,我正在用C#设计一个ATM系统,对于登录功能,我使用SQL server数据库将输入的卡号和PIN与数据库中的卡号和PIN进行比较。当输入正确的卡号和PIN码时,一切正常,但当输入的值不正确时,一切都不会发生,我一直在努力找出答案。有人知道它可能是什么吗?连我的大学讲师都不知道 //Select all fields from the table 'ATMCards' using the connection previously created and use the SqlDataReade
//Select all fields from the table 'ATMCards' using the connection previously created and use the SqlDataReader to read the values
为了简化它,我刚刚将messagebox.show放在了else中,因为我想做的就是至少触发它
SqlCommand cmd = new SqlCommand("SELECT * FROM [ATMCards] WHERE (cardNumber = @cardNumber) AND (PIN = @PIN)", cn);
cmd.Parameters.AddWithValue("@cardNumber", cboxSimCard.Text);
cmd.Parameters.AddWithValue("@PIN", txtboxPIN.Text);
cmd.Connection = cn;
SqlDataReader r = null;
r = cmd.ExecuteReader();
//While the reader is in execution:
while (r.Read())
{
//ADD IF NOT CONFISCATED DO THIS:
if (((Boolean)(r["confiscated"]) == notConfiscated))
{
string cNum = r["cardNumber"].ToString();
string pin = r["PIN"].ToString();
//Compare the results in the ATMCards table against those on the form used to log in
if (string.Equals(cNum,cboxSimCard.Text) && string.Equals(pin,txtboxPIN.Text))
{
MessageBox.Show("Card number "+cNum+" PIN "+pin);
//If the login details are correct then grant access to the menu screen by creating a new instance of it and hide the login form. Clear PIN to avoid the next user accessing the account
MessageBox.Show("Open form all is good");
txtboxPIN.Clear();
Form myNewForm = new Menu();
myNewForm.Show();
this.Hide();
break;
}
else
{
MessageBox.Show("Here");
}
如果输入了错误的卡号和pin对,则不会从数据库返回任何行,因此
while(r.Read())
会立即返回false。如果中的条件不匹配,则返回的结果集不会有行。第一个r.Read
返回false,而循环的内容永远不会执行
作为注释,如果您调试代码,这将是显而易见的
除了简单的答案
您不应该像这样执行SQL。它让你容易受到注射攻击。您可以使用Linq访问实体,或者在调用sp\u ExecuteSQL
时封装SQL
PIN不应存储为纯文本,而应存储为PIN和其他卡详细信息的安全散列
卡号不应以纯文本形式存储。如果你从来没有读过卡号,它可能会被散列。否则加密
我假设您正在验证卡的详细信息,在将查询传递到数据库之前使用modulo-13或一些行业标准检查
我并不是说你可以重现ATM机内实际发生的事情,但是,对敏感数据所需的安全性的一些点头肯定会产生额外的信用。(双关语不是故意的)伙计,你的代码是
不安全,可能会被注射
信用卡和pin必须加密,而你没有
在失败的情况下,您的代码将永远不会显示任何消息,因为如果没有重新聚合数据,while中的if子句将不会执行
你可以用
if(reader.HasRows)
///then do happy case
else
//show error message
在我看来,这似乎是:
if (string.Equals(cNum,cboxSimCard.Text) && string.Equals(pin,txtboxPIN.Text))
有什么不对劲吗。尝试使用与相同函数的重载。像这样
if (cNum.Equals(cboxSimCard.Text, StringComparison.InvariantCultureIgnoreCase) && pin.Equals(txtboxPIN.Text, StringComparison.InvariantCultureIgnoreCase))
你肯定r[“没收”]!=您应该(学习)在这里使用调试器。我希望这台ATM机是学习任务,而不是商业产品。例如,纯文本PIN?我在键入:-)@Moo Juice啊,我明白了,那么我应该将错误卡号和PIN对的代码放在哪里?在while(r.Read())循环之外?@TomCrook,是的,您可以在while循环之前检查if(r.HasRows)
,例如。@TomCrook我认为两行也是一个exception@Moo-Juice我已经实现了if(r.HasRows),它工作得非常好。如果你在这里,我会给你一个吻,不管我花了多长时间。谢谢我认为我们不应该期望在世界级的安全级别上执行一项基本的大学作业……啊,我明白了,那么我应该把错误的卡号和pin码放在哪里呢?在while(r.Read())循环之外?嗯,我认为您只需要一行,少或多都是例外。我将首先处理读取,以便在处理数据之前检查异常情况。@Tom Crook,可以将没收的支票放在where子句中,除非您想记录没收卡的使用情况。不,我不想记录没收卡的使用情况,只需阻止用户使用没收卡即可。