System.InvalidOperationException
indicates a programming error. You handle it by fixing your code.
In this particular case the error is on this line:
Account account = db.Accounts.Where(acc => acc.AccMail == emailAddress && acc.AccPassword == password.ToLower()).Single();
Your code makes an assumption that Accounts
must contain a record for any {emailAddress, password}
pair, which is not true. Replacing Single
with SingleOrDefault
will make the exception go away. Of course you would need to null-check the result to see if the record was there or not.
Here is how you can change your code:
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;
}
NOTE : Although the above change would fix the coding error, it would not address a major design flaw of storing passwords in plain text. See this question for an in-depth discussion on storing passwords in databases.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…