尝试继承RegularExpressionAttribute,不再验证

DMa*_*yer 9 validation asp.net-mvc asp.net-mvc-validation asp.net-mvc-4

我试图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; }
}
Run Code Online (Sandbox Code Playgroud)

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

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我改变了我的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; }
}
Run Code Online (Sandbox Code Playgroud)

现在,验证不会在客户端上呈现不显眼的数据属性.我不太清楚为什么,因为看起来这两者应该基本上是一回事.

有什么建议?

Dar*_*rov 16

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

DataAnnotationsModelValidatorProvider.RegisterAdapter(
    typeof(SsnAttribute), 
    typeof(RegularExpressionAttributeAdapter)
);
Run Code Online (Sandbox Code Playgroud)

您需要这个的原因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";
Run Code Online (Sandbox Code Playgroud)

然后:

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; }
}
Run Code Online (Sandbox Code Playgroud)

看起来很可读.

  • 我最终得到了我的属性实现`IClientValidatable`.我想要一个属性而不是使用`RegularExpressionAttribute`的原因主要是因为我不想弄清楚在我的项目中将`public const string`正则表达式放在哪里([计算机科学中只有两个难点] ...](http://martinfowler.com/bliki/TwoHardThings.html)),但也因为MVC人员似乎有一个emergin模式来创建基本上不超过`RegularExpressionAttribute`的属性(` PhoneAttribute',`EmailAddressAttribute`等),所以我觉得有道理 (3认同)