我有一个函数,我的控制器正在调用该函数来检查帐户是否有效。
我想知道什么是返回该函数的最佳设计。抛出异常或返回错误消息会更好吗?
选项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?哪个选项是更好的设计?干杯。
答案 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应用程序,则最好返回错误消息,而不是异常。