使用MVC4我需要从自定义ModelMetadata
中检索当前ValidationAttribute
。原因是验证属性需要知道哪些其他属性附加到正在验证的特定属性。
具体而言,检查该物业是否附有UppercaseAttribute
;如果是这种情况,那么它将执行不同的逻辑路径。如果可以从ModelMetadata
中抓取ValidationAttribute
,我将使用以下代码进行检查:
ModelMetadata.ContainerType
.GetProperty(ViewData.ModelMetadata.PropertyName)
.GetCustomAttributes(typeof(UppercaseAttribute), true)
首先,是否可以从自定义ModelMetadata
中检索ValidationAttribute
。
其次,上面的代码是检查属性是否附加了特定属性的最佳实践。
答案 0 :(得分: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,因此您必须根据其显示名称获取属性名称。
答案 1 :(得分:3)
回答你的第一个问题:是的。您可以访问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;
}
}