C# 如何在实体框架中处理System.InvalidOperationException?
我不熟悉asp.net web API。我已经做了一个函数,应该验证用户的前端发送数据,然后我在数据库中搜索数据。但是,当找不到帐户时,我总是遇到异常,我应该如何处理该异常以将信息发送到前端 另外,当第一个if语句不为true时,我应该返回什么,因为null不起作用C# 如何在实体框架中处理System.InvalidOperationException?,c#,entity-framework,asp.net-mvc-4,asp.net-web-api,C#,Entity Framework,Asp.net Mvc 4,Asp.net Web Api,我不熟悉asp.net web API。我已经做了一个函数,应该验证用户的前端发送数据,然后我在数据库中搜索数据。但是,当找不到帐户时,我总是遇到异常,我应该如何处理该异常以将信息发送到前端 另外,当第一个if语句不为true时,我应该返回什么,因为null不起作用 public UserData ByPassword(string emailAddress, string password) { if (emailAddress != 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;
}
她也有我添加的尝试和捕捉块,但仍然是相同的问题
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);
}
系统。InvalidOperationException
表示编程错误。您可以通过修复代码来处理它
在这种特殊情况下,错误出现在这一行:
Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).Single();
您的代码假设帐户
必须包含任何{emailAddress,password}
对的记录,这是不正确的。将Single
替换为SingleOrDefault
将使异常消失。当然,您需要对结果进行null检查,以查看记录是否存在
以下是如何更改代码:
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;
}
注意:尽管上述更改将修复编码错误,但它不会解决以纯文本形式存储密码的主要设计缺陷。有关在数据库中存储密码的详细讨论,请参阅。当在数据库中找不到电子邮件地址或密码时,它会触发否,它不会。您应该使用
SingleOrDefault()
而不是Single()
,如果数据不在数据库中,您将得到null
。在任何情况下,哦,上帝,我希望你不是在生产环境中这样做认证!使用ASP.NET标识(2.0)有什么问题?它处理所有棘手的部分,并正在使用EntyTrror太,所以它很容易在您的情况下使用。谢谢Luann,我会考虑认证,正如你所提到的。在第二种情况下,Single
引发的异常不会捕获任何作为起始点的链接?但是,当结果为空时,我应该做什么作为对前端的响应,同时停止其他代码executing@SergeyBerezovskiy是的,一网打尽的条款会吞并这个例外,以及代码可能产生的任何其他异常。我的观点是,这种方法从根本上是不正确的:对具有可选结果的查询调用Single()
,无论是否使用catch-all子句,都是一种编码错误。@user2918388这很奇怪-可能在调用ByPassword
之前或之后发生了一些“屏蔽”的事情OurException
在上述方法中抛出。这是一种盲目的try{}catch{}
块的危险,这些块不关心它们捕获了什么异常,类似于您的第二个片段所显示的。@user2918388该响应在我看来是正确的-您传递了一个具有漂亮名称的enum
,然后您看到了一个具有漂亮名称的enum
。生成响应字符串的代码中未使用InvalidCredentials
。如果希望字符串读取“ExceptionMessage”:“我们自己的类型异常:InvalidCredentials”
,请在OurException
中更改生成消息的代码,以将类型转换为int
进行打印。