对于登录/注册错误抛出异常是否合适
本文关键字:抛出异常 错误 是否 注册 于登录 登录 | 更新日期: 2024-10-20 05:58:58
起初,对于C#中的登录/注册表单,我为登录错误和注册错误创建了枚举,因此登录方法返回了一个枚举,如果它是"LoginErrors.None",则程序继续。然而,我想知道抛出异常是否更合适,即如果username参数为"或null,则抛出ArgumentNullException。
在这种情况下,什么是最合适的?
异常通常不用于验证目的。您应该自己验证任何登录错误。
例外是缓慢的,没有任何比你自己的验证更好的目的,所以听起来你第一次做对了。
不良做法。尝试验证,因为从来没有出于这些目的而进行过异常。进行验证
我认为我非常赞同这个答案:
https://stackoverflow.com/a/52322/2740778
在罕见或异常情况下捕获异常。验证用户或检查空输入等都是需要处理的常见问题。
IMO我认为该语言在不使用Exceptions的情况下提供了足够的流量控制。
首先,如果登录名为null
,则可能是一个错误,因为我认为来自UI的输入无法存储null
值。登录代码顶部的某个层可能出现问题。
对于上述情况,并且仅对于该情况,我将抛出一个ArgumentNullException
。在我的情况下,我会使用代码合约。
无论如何,我会给你一个提示:我会把登录信息变成一个类,我会实现规范模式来验证它。此外,看看我如何使用代码合约(按合约设计)实现参数和返回值验证:
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);
}
现在,您可以进一步推广这个解决方案,或者在结果类中添加更多收集的数据。