атрибут зависит от другого поля - PullRequest
25 голосов
/ 15 сентября 2010

В модели моего приложения ASP.NET MVC я хотел бы проверить текстовое поле как требуется, только если установлен определенный флажок.

Что-то вроде

public bool retired {get, set};

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

Как я могучто?

Спасибо.

Ответы [ 5 ]

14 голосов
/ 22 февраля 2011

Взгляните на это: 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 };
            }
        }
    }
}

Тогда используйте это:

public DateTime? DeptDateTime { get; set; }
[RequiredIf("DeptDateTime")]
public string DeptAirline { get; set; }
10 голосов
/ 18 февраля 2014

Просто используйте надежную библиотеку проверки, которая доступна в Codeplex: https://foolproof.codeplex.com/

Она поддерживает, среди прочего, следующие атрибуты / украшения проверки "requiredif":

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

ДляНачать очень просто:

  1. Загрузите пакет по предоставленной ссылке
  2. Добавьте ссылку на включенный DLL-файл
  3. Импортируйте включенные файлы JavaScript
  4. Убедитесь, что ваши представления ссылаются на включенные файлы javascript из своего HTML-кода для ненавязчивой проверки javascript и jquery.
4 голосов
/ 25 января 2018

Используя менеджер пакетов 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; }

Я гарантирую вам, что это будет работать!

3 голосов
/ 16 сентября 2010

Я не видел ничего из коробки, что позволило бы вам сделать это.

Я создал для вас класс, он немного грубый и определенно не гибкий ... но я думаю, что он может решить вашу текущую проблему. Или, по крайней мере, поставить вас на правильный путь.

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

Над вашим классом Model вам просто нужно добавить:

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

По вашему мнению

<%= Html.ValidationSummary() %> 

Должно отображаться сообщение об ошибке, если выбранное свойство имеет значение true, а обязательное свойство пусто.

Надеюсь, это поможет.

0 голосов
/ 16 ноября 2013

Попробуйте мой пользовательский атрибут проверки :

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

Он поддерживает несколько условий.

...