C# SQL Server验证返回错误的输出
我正在使用SQL server在本地服务器上进行登录页面验证。我创建了一个登录页面和注册页面,我的注册页面工作正常,但登录页面一直显示用户未激活的错误 这是我登录页面的代码C# SQL Server验证返回错误的输出,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我正在使用SQL server在本地服务器上进行登录页面验证。我创建了一个登录页面和注册页面,我的注册页面工作正常,但登录页面一直显示用户未激活的错误 这是我登录页面的代码 public partial class Login : System.Web.UI.Page { protected void Validate_User(object sender, EventArgs e) { int userId = 0
public partial class Login : System.Web.UI.Page
{
protected void Validate_User(object sender, EventArgs e)
{
int userId = 0;
string constr = `ConfigurationManager.ConnectionStrings["constr"].ConnectionString;`
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Validate_User"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Username", Login1.UserName);
cmd.Parameters.AddWithValue("@Password", Login1.Password);
cmd.Connection = con;
con.Open();
userId = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
}
switch (userId)
{
case -1:
Login1.FailureText = "Username and/or password is incorrect.";
break;
case -2:
Login1.FailureText = "Account has not been activated.";
break;
default:
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
break;
}
}
}
}
下面是验证用户的过程
CREATE PROCEDURE [dbo].[Validate_User]
@Username NCHAR(50),
@Password VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @UserId INT, @LastLoginDate DATETIME
SELECT @UserId = UserId, @LastLoginDate = LastLoginDate
FROM NervSuiteUsers
WHERE Username = @UserName AND [Password] = @Password
IF @UserId IS NOT NULL
BEGIN
IF NOT EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName)
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserName [UserName] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
END
ELSE
BEGIN
SELECT -1 -- User invalid.
END
END
问题是,即使数据库中有一个用户,我仍然得到未验证的帐户您的SP对我做出了矛盾的陈述。只有当用户名/密码匹配时,下面的查询才会给出结果
SELECT @UserId = UserId, @LastLoginDate = LastLoginDate
FROM NervSuiteUsers
WHERE Username = @UserName AND [Password] = @Password
那么下面的这个查询就没有意义了
IF @UserId IS NOT NULL // will be true when both username/password matches
BEGIN
IF NOT EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName) // Why this???? This will not be TRUE
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
因此,您的else块将得到评估,您将得到发布的结果
ELSE
BEGIN
SELECT -2 -- User not activated.
END
你的SP对我的陈述自相矛盾。只有当用户名/密码匹配时,下面的查询才会给出结果
SELECT @UserId = UserId, @LastLoginDate = LastLoginDate
FROM NervSuiteUsers
WHERE Username = @UserName AND [Password] = @Password
那么下面的这个查询就没有意义了
IF @UserId IS NOT NULL // will be true when both username/password matches
BEGIN
IF NOT EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName) // Why this???? This will not be TRUE
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
因此,您的else块将得到评估,您将得到发布的结果
ELSE
BEGIN
SELECT -2 -- User not activated.
END
除了您在关于实现问题的评论中得到的所有反馈之外,您还对以下几行查询有意见
IF NOT EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName)
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserName [UserName] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
它不应该不存在。它应该是存在的,因为@UserId NOT NULL意味着它存在于表中,请按如下方式更改查询
IF EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName)
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserName [UserName] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
除了您在关于实现问题的评论中得到的所有反馈之外,您还对以下几行查询有意见
IF NOT EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName)
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserName [UserName] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
它不应该不存在。它应该是存在的,因为@UserId NOT NULL意味着它存在于表中,请按如下方式更改查询
IF EXISTS(SELECT UserId FROM NervSuiteUsers WHERE Username = @UserName)
BEGIN
UPDATE NervSuiteUsers
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserName [UserName] -- User Valid
END
ELSE
BEGIN
SELECT -2 -- User not activated.
END
除了已经讨论过的SP中的小故障外,.NET代码中还存在与结果是整数失败还是字符串成功相关的问题。解决这个问题的一个实用方法是始终返回相同的类型。由于用户传入用户名,因此再次传出用户名不一定有什么意义,除非您的目的是自动更正不区分大小写的字符串,但一个简单的修复方法是在成功案例中只选择1或其他哨兵值,而不是选择@username 但是,在现有代码中也可以解决相同的问题,只需测试以下值:
object sqlResult = cmd.ExecuteScalar();
switch (sqlResult)
{
case int i when i == -1:
// TODO ...
break;
case int i when i == -2:
// TODO ...
break;
case string s:
// success, and the value was s
// TODO...
break;
default:
// I HAVE NO CLUE
throw new SomeSensibleException(...);
}
注意:这使用了新的C语言语法功能,但如果使用低级C,同样的基本方法也可以通过以下方式手动完成:
if (sqlResult is int)
{
switch ((int)sqlResult)
{
// ...
}
}
else if (sqlResult is string)
{
string s = (string)sqlResult;
// ...
}
除了已经讨论过的SP中的小故障外,.NET代码中还存在与结果是整数失败还是字符串成功相关的问题。解决这个问题的一个实用方法是始终返回相同的类型。由于用户传入用户名,因此再次传出用户名不一定有什么意义,除非您的目的是自动更正不区分大小写的字符串,但一个简单的修复方法是在成功案例中只选择1或其他哨兵值,而不是选择@username 但是,在现有代码中也可以解决相同的问题,只需测试以下值:
object sqlResult = cmd.ExecuteScalar();
switch (sqlResult)
{
case int i when i == -1:
// TODO ...
break;
case int i when i == -2:
// TODO ...
break;
case string s:
// success, and the value was s
// TODO...
break;
default:
// I HAVE NO CLUE
throw new SomeSensibleException(...);
}
注意:这使用了新的C语言语法功能,但如果使用低级C,同样的基本方法也可以通过以下方式手动完成:
if (sqlResult is int)
{
switch ((int)sqlResult)
{
// ...
}
}
else if (sqlResult is string)
{
string s = (string)sqlResult;
// ...
}
我个人不使用SELECT,而是在这里使用输出参数。这说明了如何使用它们。真正严重的问题是,您似乎正在以纯文本形式存储和传输密码。在你认真阅读散列和盐类之前,停止这一点。你为什么不使用ASP.NET自己的授权机制呢?存储密码,即使是加密的,也是一个非常糟糕的主意。这一行:[密码]=@密码应该出现在每个面试问题中。认真地仍然有人这样做,他们不仅在他们的系统中制造漏洞,而且还真的将私人信息转储给第三方……如果我们忽略已经讨论过的纯文本密码问题,它看起来应该可以正常工作。所以要做的第一件事是隔离尝试SP,例如通过SSM。如果SP不工作:请修复该问题。如果SP在SSMS中工作正常,那么您需要查看ExecuteScalar之后的用户ID。在这些情况下是什么?作为旁注,根据逻辑流在integer和nvarchar的位置返回不同的类型是非常有问题的——我个人会避免这样做。我希望convert抛出异常,因为它在正常情况下不是整数。我个人不使用SELECT,而是在这里使用输出参数。这说明了如何使用它们。真正严重的问题是,您似乎正在以纯文本形式存储和传输密码。在你认真阅读散列和盐类之前,停止这一点。你为什么不使用ASP.NET自己的授权机制呢?存储密码,即使是加密的,也是一个非常糟糕的主意。这一行:[密码]=@密码应该出现在每个面试问题中。认真地仍然有人这样做,他们不仅在他们的系统中制造了漏洞,而且还真的将私人信息转储给第三方……如果我们忽略了
纯文本密码问题已经讨论过了,看起来应该可以正常工作。所以要做的第一件事是隔离尝试SP,例如通过SSM。如果SP不工作:请修复该问题。如果SP在SSMS中工作正常,那么您需要查看ExecuteScalar之后的用户ID。在这些情况下是什么?作为旁注,根据逻辑流在integer和nvarchar的位置返回不同的类型是非常有问题的——我个人会避免这样做。我希望转换会抛出一个异常,因为它在正常情况下不是整数。这是可行的,我已经这样做了,但仍然得到了相同的结果。显然,在运行之前我没有更新脚本和过程,因此我再次出现了错误。对不起,我无法理解您。你能解释一下更改后出现了什么问题吗?没有问题,我的意思是我更改了代码以删除先前语句中的NOT,但仍然有相同的先前错误,因为我没有更新脚本。现在很好用了。这很有效,我已经做了,但还是得到了同样的结果。显然,在运行之前我没有更新脚本和过程,因此我再次出现了错误。对不起,我无法理解您。你能解释一下更改后出现了什么问题吗?没有问题,我的意思是我更改了代码以删除先前语句中的NOT,但仍然有相同的先前错误,因为我没有更新脚本。现在很好用。