抛出异常或返回

时间:2019-03-10 12:48:17

标签: c# asp.net-mvc

我有一个函数,我的控制器正在调用该函数来检查帐户是否有效。

我想知道什么是返回该函数的最佳设计。抛出异常或返回错误消息会更好吗?

选项1 ,当前正在使用

public void ValidateLocalAccount(Login dto) {
     var user = _userService.GetUserByUsername(dto.username);
     if (user == null)
           throw new Exception("User does not exist");

     if (user.accountType != AccountType.Local)
           throw new Exception("Account is not local");
}

控制器:

[HttpPost("Login")]
public async Task<ActionResult> Login([FromBody] Login loginDto)
{
    try
    {
          _accountService.ValidateLocalAccount(loginDto);
          return Ok(await _accountService.GetToken(loginDto));
    }
    catch (Exception ex)
    {
          return BadRequest(ex.Message);
    }
}

选项2 ,这对我来说似乎很不常规

public <bool, string> ValidateLocalAccount(Login dto) {
     var user = _userService.GetUserByUsername(dto.username);
     if (user == null)
           return (false,"User does not exist");

     if (user.accountType != AccountType.Local)
           return (false,"Account is not local");

     return (true,string.empty);
}

控制器:

[HttpPost("Login")]
public async Task<ActionResult> Login([FromBody] Login loginDto)
{
     var res = _accountService.ValidateLocalAccount(loginDto);
     if(!res.item1)
        return BadRequest(res.item2)

     return Ok(await _accountService.GetToken(loginDto));
}

我会滥用选项1的异常,因为我有点用它来控制流程吗?因此,我的问题是我何时应该选择错误代码以外的异常或返回null?哪个选项是更好的设计?干杯。

2 个答案:

答案 0 :(得分:2)

失败的登录尝试绝非例外,因此在这种情况下,您不应使用异常。那就是埃里克·利珀特(Eric Lippert)所说的vexing exception-因此,我肯定会选择选项#2。

如果使用的是C#7.0或更高版本,则可以返回value tuple,因此可以为其项目使用有意义的名称(而不是System.Tuple中的Item1和Item2)。如果您使用的是早期版本的c#,则可能希望返回自己的struct或类,以便将来维护和提高代码可读性。

答案 1 :(得分:0)

最佳做法是返回正确的状态代码,例如404(未找到),401(未经授权)或500(内部服务器错误)。

签出HTTP状态代码的list

P.S。在编写API的情况下,返回状态代码是最佳做法,但如果编写的是剃刀页面之类的Web应用程序,则最好返回错误消息,而不是异常。