属性依赖于另一个字段

Ahm*_*yan 25 validation asp.net-mvc annotations model

在我的ASP.NET MVC应用程序的模型中,我想仅在选中特定复选框时才根据需要验证文本框.

就像是

public bool retired {get, set};

[RequiredIf("retired",true)]
public string retirementAge {get, set};
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

谢谢.

Ric*_*rdN 14

看看这个:http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx

我已经根据我的需要修改了代码.也许您也可以从这些变化中受益.

public class RequiredIfAttribute : ValidationAttribute
{
    private RequiredAttribute innerAttribute = new RequiredAttribute();
    public string DependentUpon { get; set; }
    public object Value { get; set; }

    public RequiredIfAttribute(string dependentUpon, object value)
    {
        this.DependentUpon = dependentUpon;
        this.Value = value;
    }

    public RequiredIfAttribute(string dependentUpon)
    {
        this.DependentUpon = dependentUpon;
        this.Value = null;
    }

    public override bool IsValid(object value)
    {
        return innerAttribute.IsValid(value);
    }
}

public class RequiredIfValidator : DataAnnotationsModelValidator<RequiredIfAttribute>
{
    public RequiredIfValidator(ModelMetadata metadata, ControllerContext context, RequiredIfAttribute attribute)
        : base(metadata, context, attribute)
    { }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        // no client validation - I might well blog about this soon!
        return base.GetClientValidationRules();
    }

    public override IEnumerable<ModelValidationResult> Validate(object container)
    {
        // get a reference to the property this validation depends upon
        var field = Metadata.ContainerType.GetProperty(Attribute.DependentUpon);

        if (field != null)
        {
            // get the value of the dependent property
            var value = field.GetValue(container, null);

            // compare the value against the target value
            if ((value != null && Attribute.Value == null) || (value != null && value.Equals(Attribute.Value)))
            {
                // match => means we should try validating this field
                if (!Attribute.IsValid(Metadata.Model))
                    // validation failed - return an error
                    yield return new ModelValidationResult { Message = ErrorMessage };
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

public DateTime? DeptDateTime { get; set; }
[RequiredIf("DeptDateTime")]
public string DeptAirline { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 你需要添加'DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredIfAttribute),typeof(RequiredIfValidator));' 到你的global.asax.cs来实现这一点.(如RickardN提供的链接中所述. (3认同)

小智 10

只需使用Codeplex上提供的Foolproof验证库:https: //foolproof.codeplex.com/

它支持以下"requiredif"验证属性/装饰:

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
Run Code Online (Sandbox Code Playgroud)

开始很容易:

  1. 从提供的链接下载包
  2. 添加对包含的.dll文件的引用
  3. 导入包含的javascript文件
  4. 确保您的视图引用其HTML中包含的javascript文件,以进行不显眼的javascript和jquery验证.


Ton*_*olf 6

使用 NuGet 包管理器我安装了这个: https: //github.com/jwaliszko/ExpressiveAnnotations

这是我的模型:

using ExpressiveAnnotations.Attributes;

public bool HasReferenceToNotIncludedFile { get; set; }

[RequiredIf("HasReferenceToNotIncludedFile == true", ErrorMessage = "RelevantAuditOpinionNumbers are required.")]
public string RelevantAuditOpinionNumbers { get; set; }
Run Code Online (Sandbox Code Playgroud)

我向你保证这会起作用!


Zac*_*ack 5

我还没有看到任何现成的东西可以让你做到这一点。

我创建了一个类供您使用,它有点粗糙并且绝对不灵活..但我认为它可以解决您当前的问题。或者至少让你走上正轨。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Globalization;

namespace System.ComponentModel.DataAnnotations
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public sealed class RequiredIfAttribute : ValidationAttribute
    {
        private const string _defaultErrorMessage = "'{0}' is required";
        private readonly object _typeId = new object();

        private string  _requiredProperty;
        private string  _targetProperty;
        private bool    _targetPropertyCondition;

        public RequiredIfAttribute(string requiredProperty, string targetProperty, bool targetPropertyCondition)
            : base(_defaultErrorMessage)
        {
            this._requiredProperty          = requiredProperty;
            this._targetProperty            = targetProperty;
            this._targetPropertyCondition   = targetPropertyCondition;
        }

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

        public override string FormatErrorMessage(string name)
        {
            return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString, _requiredProperty, _targetProperty, _targetPropertyCondition);
        }

        public override bool IsValid(object value)
        {
            bool result             = false;
            bool propertyRequired   = false; // Flag to check if the required property is required.

            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            string requiredPropertyValue            = (string) properties.Find(_requiredProperty, true).GetValue(value);
            bool targetPropertyValue                = (bool) properties.Find(_targetProperty, true).GetValue(value);

            if (targetPropertyValue == _targetPropertyCondition)
            {
                propertyRequired = true;
            }

            if (propertyRequired)
            {
                //check the required property value is not null
                if (requiredPropertyValue != null)
                {
                    result = true;
                }
            }
            else
            {
                //property is not required
                result = true;
            }

            return result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在模型类之上,您只需要添加:

[RequiredIf("retirementAge", "retired", true)]
public class MyModel
Run Code Online (Sandbox Code Playgroud)

在你看来

<%= Html.ValidationSummary() %> 
Run Code Online (Sandbox Code Playgroud)

每当退休属性为 true 并且所需属性为空时,应显示错误消息。

希望这可以帮助。