asp.net-mvc 依赖于另一个字段的属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3713281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:29:39  来源:igfitidea点击:

attribute dependent on another field

asp.net-mvcvalidationmodelannotations

提问by Ahmet Dalyan

In a model of my ASP.NET MVC application I would like validate a textbox as required only if a specific checkbox is checked.

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

Something like

就像是

public bool retired {get, set};

[RequiredIf("retired",true)]
public string retirementAge {get, set};

How can I do that?

我怎样才能做到这一点?

Thank you.

谢谢你。

回答by RickardN

Take a look at this: http://blogs.msdn.com/b/simonince/archive/2010/06/04/conditional-validation-in-mvc.aspx

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

I've modded the code somewhat to suit my needs. Perhaps you benefit from those changes as well.

我对代码进行了一些修改以满足我的需要。也许您也从这些变化中受益。

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 };
            }
        }
    }
}

Then use it:

然后使用它:

public DateTime? DeptDateTime { get; set; }
[RequiredIf("DeptDateTime")]
public string DeptAirline { get; set; }

回答by RickardN

Just use the Foolproof validation library that is available on Codeplex: https://foolproof.codeplex.com/

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

It supports, amongst others, the following "requiredif" validation attributes / decorations:

它支持以下“requiredif”验证属性/装饰等:

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]

To get started is easy:

入门很容易:

  1. Download the package from the provided link
  2. Add a reference to the included .dll file
  3. Import the included javascript files
  4. Ensure that your views references the included javascript files from within its HTML for unobtrusive javascript and jquery validation.
  1. 从提供的链接下载包
  2. 添加对包含的 .dll 文件的引用
  3. 导入包含的 javascript 文件
  4. 确保您的视图从其 HTML 中引用包含的 javascript 文件,以进行不显眼的 javascript 和 jquery 验证。

回答by Tony_KiloPapaMikeGolf

Using NuGet Package Manager I intstalled this: https://github.com/jwaliszko/ExpressiveAnnotations

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

And this is my Model:

这是我的模型:

using ExpressiveAnnotations.Attributes;

public bool HasReferenceToNotIncludedFile { get; set; }

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

I guarantee you this will work!

我向你保证这会奏效!

回答by Zack

I have not seen anything out of the box that would allow you to do this.

我还没有看到任何可以让你这样做的开箱即用的东西。

I've created a class for you to use, it's a bit rough and definitely not flexible.. but I think it may solve your current problem. Or at least put you on the right track.

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

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;
        }
    }
}

Above your Model class, you should just need to add:

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

[RequiredIf("retirementAge", "retired", true)]
public class MyModel

In your View

在你看来

<%= Html.ValidationSummary() %> 

Should show the error message whenever the retired property is true and the required property is empty.

只要停用的属性为真且所需的属性为空,就应显示错误消息。

Hope this helps.

希望这可以帮助。

回答by karaxuna

Try my custom validation attribute:

试试我的自定义验证属性

[ConditionalRequired("retired==true")]
public string retirementAge {get, set};

It supports multiple conditions.

它支持多种条件。