在asp.net mvc2中动态地为模型属性添加验证规则

时间:2013-07-03 10:56:19

标签: asp.net-mvc asp.net-mvc-2 model customvalidator asp.net-mvc-2-validation

在同一模型对象的其他属性中可以使用一个模型属性验证信息/规则。我必须使用其他属性值验证属性值。

模特课: -

    [FormatValidtion("Value", "Format", "MinLength", "MaxLength", ErrorMessage = "Please enter correct format")]
    public class Sample
    {        
        #region ModelProperties

        public string Id { get; set; }

        [Required(ErrorMessage = "Please Enter Value")]
        public string Value { get; set; }              

        public string Format { get; set; }

        public string MinLength { get; set; }

        public string MaxLength { get; set; }

        #endregion
    }

模型对象如上所示。我必须使用

验证 Value 属性
  • 格式(Fomart验证,如电子邮件,手机和日期)

  • MinLength,MaxLength (范围验证)属性。

我知道我们可以使用

等自定义验证来完成此操作
  1. 创建自定义类,将 ValidationAttribute 作为基础
  2. 传递所有这些属性(Value,Format,MinLength& MaxLength)
  3. 使用Format属性写开关案例。
  4. 使用Regex验证格式并执行手动范围验证或动态Regex验证。
  5. 编辑: - 在此处添加了自定义验证类代码

    自定义验证类:

    [AttributeUsage(AttributeTargets.Class)]
    public class FormatValidtion : ValidationAttribute
    {
    
        public String Value { get; set; }
        public String Format { get; set; }
        public String MinLength { get; set; }
        public String MaxLength { get; set; }
    
        public FormatValidtion(String value, String format, String minLength, String maxLength)
        {
            Value = value;
            Format = format;
            MinLength = minLength;
            MaxLength = maxLength;
        }
    
        public override Boolean IsValid(Object value)
        {
            Type objectType = value.GetType();
    
            PropertyInfo[] neededProperties =
              objectType.GetProperties()
              .Where(p => p.Name == Value || p.Name == Format || p.Name == MinLength || p.Name == MaxLength)
              .ToArray();
    
            if (neededProperties.Count() != 4)
            {
                throw new ApplicationException("PropertiesMatchAttribute error on " + objectType.Name);
            }
    
            Boolean isMatched = true;
    
            switch (Convert.ToString(neededProperties[1].GetValue(value, null)))
            {
                case "Alpha":
                    Regex regExAlpha = new Regex(@"/^[A-Za-z]+$/");
                    if (!regExAlpha.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = false;
                    }
                    break;
                case "Number":
                    Regex regExNumber = new Regex(@"/^[0-9]+$/");
                    if (!regExNumber.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = false;
                    }
                    break;
                case "AlphaNum":
                    Regex regExAlphaNum = new Regex(@"/^[a-zA-Z][a-zA-Z0-9]+$/");
                    if (!regExAlphaNum.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = false;
                    }
                    break;
                default:
                    isMatched = false;
                    break;
            }
            return isMatched;
        }    
    }
    

    这在类级别上正常工作,并通过验证摘要显示验证消息。但我想修改上面的代码来做以下事情。

    1. 验证应该在属性级别进行,或者需要在属性级别显示错误消息(使用validationMessage帮助程序类)。
    2. 除常见错误消息外,需要为每个验证提供特定的错误消息。
    3. 应该进行范围验证。
    4. 有人可以围绕这些提出一些想法吗?

2 个答案:

答案 0 :(得分:0)

您可以使用IValidatableObject interface。正确实施后,您可以显示属性级别和自定义错误消息。

以下是进一步阅读的question

答案 1 :(得分:0)

我完成了以下代码。

模特课: -

    [FormatValidtion("Value", "Format", "MinLength", "MaxLength")]
    public class Sample
    {
        #region ModelProperties

        public string Id { get; set; }

        [Required(ErrorMessage = "Please Enter Value")]
        public string Value { get; set; }

        public string Format { get; set; }

        public string MinLength { get; set; }

        public string MaxLength { get; set; }

        #endregion
    }

自定义验证类: -

[AttributeUsage(AttributeTargets.Class)]
    public class FormatValidtion : ValidationAttribute
    {

        public string Value { get; set; }
        public string Format { get; set; }
        public string MinLength { get; set; }
        public string MaxLength { get; set; }
        public string Format1 { get; set; }
        public string Value1 { get { return Value; } }

        public FormatValidtion(String value, String format, String minLength, String maxLength)
        {
            Value = value;
            Format = format;
            MinLength = minLength;
            MaxLength = maxLength;
        }

        public override Boolean IsValid(Object value)
        {
            Type objectType = value.GetType();

            PropertyInfo[] neededProperties =
              objectType.GetProperties()
              .Where(p => p.Name == Value || p.Name == Format || p.Name == MinLength || p.Name == MaxLength)
              .ToArray();

            if (neededProperties.Count() != 4)
            {
                throw new ApplicationException("PropertiesMatchAttribute error on " + objectType.Name);
            }

            Boolean isMatched = true;
            this.Format1 = Convert.ToString(neededProperties[1].GetValue(value, null));

            switch (Convert.ToString(neededProperties[1].GetValue(value, null)))
            {
                case "Alpha":
                    Regex regExAlpha = new Regex(@"/^[A-Za-z]+$/");
                    if (!regExAlpha.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
                    }
                    break;
                case "Number":
                    Regex regExNumber = new Regex(@"/^[0-9]+$/");
                    if (!regExNumber.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
                    }
                    break;
                case "AlphaNum":
                    Regex regExAlphaNum = new Regex(@"/^[a-zA-Z][a-zA-Z0-9]+$/");
                    if (!regExAlphaNum.IsMatch(Convert.ToString(neededProperties[0].GetValue(value, null))))
                    {
                        isMatched = IsValidLength(Convert.ToString(neededProperties[0].GetValue(value, null)).Length, Convert.ToInt32(neededProperties[2].GetValue(value, null)), Convert.ToInt32(neededProperties[3].GetValue(value, null)));
                    }
                    break;
                default:
                    isMatched = false;
                    break;
            }
            return isMatched;
        }

        /// range validation
        public bool IsValidLength(int valueLenght, int minLenght, int maxLenght)
        {
            if (valueLenght >= minLenght && valueLenght <= maxLenght)
                return true;
            return false;
        }

    }

验证适配器类: -

public class FormatValidtionAdapter : DataAnnotationsModelValidator<FormatValidtion>
    {

        public FormatValidtionAdapter(ModelMetadata metadata, ControllerContext context, FormatValidtion attribute)
            : base(metadata, context, attribute)
        {
        }


       // To Provide Error messages dynamically depends on format.            
        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            string ErrorMessage = null;
            if (!Attribute.IsValid(Metadata.Model))
            {
                switch (Attribute.Format1)
                {
                    case "Alpha":
                        ErrorMessage = "Please enter alphabets only";
                        break;
                    case "Number":
                        ErrorMessage = "Please enter numbers only";
                        break;
                    case "AlphaNum":
                        ErrorMessage = "Please enter alphanumeric  only";
                        break;
                    default:
                        break;
                }
                yield return new ModelValidationResult
                {
                    Message = ErrorMessage,
                    MemberName = Attribute.Value1
                };
            }
        }
    }

<强> Global.aspx.cs: -

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);

            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(FormatValidtion), typeof(FormatValidtionAdapter));
        }