1

我有一个具有如下属性的模型:

public class YourDetails {

  [Required(ErrorMessage = "Code is required")]
  [StringLength(10, ErrorMessage = "Code length is wrong", MinimumLength = 2)]
  [Range(0, int.MaxValue, ErrorMessage = "Please enter a value bigger than {1}")]
  public int Code { get; set; }

}

UI 验证是通过不显眼的 JS 验证插件以通常的开箱即用方式设置的。

问题:我有 2 个导航操作,返回和下一步。接下来很好,当事情出错时验证触发,当事情正确时,即.isValid()返回 true,数据被传递给 DB 服务等。

但是,当我按“返回”时,我需要在保存之前以不同方式验证表单/ViewModel。即确保Code是一个正整数,但不要打扰RequiredorStringLength验证。

所以基本上我想在 Next 上完全验证,但在 Back 上部分验证。那可能吗?

4

2 回答 2

1

当我过去做过类似的事情时,我发现最简单的方法是使用流利的验证http://fluentvalidation.codeplex.com/wikipage?title=mvc。您可以将参数传递给验证器并切换到不同的规则集。

于 2013-04-05T07:53:34.397 回答
0

我过去使用过以下条件“必需”和“字符串长度”属性,它们运行良好。

必需的 If 属性:

using System;
using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace Website.Core.Mvc.DataAnnotations
{
    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = true)]
    public class RequiredIfAttribute : RequiredAttribute
    {
        public string OtherProperty { get; set; }

        public object OtherPropertyValue { get; set; }

        public RequiredIfAttribute(string otherProperty, object value)
            : base()
        {
            OtherProperty = otherProperty;
            OtherPropertyValue = value;
        }

        private object _TypeId = new object();

        public override object TypeId
        {
            get
            {
                return _TypeId;
            }
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            PropertyInfo property = validationContext.ObjectType.GetProperty(this.OtherProperty);
            if (property == null)
            {
                return new ValidationResult(this.OtherProperty + " not found");
            }

            // Get 
            object actualOtherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);

            // If the other property matches the expected value then validate as normal
            if (IsRequired(OtherPropertyValue, actualOtherPropertyValue))
            {
                // Call base and validate required as normal
                ValidationResult isValid = base.IsValid(value, validationContext);
                return isValid;
            }
            return ValidationResult.Success;
        }

        protected virtual bool IsRequired(object otherPropertyValue, object actualOtherPropertyValue)
        {
            return object.Equals(OtherPropertyValue, actualOtherPropertyValue);
        }
    }
}

字符串长度 If 属性:

using System.ComponentModel.DataAnnotations;
using System.Reflection;

namespace Website.Core.Mvc.DataAnnotations
{
    public class StringLengthIfAttribute : StringLengthAttribute
    {
        public string OtherProperty { get; set; }

        public object OtherPropertyValue { get; set; }

        public StringLengthIfAttribute(int maximumLength, string otherProperty, object value)
            : base(maximumLength)
        {
            OtherProperty = otherProperty;
            OtherPropertyValue = value;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            PropertyInfo property = validationContext.ObjectType.GetProperty(this.OtherProperty);
            if (property == null)
            {
                return new ValidationResult(this.OtherProperty + " not found");
            }

            // Get 
            object actualOtherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);

            // If the other property matches the expected value then validate as normal
            if (object.Equals(OtherPropertyValue, actualOtherPropertyValue))
            {
                // Call base and validate required as normal
                return base.IsValid(value, validationContext);
            }
            return null;
        }
    }
}

示例用法:

public class MyModel
{
    [RequiredIf("IsBack", false)]
    public string Name { get; set; }

    public bool IsBack { get; set; } 
}
于 2013-04-05T08:04:03.683 回答