3

使用 MVC4 我需要ModelMetadata从自定义的ValidationAttribute. 这样做的原因是验证属性需要知道哪些其他属性附加到正在验证的特定属性。

具体来说,它会检查该财产是否有UppercaseAttribute附属物;如果是这种情况,那么它将执行不同的逻辑路径。如果可以ModelMetadata从 中获取ValidationAttribute,我将使用以下代码进行检查:

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

首先,是否可以ModelMetadata从 custom中检索ValidationAttribute.

其次,上面的代码是检查属性是否附加了特定属性的最佳实践。

4

2 回答 2

4

回答你的第一个问题:是的。您可以访问ModelMetadata对象内的ValidationAttribute对象。最简单的方法是实现System.Web.Mvc.IMetadataAware接口。该接口有一个调用方法,该方法将在验证属性对象上OnMetadataCreated的方法之前调用。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 回答
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 回答