Asp.net 登录页面上的IndexAutoFrangeException

Asp.net 登录页面上的IndexAutoFrangeException,asp.net,sql-server,validation,login,Asp.net,Sql Server,Validation,Login,我有一个登录页面,其中它使用用户的电子邮件地址和密码登录用户。下面是验证用户的存储过程,然后从tblAllUser发出“UserId”和“Role” Alter proc spValidateUser @EmailAdd nvarchar(30), @Password nvarchar(20) as begin Set Nocount on; Declare @UserId nvarchar(10),@LastLogin da

我有一个登录页面,其中它使用用户的电子邮件地址和密码登录用户。下面是验证用户的存储过程,然后从tblAllUser发出“UserId”和“Role”

     Alter proc spValidateUser
     @EmailAdd nvarchar(30),
     @Password nvarchar(20)
     as
     begin
     Set Nocount on;
     Declare @UserId nvarchar(10),@LastLogin datetime,@RoleId int

     Select @UserId = UserId, @LastLogin=LastLogin, @RoleId=RoleId
     from tblAllUsers where EmailAdd=@EmailAdd and Password=@Password

     If @UserId is not null
     Begin
     Update tblAllUsers
     SET LastLogin= GETDATE()
     WHERE UserId=@UserId
     Select @UserId [UserId],
     (Select Role from tblRoles where RoleId=@RoleId) [Roles]
     End
     Else
     Begin
     Select -1
     End
     End
我已经测试了上述过程,它工作正常,并根据需要提供用户ID和角色。问题是当我单击我抛出的登录按钮和异常索引时。以下是代码:

  protected void LoginControl_Authenticate(object sender, EventArgs e)
{
    string userId = string.Empty;
    string roles = string.Empty;
    string CS = ConfigurationManager.ConnectionStrings["SportsActiveConnectionString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(CS))
    {
        using (SqlCommand cmd = new SqlCommand("spValidateUser"))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@EmailAdd", Login1.UserName);
            cmd.Parameters.AddWithValue("@Password", Login1.Password);
            cmd.Connection = con;
            con.Open();
            SqlDataReader reader = cmd.ExecuteReader();
            reader.Read();
            userId = reader["UserId"].ToString();
            roles = reader["Roles"].ToString();
            con.Close();
        }
        switch (userId)
        {
            case "-1":
                Login1.FailureText = "Username and/or password is incorrect.";
                break;
            default:
                FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), Login1.RememberMeSet, roles, FormsAuthentication.FormsCookiePath);
                string hash = FormsAuthentication.Encrypt(ticket);
                HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);

                if (ticket.IsPersistent)
                {
                    cookie.Expires = ticket.Expiration;
                }
                Response.Cookies.Add(cookie);
                Response.Redirect(FormsAuthentication.GetRedirectUrl(Login1.UserName, Login1.RememberMeSet));
                break;
        }
    }
}
异常被抛出

   userId = reader["UserId"].ToString();

任何帮助都将不胜感激。

无论您是指定有效的用户名/密码组合,还是仅当登录无效时,是否会引发异常?因为在后一种情况下,存储过程生成的结果集不包括名为
UserId
的列(或者称为
Roles
)。在登录失败的情况下,最好不要生成结果集,然后通过检查
reader.Read()
的返回值进行测试。此外,尽管您尚未共享所有相关代码,但我担心您是否安全地存储密码。如果它们以明文形式存在于数据库中,请查看一些答案。是的,即使用户无效,我也必须给出列。问题是存储过程只给出了-1,并且没有与列UserId关联。这就解决了问题。@JoeFarrellIs无论您指定的用户名/密码组合是否有效,还是仅当登录无效时,都会引发异常?因为在后一种情况下,存储过程生成的结果集不包括名为
UserId
的列(或者称为
Roles
)。在登录失败的情况下,最好不要生成结果集,然后通过检查
reader.Read()
的返回值进行测试。此外,尽管您尚未共享所有相关代码,但我担心您是否安全地存储密码。如果它们以明文形式存在于数据库中,请查看的一些答案。是的,即使用户无效,我也必须给出列。问题是存储过程只给出了-1,并且与列UserId没有关联。这就解决了问题。@JoeFarrell