web-dev-qa-db-ja.com

別のフィールドに依存する属性

ASP.NET MVCアプリケーションのモデルで、特定のチェックボックスがオンになっている場合にのみ、必要に応じてテキストボックスを検証します。

何かのようなもの

public bool retired {get, set};

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

どうやってやるの?

ありがとうございました。

25
Ahmet Dalyan

これを見てください: 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; }
14
RickardN

Codeplexで利用可能なFoolproof検証ライブラリを使用するだけです: https://foolproof.codeplex.com/

特に、次の「requiredif」検証属性/装飾をサポートしています。

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

始めるのは簡単です:

  1. 提供されたリンクからパッケージをダウンロードします
  2. 含まれている.dllファイルへの参照を追加する
  3. 含まれているJavaScriptファイルをインポートする
  4. 控えめなJavaScriptとjqueryの検証のために、ビューがHTML内から含まれているJavaScriptファイルを参照していることを確認してください。
10
user3083619

私はあなたがこれを行うことを可能にするような箱から出して何も見ていません。

私はあなたが使用するクラスを作成しました。それは少しラフで、間違いなく柔軟ではありません。または、少なくともあなたを正しい軌道に乗せます。

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で、必要なプロパティが空の場合は常にエラーメッセージを表示する必要があります。

お役に立てれば。

4
Zack

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

これが機能することを保証します!

私のカスタムを試してください 検証属性

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

複数の条件をサポートしています。

0
karaxuna