0

我有一个名为 SignUp 的视图模型,其 EmailAddress 属性设置如下:

 [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 属性没有处理这个问题 - 为什么它直接跳到自定义验证器中?

4

2 回答 2

0

NullReferenceException 被抛出,因为 value.ToString() 在检查 null 之前被调用。由于您仅在检查后才需要哈希变量,因此可以通过重新排序语句来解决此问题:

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

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

于 2013-11-29T09:47:57.760 回答
0

Required属性会导致将错误添加到模型状态。它不会使执行短路。该框架继续运行其他验证器,原因很简单,即所有关于请求的错误都需要一次性发送出去。理想情况下,您不希望服务一开始就说有问题,当用户在进行更正后重新提交请求时,服务会回来说其他事情有问题等等。我想这会很烦人。

于 2013-10-21T10:37:57.887 回答