【问题标题】:How can I do a data type validation on a field that is dependent on another field?如何对依赖于另一个字段的字段进行数据类型验证?
【发布时间】:2013-01-24 03:09:29
【问题描述】:

我无法执行依赖于另一个字段的数据类型验证。我在这里找到的大多数示例都是基于另一个字段的值来确定是否需要某个字段(仅当IsMarriedtrue 时才需要MaidenName)。

我的模特

public class AttributeValuesModel
{
    public IList<AttributeModel> Values {get; set;}
}

public class AttributeModel
{
    [Required]
    public string AttributeName {get; set;}

    [Required]
    public string AttributeValue {get; set;}

    [Required]
    public int DataTypeId {get; set;}
}

我想做的是根据 DataTypeId 的值验证 AttributeValue 的用户输入。为了清楚起见,DataTypeId 的值在我向用户展示视图之前就已经知道了。

    //Possible values for DataTypeId are 
    //1 for decimal
    //2 for dates
    //3 for integer

这可能吗?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 razor entity-attribute-value


    【解决方案1】:

    您可以查看 ASP.NET MVC 的 FoolProof 验证扩展。它们包含验证属性,可用于执行条件验证,例如[RequiredIf]

    还有一个更强大的验证库(也是我使用和推荐的)是FluentMVC。与验证数据注释相反,此库允许您执行命令式验证而不是声明式验证。这允许您表达任意复杂的规则以及依赖属性之间的规则。

    【讨论】:

    • 我在发布我的问题之前看过 FoolProof,但我认为他们不进行数据类型验证。他们拥有的最接近的是[RequiredIfRegExMatch][RequiredIfNotRegExMatch],我觉得这有点把它推到了极限来进行数据类型验证。我会检查 FluentMVC,因为它在模型模板部分(页面底部)提到了 DataType
    • 那么,使用 FluentMVC,您将获得所有的乐趣(和力量)。
    • 既然您说您使用过FluentMVC,我想知道您是否在与我现在类似的情况下使用过内置的DataType 模板?这意味着只有在满足对另一个字段的依赖时才会触发数据类型验证。
    • 我尝试了 FluentMVC,这就是我的工作:context.RulesFor(x=&gt; x.AttributeValue).Required(c =&gt; c.Message("not valid").StopOnFail()); 但这个不是context.RulesFor(model =&gt; model.AttributeValue).Required(c =&gt; c.Message("not valid").When(x =&gt; x.DataTypeId == 1).StopOnFail()); 不知何故,DataTypeId 总是0。我错过了什么? :)
    • 您可能错过了在提交表单时将此属性的值发布到控制器操作。或者,如果您在表单中有相应的字段,您没有遵守模型绑定器所期望的正确命名约定。
    【解决方案2】:

    滚动您自己的验证属性并不难。我前段时间实施了一个。它检查其他属性的值是否小于使用此属性修饰的属性:

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited=true)]
    public class SmallerThanAttribute : ValidationAttribute
    {
        public SmallerThanAttribute(string otherPropertyName)
        {
            this.OtherPropertyName = otherPropertyName;
        }
    
        public string OtherPropertyName { get; set; }
        public string OtherPropertyDisplayName { get; set; }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return IsValid(OtherPropertyName, value, validationContext);
        }
    
        private ValidationResult IsValid(string otherProperty, object value, ValidationContext validationContext)
        {
            PropertyInfo otherPropertyInfo = validationContext.ObjectType.GetProperty(otherProperty);
    
            if (otherPropertyInfo == null)
            {
                throw new Exception("Could not find property: " + otherProperty);
            }
    
            var displayAttribute = otherPropertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).FirstOrDefault() as DisplayAttribute;
    
            if (displayAttribute != null && OtherPropertyDisplayName == null)
            {
                OtherPropertyDisplayName = displayAttribute.GetName();
            }
    
            object otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null);
    
            var smaller = (IComparable) value;
            var bigger = (IComparable) otherPropertyValue;
    
            if (smaller == null || bigger == null)
            {
                return null;
            }
    
            if (smaller.CompareTo(bigger) > 0)
            {
                return new ValidationResult(string.Format(ValidatorResource.SmallerThan, validationContext.DisplayName, OtherPropertyDisplayName));
            }
    
            return null;
        }
    }
    

    有一个问题。错误消息格式在资源类属性 (ValidatorResource.SmallerThan) 中定义,因此它不可插入——我不需要这个。但是,我认为这对您来说仍然是一个很好的起点。

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 2015-09-20
      • 2019-03-11
      • 2019-02-16
      • 2017-04-12
      • 1970-01-01
      • 2011-02-12
      • 2016-10-03
      • 1970-01-01
      相关资源
      最近更新 更多