首先,我在C#中登录/注册表单,我创建了登录错误和注册错误的枚举,以便login方法返回枚举,如果是例如" LoginErrors.None&#34 ;然后程序继续。但是我想知道抛出异常是否更合适,即如果username参数是&#34则抛出ArgumentNullException。 "或null。
在这种情况下最合适的是什么?
答案 0 :(得分:2)
例外通常不用于验证目的。您应该自己验证任何登录错误。
例外情况很慢,并没有比你自己的验证更好的目的,所以听起来你第一次就做对了。
答案 1 :(得分:0)
糟糕的做法。尝试验证,因为从未为这些目的做过例外。去验证
答案 2 :(得分:0)
我认为我在这里非常符合这个答案:
https://stackoverflow.com/a/52322/2740778
在罕见或特殊情况下捕获异常。验证用户或检查空输入等都是常见的事情。
IMO我认为该语言提供了足够的流量控制,而不使用例外来实现这一目标。
答案 3 :(得分:0)
首先,如果登录名是null
可能是错误,因为我不认为来自用户界面的输入可以存储null
值。在您的登录代码之上的某个层中可能出现问题。
对于上述情况,仅针对该情况,我会抛出ArgumentNullException
。就我而言,我会使用code contracts。
无论如何,我会给你一个提示:我会将登录信息转换为一个类,我会实现specification pattern来验证它。另外,请参阅我如何使用code contracts (design by contract)实现参数和返回值验证:
public class UserLogin
{
public string Name { get; set; }
public string Password { get; set; }
}
public class UserLoginSpec
{
// This could be a simplified way of storing broken rules,
// where keys are the affected resource or property by the
// rule, and the value, a human-readable description of what
// happened with the broken rule...
public Dictionary<string, string> BrokenRules { get; } = new Dictionary<string, string>();
public bool IsSatisfiedBy(UserLogin login)
{
Contract.Requires(login != null);
if(string.IsNullOrEmpty(login.Name))
BrokenRules.Add("Name", "Name cannot be empty");
if(string.IsNullOrEmpty(login.Password))
BrokenRules.Add("Password", "Password cannot be empty");
// The spec is passed if no broken rule has been added
return BrokenRules.Count == 0;
}
}
public class UserLoginResult
{
public UserLoginResult(UserLoginSpec spec)
{
Contract.Requires(spec != null);
Successful = spec.BrokenRules.Count == 0;
Errors = spec.BrokenRules;
}
public bool Successful { get; private set; }
public Dictionary<string, string> Errors { get; private set; }
}
现在您的身份验证方法如下所示:
public UserLoginResult Authenticate(UserLogin login)
{
Contract.Requires(login != null);
Contract.Ensures(Contract.Result<UserLoginResult>() != null);
UserLoginSpec loginSpec = new UserLoginSpec();
if(loginSpec.IsSatisfiedBy(login))
{
// Actual code to validate user's credentials here
}
return new UserLoginResult(loginSpec);
}
现在,您可以进一步概括此解决方案,或在结果类中添加更多收集的数据。