10

我正在尝试继承RegularExpressionAttribute以通过验证 SSN 来提高可重用性。

我有以下模型:

public class FooModel
{
    [RegularExpression(@"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$", ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")]
    public string Ssn { get; set; }
}

这将在客户端和服务器上正确验证。我想将冗长的正则表达式封装到它自己的验证属性中,如下所示:

public class SsnAttribute : RegularExpressionAttribute
{
    public SsnAttribute() : base(@"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$")
    {
        ErrorMessage = "SSN is invalid";
    }
}

然后我改变了我的FooModel喜欢:

public class FooModel
{
    [Ssn(ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")]
    public string Ssn { get; set; }
}

现在验证不会在客户端呈现不显眼的数据属性。我不太确定为什么,因为这似乎两者本质上应该是同一回事。

有什么建议么?

4

1 回答 1

19

在您Application_Start添加以下行以将适配器关联到您的自定义属性,该属性将负责发出客户端验证属性:

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(SsnAttribute), 
    typeof(RegularExpressionAttributeAdapter)
);

你需要这个的原因RegularExpressionAttribute是实现的方式。它没有实现IClientValidatable接口,而是有一个RegularExpressionAttributeAdapter与之关联的接口。

在您的情况下,您有一个派生自的自定义属性,RegularExpressionAttribute但您的属性没有实现IClientValidatable接口以使客户端验证正常工作,也没有与之关联的属性适配器(与其父类相反)。因此,您SsnAttribute应该IClientValidatable按照我之前的回答中的建议实现接口或关联适配器。

就个人而言,我认为实现这个自定义验证属性没有多大意义。在这种情况下,一个常数可能就足够了:

public const string Ssn = @"^(?!000)(?!666)(?!9[0-9][0-9])\d{3}[- ]?(?!00)\d{2}[- ]?(?!0000)\d{4}$", ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank";

进而:

public class FooModel
{
    [RegularExpression(Ssn, ErrorMessage = "The SSN you entered is invalid. If you do not have this number please leave the field blank")]
    public string Ssn { get; set; }
}

看起来很可读。

于 2013-09-06T21:38:39.627 回答