【问题标题】:Change Validation For a Property in ASP.NET MVC 3 by Condition按条件更改 ASP.NET MVC 3 中属性的验证
【发布时间】:2012-05-15 20:50:04
【问题描述】:

这是我的模特:

[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 Validation by Change PhoneType 如果我想说更具体:

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

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

如果选择Phone,则验证是

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

你有什么建议?

【问题讨论】:

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


    【解决方案1】:

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

    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。看看定义验证规则是多么容易,而不是编写大量的管道代码,并且不再能够理解哪个部分是管道,哪个部分是实际验证。使用 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);
        }
    }
    

    只需将此验证器与前一个进行比较。

    【讨论】:

    • FluentValidation.NET 是否也引入了简单的方法来注册客户端非侵入式验证?
    • @WahidBitar,是的,FluentValidation.NET 支持与数据注释相同的客户端验证规则。
    • @DarinDimitrov 感谢您的回答,但首先使用 FluentValidation.Net 存在一些问题:正如文档所述:FluentValidation 也适用于 ASP.NET MVC 的客户端验证,但并非所有规则支持。例如,使用条件(使用 When/Unless)、自定义验证器或对 Must 的调用定义的任何规则都不会在客户端运行。第二:我无法在客户端控制 ErrorMessage。我说的对吗?
    • @Saeid,是的,你是对的。但是不要认为使用我在答案中显示的自定义属性,您将获得任何客户端验证。您将不得不编写一个自定义客户端适配器来完成这项工作。因为这个验证器依赖于另一个属性的值。 FluentValidation.NET 支持与数据注释相同的开箱即用验证规则。对于其他所有内容,您必须以与数据注释相同的方式编写 javascript 适配器。以下是您在这两种情况下需要的示例:stackoverflow.com/a/7854915/29407
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    相关资源
    最近更新 更多