0

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

型号类:-

    [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. 传递所有这些属性(值、格式、最小长度和最大长度)
  3. 使用 Format 属性编写 switch case。
  4. 使用正则表达式验证格式并进行手动范围验证或动态正则表达式验证。

编辑:- 在此处添加自定义验证类代码

自定义验证类:

[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 回答 2

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));
        }
于 2013-10-04T10:57:05.423 回答
0

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

这是进一步阅读的问题

于 2013-07-04T08:18:31.167 回答