2013-10-21 82 views
0

我有一个名为注册视图模型与EmailAddress的属性设置是这样的:的Web API验证错误

[Required] 
[DuplicateEmailAddressAttribute(ErrorMessage = "This email address already exists")] 
public string EmailAddress { get; set; } 

和自定义验证看起来是这样的:

public class DuplicateEmailAddressAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     PestControlContext _db = new PestControlContext(); 
     int hash = value.ToString().GetHashCode(); 

     if (value == null) 
     { 
      return true; 
     } 

     if (_db.Users.Where(x => x.EmailAddressHash == hash).Count() > 0) 
      return false; 
     else 
      return true; 
    } 
} 

我有问题如果用户在注册表单上留下了空白的电子邮件地址字段,应用程序就会抛出一个空引用异常错误(我认为它正在数据库中查找“”,并且找不到它)。我不明白的是为什么这不是由Required属性处理 - 为什么它直接跳入自定义验证器?

回答

0

Required属性会导致错误被添加到模型状态。尽管如此,它不会使执行短路。该框架继续运行其他验证器,原因很简单,因为全部是关于请求的错误需要一次性发送出去。理想情况下,您不希望服务说一开始是错误的,当用户在纠正之后重新提交请求时,服务会返回并说出其他问题,等等。我想,这将是一个烦恼。

0

NullReferenceException被抛出,因为在检查null之前调用value.ToString()。当你只有检查后需要的散列变量,您可以通过重新排序报表解决这个问题:

if (value == null) 
{ 
    return true; 
} 
int hash = value.ToString().GetHashCode(); 

此外,您还可以移动PestControlContext对空的检查后,并使用using语句来处理它正常。
正如@Baldri指出的那样,每个验证器都可以添加错误消息,并且所有这些错误消息都可以运行,即使前一个验证器已经表示数据无效。此外,我不会依赖于验证是按照您在使用属性标记属性时指定的顺序运行的(某些框架实施其自己的属性排序机制来声明顺序是确定性的,例如优先级或先前属性)。
因此,我建议重新排序自定义验证程序中的代码是最佳解决方案。