2010-09-14 3 views
23

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

Что-то вроде

public bool retired {get, set}; 

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

Как я могу это сделать?

спасибо.

+1

'[RequiredIf ("отставной == истинный")]' [подробнее здесь] (https://github.com/JaroslawWaliszko/ExpressiveAnnotations) – jwaliszko

ответ

3

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

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

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

Выше вашего класса модели, вы должны просто нужно добавить:

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

На ваш взгляд

<%= Html.ValidationSummary() %> 

Если появляется сообщение об ошибке, когда отставной свойство верно и требуется свойство пусто.

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

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

Затем использовать:

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

вам нужно добавить 'DataAnnotationsModelValidatorProvider.RegisterAdapter ( TYPEOF (RequiredIfAttribute) , typeof (RequiredIfValidator)); на ваш global.asax.cs, чтобы заставить это работать. (как описано в ссылке RickardN. – tkerwood

+0

'ModelMetadata.FromLambdaExpression (ex, html.ViewData) .IsRequired' всегда возвращает' false', даже если зависимость от свойства истинна/false – Hanady

1

Попробуйте мой обычай validation attribute:

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

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

+0

Было бы неплохо, если бы вы могли предоставить полный проект в вашем репо, который включает в себя все необходимые ссылки, такие как System.Linq.Dynamic. Кроме того, вы, похоже, используете пользовательскую версию System.Linq.Dynamic, поскольку Microsoft имеет метод ExpressionParser.Parse(), который принимает 1 аргумент, но вы вызываете версию с 2 аргументами. –

+0

Спасибо @IanKemp, я рассмотрю ваши предложения и улучшу репозиторий – karaxuna

+0

@karaxuna Что мне делать с ExpressionParser, там есть ошибка, показывающая меня? –

9

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

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

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

Для начала легко :

  1. Загрузить пакет из предоставленного ссылки
  2. Добавить ссылку на прилагаемый .dll файл
  3. Импортировать включенные JavaScript файлов
  4. Убедитесь, что ваши взгляды ссылки на включенные JavaScript файлов из его HTML для Ненавязчивого JavaScript и JQuery проверки.
+0

Полнофункциональный не работает с EF 4+. –

+0

Ссылка? Кажется, что работает отлично для меня - я использую EF 6. Я загрузил исходный код для Foolproof и скомпилировал его так что, возможно, это объясняет, почему он работает для меня? –

+0

http://foolproof.codeplex.com/workitem/15609 и http://forums.asp.net/t/1752975.aspx –

1

С помощью диспетчера NuGet пакета я intstalled это: 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; } 

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

Смежные вопросы