Asp.net web api Web API验证错误

Asp.net web api Web API验证错误,asp.net-web-api,customvalidator,Asp.net Web Api,Customvalidator,我有一个名为SignUp的视图模型,其EmailAddress属性设置如下: [Required] [DuplicateEmailAddressAttribute(ErrorMessage = "This email address already exists")] public string EmailAddress { get; set; } public class DuplicateEmailAddressAttribute : ValidationAttribute {

我有一个名为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]
 [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属性处理的-为什么它直接跳入自定义验证器?

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

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

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