3

MVC4 を使用しModelMetadataて、 custom 内からcurrent を取得する必要がありますValidationAttribute。これは、検証属性が、検証対象の特定のプロパティに他のどの属性が関連付けられているかを認識している必要があるためです。

具体的には、プロパティにUppercaseAttributeアタッチされているかどうかを確認します。この場合、別のロジック パスが実行されます。ModelMetadata内からを取得できる場合はValidationAttribute、次のコードを使用して確認します。

ModelMetadata.ContainerType
    .GetProperty(ViewData.ModelMetadata.PropertyName)
    .GetCustomAttributes(typeof(UppercaseAttribute), true)

ModelMetadataまず、 custom 内からを取得することは可能ですかValidationAttribute

次に、上記のコードは、プロパティに特定の属性が関連付けられているかどうかを確認するためのベスト プラクティスですか。

4

2 に答える 2

4

できることは次のとおりです。

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    var model = validationContext.ObjectInstance;

    var displayName = validationContext.DisplayName;
    var propertyName = model.GetType().GetProperties()
        .Where(p => p.GetCustomAttributes(false).OfType<DisplayAttribute>().Any(a => a.Name == displayName))
        .Select(p => p.Name).FirstOrDefault();
    if (propertyName == null)
        propertyName = displayName;

    var property = model.GetType().GetProperty(propertyName);
    var uppercaseAttribute = property.GetCustomAttributes(typeof(UppercaseAttribute), false).SingleOrDefault() as UppercaseAttribute;

    if (uppercaseAttribute != null)
    {
        // some code...
    }

    // return validation result...
}

何らかの理由で、validationContext.MemberName は常に null であるため、表示名に基づいてプロパティ名を取得する必要があります。

于 2013-07-22T18:15:24.753 に答える
4

最初の質問に答えるには: はい。ModelMetadataオブジェクト内のオブジェクトにアクセスできValidationAttributeます。System.Web.Mvc.IMetadataAwareこれを行う最も簡単な方法は、インターフェイスを実装することです。インターフェイスには、検証属性オブジェクトOnMetadataCreatedのメソッドの前に呼び出されるメソッドが 1 つあります。IsValidこのメソッドは、現在の ModelMetadata オブジェクトを受け取るために使用されます。次のコードは、使用方法を示しています。

   public class MyCustomValidationAttribute : ValidationAttribute, IMetadataAware
    {
        private readonly object _typeId = new object();
        private ModelMetadata _metadata;

        public MyCustomValidationAttribute()
        {
        }

        public override object TypeId
        {
            get
            {
                return _typeId;
            }
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            //Do something with the meta data
            string propertyName = _metadata.PropertyName;

            return ValidationResult.Success;
        }

        public void OnMetadataCreated(ModelMetadata metadata)
        {
            _metadata = metadata;         
        }
    }
于 2014-08-12T11:22:01.657 に答える