2010-09-14 103 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 2014-08-13 12:51:06

回答

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() %> 

应显示错误消息每当退役属性为true和所需财产是空的。

希望这会有所帮助。

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 2012-04-13 03:44:57

+0

' ModelMetadata.FromLambdaExpression(ex,html.ViewData).IsRequired'总是返回'false',即使认为依赖属性是真/假 – Hanady 2017-08-21 11:26:44

1

试试我的自定义validation attribute

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

它支持多个条件。

+0

如果您可以提供完整的项目在你的回购中,包括所有必需的引用,如System.Linq.Dynamic。此外,你似乎使用System.Linq.Dynamic的定制版本,因为Microsoft有一个'ExpressionParser.Parse()'方法,需要1参数,但是你正在调用一个双参数版本 – 2013-11-21 10:13:51

+0

谢谢@IanKemp,我会考虑你的建议,并改进知识库 – karaxuna 2013-11-21 16:54:31

+0

@karaxuna我如何处理ExpressionParser有一个错误显示我? – 2016-11-23 11:20:50

9

只需使用万无一失的验证库,在CodePlex上: https://foolproof.codeplex.com/

支持,除其他外,下面的“requiredif”确认属性/装饰品:

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

上手容易:

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

Fullproof不起作用与EF 4+。 – 2014-02-24 02:23:43

+0

链接?它似乎对我来说工作正常 - 我使用EF 6.我下载了源代码以便万无一失并编译它我自己也许这解释了为什么它为我工作? – 2014-02-24 05:26:03

+0

http://foolproof.codeplex.com/workitem/15609和http://forums.asp.net/t/1752975.aspx – 2014-02-24 07:03:07

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

我向你保证,这将工作!

相关问题