1

MVC アプリケーションのカスタム検証属性を作成しようとしています。書かれた私のコードは、コードで指定されたプロパティに対してうまく機能します。私は今それを拡張したいので、この同じ属性を使用したい他の5つのプロパティがあるので、より一般的です。
一般的な考え方は、指定された他のプロパティが true の場合、属性に関連付けられたプロパティは > 0 でなければならないということです。

これを行う方法は、プロパティの値と他のプロパティの値を受け入れるコンストラクターを作成することだと思いますが、うまくいかないようです。私が抱えている特定の問題は、必要な値を取得する正しい方法が見つからないことです。

ここに私が持っているものがあります:

public class MustBeGreaterIfTrueAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        var model = context.ObjectInstance as HistoryViewModel;
        //ValidationResult result = null;

        // Validate to ensure the model is the correct one
        if (context.ObjectInstance.GetType().Name == null)
        {
            throw new InvalidOperationException(string.Format(
                    CultureInfo.InvariantCulture, "Context of type {0} is not supported. "
                                                  + "Expected type HistoryViewModel",
                                                   context.ObjectInstance.GetType().Name));
        }

        // Here is the actual custom rule
        if (model.HistoryModel.IsRetired == true)
        {
            if (model.CounterA == 0)
            {
                return new ValidationResult("Please enter more information regarding your History");
            }
        }
        else if ( model.HistoryModel.IsRetired == true )
        {
            if ( model.ROCounter > 0 )

            return ValidationResult.Success;
        }

        // If all is ok, return successful.
        return ValidationResult.Success;

    }

    //  Add the client side unobtrusive 'data-val' attributes
    //public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    //{

    //}

}

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

4

1 に答える 1

1

「RequiredIfTrueAttribute」と呼ばれる属性で同様のことをしました。これにより、モデル内の他のプロパティの値が取得されます。他のプロパティ名を文字列としてカスタム属性コンストラクターに渡します。

public class RequiredIfTrueAttribute: ValidationAttributeBase
{

    public string DependentPropertyName { get; private set; }

    public RequiredIfTrueAttribute(string dependentPropertyName) 
        : base()
    {
            this.DependentPropertyName = dependentPropertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // Get the property we need to see if we need to perform validation
        PropertyInfo property = validationContext.ObjectType.GetProperty(this.DependentPropertyName);
        object propertyValue = property.GetValue(validationContext.ObjectInstance, null);

        // ... logic specific to my attribute

        return ValidationResult.Success;
    }


}

文字列を使用せずにdependentPropertyNameを検証属性に渡す方法があれば...


アップデート:

C#6.0では、文字列を使用せずにdependentPropertyNameを呼び出す方法があります。nameof(thePropertyName)を使用するだけで、文字列に置き換えられます。これはコンパイル時に発生するため、プロパティ名を変更すると、これも変更する必要があることがすぐにわかります。または、さらに良いことに、Ctrl+ RCtrl+Rを実行して変数の名前を変更すると、nameof内のバージョンの名前も自動的に変更されます。素晴らしい!

参照:nameof(C#およびVisual Basicリファレンス)

于 2012-11-07T16:08:53.113 に答える