对于登录/注册错误抛出异常是否合适

本文关键字:抛出异常 错误 是否 注册 于登录 登录 | 更新日期: 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);
}

现在,您可以进一步推广这个解决方案,或者在结果类中添加更多收集的数据。