按条件更改ASP.NET MVC 3中的属性的验证

时间:2012-05-07 10:30:49

标签: asp.net-mvc asp.net-mvc-3 validation validationattribute

这是我的模特:

[RegularExpression(@"^08[589][0-9]{8}$", ErrorMessage = "Invalid Number!")]
public string Phone { get; set; }

[ForeignKey]
public long PhoneType { get; set; } // 1-CellPhone , 2-Phone

所以如果我想说更具体的话,我想改变RegularExpression更改验证PhoneType

如果用户从CellPhone选择DropDownList,则验证为

[RegularExpression(@"^08[589][0-9]{8}$", ErrorMessage = "Invalid Number!")] 

如果选择Phone则验证为

 [RegularExpression("^[1-9][0-9]{9}$", ErrorMessage = "Invalid Number!")]

你的建议是什么?

1 个答案:

答案 0 :(得分:6)

您可以编写自定义验证属性:

public class PhoneAttribute : ValidationAttribute
{
    private readonly string _phoneTypeProperty;
    public PhoneAttribute(string phoneTyperoperty)
    {
        _phoneTypeProperty = phoneTyperoperty;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(_phoneTypeProperty);
        if (property == null)
        {
            return new ValidationResult(string.Format("Unknown property: {0}", _phoneTypeProperty));
        }

        var phone = Convert.ToString(value, CultureInfo.CurrentCulture);
        if (string.IsNullOrEmpty(phone))
        {
            return null;
        }

        var phoneType = (long)property.GetValue(validationContext.ObjectInstance, null);
        Regex regex = null;
        if (phoneType == 1)
        {
            regex = new Regex(@"^08[589][0-9]{8}$");
        }
        else if (phoneType == 2)
        {
            regex = new Regex("^[1-9][0-9]{9}$");
        }
        else
        {
            return new ValidationResult(string.Format("Unknown phone type: {0}", phoneType));
        }

        var match = regex.Match(phone);
        if (match.Success && match.Index == 0 && match.Length == phone.Length)
        {
            return null;
        }

        return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
    }
}

然后使用以下属性修饰视图模型属性:

public class MyViewModel
{
    [Phone("PhoneType", ErrorMessage = "Invalid Number!")]
    public string Phone { get; set; }

    public long PhoneType { get; set; }
}

如果您希望通过验证让生活更轻松,另一种可能性(我强烈建议)可以使用FluentValidation.NET。只要看看定义验证规则是多么容易,而不是编写管道代码行的gazzilions,不再能够理解哪个部分是管道,哪个部分是实际验证。使用FluentValidation.NET,没有管道。您以流利的方式表达您的验证要求:

public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
    public MyViewModelValidator()
    {
        RuleFor(x => x.Phone)
            .Matches(@"^08[589][0-9]{8}$").When(x => x.PhoneType == 1)
            .Matches("^[1-9][0-9]{9}$").When(x => x.PhoneType == 2);
    }
}

只需将此验证器与之前的验证器进行比较。