使用Linq Select语句帮助 - 使用FirstOrDefault后的NullReferenceException

时间:2014-11-27 04:33:05

标签: c# linq

我有一个处理Login进程的LINQ语句。传递有效的用户名和密码组合时,它工作正常。但是,当我测试无效凭据时,我在下面的行上显示NullReferenceException错误<<<<" ----------------需要一些正确的帮助处理无效凭证好吗?

public int _accountID;
public int _securityLevelID;
public void GetLoginInfo(string EmailAddress, string Password)
{
    LoginItem l = null;

    {
        try
        {
            using (RootsDataContext RDC = new RootsDataContext())

                l = (from a in RDC.DBLogIns
                     where a.EmailAddress == EmailAddress
                     && a.Password == Password
                     && a.IsActive == 1

                     select new LoginItem
                     {
                         AccountIDFK = a.AccountIDFK,
                         SecurityLevelIDFK = a.SecurtityLevelIDFK,

                     }).FirstOrDefault();

            _accountID = (int)l.AccountIDFK;      <<<---------------- 
            _securityLevelID = (int)l.SecurityLevelIDFK;

            if (_accountID < 1 || _accountID == null)
            {
                lbl_LoginStatus.Text = "Invalid";
            }

        }


        catch (Exception ex)
        {
            string error = ex.Message;
        }


        if (_accountID > 0)
        {
            if (_accountID == 1 && _securityLevelID == 1) // [Quentin]   
            {
                Response.Redirect("~/AccountsMaster.aspx");
            }

            if (_accountID > 1 && _securityLevelID == 2) // [Companies]    
            {
                Response.Redirect("~/CompanyMaster.aspx");
            }

            if (_accountID > 1 && _securityLevelID == 3) // [Branch]
            {
                Response.Redirect("~/BranchMaster.Aspx");
            }

            if (_accountID > 1 && _securityLevelID == 4) // [Clients]   
            {
                Response.Redirect("~/Home.aspx");
            }
        }
    }
}    

5 个答案:

答案 0 :(得分:2)

  // ... 
  }).FirstOrDefault();

如果找到匹配,您将获得DBLogIn个对象,如果不匹配,您将获得null

在访问属性AccountIDFKSecurityLevelIDFK之前,您需要检查null:

// ... }).FirstOrDefault();
if (l != null)
{
    _accountID = (int)l.AccountIDFK;
    _securityLevelID = (int)l.SecurityLevelIDFK;
}

其他一些要考虑的要点:

  • 您不应该在数据库中store passwords directly。更安全的方法是在数据库中存储散列(并且可能是盐渍的)密码,然后找到用户(通过EmailAddress and Active = 1),然后比较用户输入的内容的哈希值以及存储在DB。
  • 此代码swallows exceptions - 这使得诊断问题成为一场噩梦:

    catch (Exception ex)
    {
        string error = ex.Message;
    }
    
  • Don't make fields publicpublic int _accountID;) - 如果不在外部使用,请将其设为私有,如果从您的班级外部可见,则将其转换为(自动生成)属性。

答案 1 :(得分:1)

如果没有DBLogIn条记录符合您给出的条件,

FirstOrDefault方法将返回null,因此您需要先检查l是否为空,然后再访问(int)l.AccountIDFK。此外,当lbl_LoginStatus.Text = "Invalid";为空时,l看起来应该是if (_accountID < 1 || _accountID == null),因此您需要删除if (l != null) { _accountID = (int)l.AccountIDFK; _securityLevelID = (int)l.SecurityLevelIDFK; } else { // logic when l is null lbl_LoginStatus.Text = "Invalid"; } 块并更改代码,如下所示:

l

或者,您也可以使用C# Ternary Operator检查_accountID = l != null ? (int)l.AccountIDFK : 0; _securityLevelID = l != null ? (int)l.SecurityLevelIDFK : 0; if (_accountID < 1) { lbl_LoginStatus.Text = "Invalid"; } 是否为空

{{1}}

答案 2 :(得分:0)

在使用之前,您应该在'l'中检查空值。

if(l!=null)
{
_accountID = (int)l.AccountIDFK;    
            _securityLevelID = (int)l.SecurityLevelIDFK;
}
else
{
 lbl_LoginStatus.Text = "Invalid";
}

答案 3 :(得分:0)

如果列表中没有与您的查询匹配的项目,则Linq FirstOrDefault返回null。如果您的代码中出现null,则意味着用户登录无效。

 public int _accountID;
    public int _securityLevelID;
    public void GetLoginInfo(string EmailAddress, string Password)
    {
        LoginItem l = null;

        {
            try
            {
                using (RootsDataContext RDC = new RootsDataContext())

                    l = (from a in RDC.DBLogIns
                         where a.EmailAddress == EmailAddress
                         && a.Password == Password
                         && a.IsActive == 1

                         select new LoginItem
                         {
                             AccountIDFK = a.AccountIDFK,
                             SecurityLevelIDFK = a.SecurtityLevelIDFK,

                         }).FirstOrDefault();
              if(l==null || _accountID < 1 || _accountID == null)
              {
                 lbl_LoginStatus.Text = "Invalid";
                Response.Redirect("~/InvalidCredentials.aspx"); // redirect to invalid login page.
              }
              else
              {
               _accountID = (int)l.AccountIDFK;
                _securityLevelID = (int)l.SecurityLevelIDFK;

              }
            }


            catch (Exception ex)
            {
                string error = ex.Message;
            }


            if (_accountID > 0)
            {
                if (_accountID == 1 && _securityLevelID == 1) // [Quentin]   
                {
                    Response.Redirect("~/AccountsMaster.aspx");
                }

                if (_accountID > 1 && _securityLevelID == 2) // [Companies]    
                {
                    Response.Redirect("~/CompanyMaster.aspx");
                }

                if (_accountID > 1 && _securityLevelID == 3) // [Branch]
                {
                    Response.Redirect("~/BranchMaster.Aspx");
                }

                if (_accountID > 1 && _securityLevelID == 4) // [Clients]   
                {
                    Response.Redirect("~/Home.aspx");
                }

            }


        }

    }    

答案 4 :(得分:0)

您应检查LoginItem的默认值null,如果其为空(如果凭据无效),则执行您想要的操作。