【问题标题】:How to handle System.InvalidOperationException in entity framework?如何在实体框架中处理 System.InvalidOperationException?
【发布时间】:2014-08-22 21:12:24
【问题描述】:

我是 asp.net Web API 的新手。我做了一个功能,应该验证前端发送数据的用户,然后我在数据库中搜索数据。但是当找不到帐户时,我总是遇到异常我应该如何处理该异常以发送到前端信息 当第一个 if 语句不正确时我应该返回什么,因为 null 不起作用。

public UserData ByPassword(string emailAddress, string password)
        {
            if (emailAddress != null && password != null)
            {
                    Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).Single();
                    string token = OurAuthorizationAttribute.CreateTicket(account.AccID, false);
                    UserData data = new UserData();
                    data.Id = account.AccID;
                    data.Token = token;
                    return data;

            }

她我也添加了 try 和 catch 块,但仍然是同样的问题。

public UserData ByPassword(string emailAddress, string password)
        {
            if (emailAddress != null && password != null)
            {
                try
                {
                    Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).Single();
                    string token = OurAuthorizationAttribute.CreateTicket(account.AccID, false);
                    UserData data = new UserData();
                    data.Id = account.AccID;
                    data.Token = token;
                    return data;
                }
                catch
                {
                    throw new OurException(OurExceptionType.InvalidCredentials);
                }
            }
             throw new OurException(OurExceptionType.InvalidCredentials);
        }

【问题讨论】:

  • 在数据库中找不到 emailAddress 或密码时触发
  • 不,它没有。您应该使用SingleOrDefault() 而不是Single(),然后如果数据不在数据库中,您将获得null。无论如何,天哪,我希望您不要在生产环境中进行这样的身份验证!使用 ASP.NET Identity (2.0) 有什么问题?它为您处理所有棘手的部分,并且也使用 EntityFramework 工作,因此在您的情况下很容易使用。
  • 谢谢 Luann 我会考虑你提到的身份验证。任何链接作为起点

标签: c# entity-framework asp.net-mvc-4 asp.net-web-api


【解决方案1】:

System.InvalidOperationException 表示编程错误。您可以通过修复代码来处理它。

在这种特殊情况下,错误出现在这一行:

Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).Single();

您的代码假设Accounts 必须包含任何{emailAddress, password} 对的记录,这是不正确的。用SingleOrDefault 替换Single 将使异常消失。当然,您需要对结果进行空值检查以查看记录是否存在。

以下是更改代码的方法:

public UserData ByPassword(string emailAddress, string password) {
    // null-check your arguments to detect programming errors in the "upstream" code
    if (emailAddress == null) throw new ArgumentNullException("emailAddress");
    if (password == null) throw new ArgumentNullException("password");
    // Now that your arguments are "sanitized", fix the Single() call
    Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).SingleOrDefault();
    // Missing credentials is not a programming error - throw your specific exception here:
    if (account == null) {
        throw new OurException(OurExceptionType.InvalidCredentials);
    }
    string token = OurAuthorizationAttribute.CreateTicket(account.AccID, false);
    UserData data = new UserData();
    data.Id = account.AccID;
    data.Token = token;
    return data;
}

注意:虽然上述更改将修复编码错误,但它不会解决以纯文本形式存储密码的主要设计缺陷。有关在数据库中存储密码的深入讨论,请参阅 this question

【讨论】:

  • 不会在第二种情况下捕获Single 抛出的异常吗?
  • 但是当结果为空时,我应该怎么做作为对前端的响应,并停止执行其余代码
  • @SergeyBerezovskiy 是的,catch all 子句会吞下该异常以及代码可能产生的任何其他异常。我的观点是,这种方法从根本上是不正确的:在具有 optional 结果的查询上调用 Single() 是一个编码错误,无论是否有 catch-all 子句。
  • @user2918388 这很奇怪——可能在调用ByPassword 之前或之后发生了其他事情,“掩码”OurException 在上述方法中抛出。这是盲目的try {} catch {} 块的危险,它们不关心它们捕获的异常,类似于您的第二个片段显示的内容。
  • @user2918388 这个响应对我来说是正确的——你传递了一个名字好看的enum,你看到了一个名字好看的enum。在产生响应字符串的代码中没有使用InvalidCredentials 的事实。如果您希望字符串读取"ExceptionMessage": "Our own exception of type: InvalidCredentials",请更改在OurException 中生成Message 的代码,以将类型转换为int 以进行打印。
猜你喜欢
  • 2016-07-18
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
相关资源
最近更新 更多