How to get property name by one of it's attributes' value using reflection or how to get property info of data property which is currently validating?
asp.net-mvc, c#, properties, reflection, validation
Solution
Using that code, both test passes, so the MemberName isn't null.
[TestClass]
public class RefectionInValidationTest
{
[TestMethod]
public void GivenAModelWithItemMaxAttributeOnFieldName_WhenValidating_ThenModelClassIsValid()
{
//Arange
var validModelClass = new ModelClass();
var validations = new Collection<ValidationResult>();
//Act
var isValid = Validator.TryValidateObject(validModelClass, new ValidationContext(validModelClass, null, null), validations, true);
//Assert
Assert.IsTrue(isValid);
}
[TestMethod]
public void GivenAModelWithItemMaxAttributeOnFieldNotName_WhenValidating_ThenModelClassIsInvalid()
{
//Arange
var invalidaModelClass = new InvalidModelClass();
var validations = new Collection<ValidationResult>();
//Act
var isValid = Validator.TryValidateObject(invalidaModelClass, new ValidationContext(invalidaModelClass, null, null), validations, true);
//Assert
Assert.IsFalse(isValid);
}
}
public class ModelClass
{
[ItemMaxLength(10)]
public IDictionary<string, string> Names { get; set; }
}
public class InvalidModelClass
{
[ItemMaxLength(10)]
public IDictionary<string, string> NotNames { get; set; }
}
public class ItemMaxLengthAttribute : ValidationAttribute
{
private readonly int _maxLength = int.MaxValue;
public ItemMaxLengthAttribute(int maxLength)
{
_maxLength = maxLength;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var propretyInfo = validationContext.ObjectType.GetProperty(validationContext.MemberName);
if (propretyInfo.Name == "Names")
return ValidationResult.Success;
return new ValidationResult("The property isn't 'Names'");
}
}
Problem
I want to write custom validation attribute and add additional member names which have validation errors to validation result. The thing is I want to generate member name dynamically based on property name and invalid match property index or key (I want to validate IEnumerables or IDictionaries) like `Names[0]`, `Names[1]`, `Names[key]` etc. For example: Model: ``` public class ModelClass { [ItemMaxLength(10)] [Display(ResourceType = typeof(CategoriesRename), Name = "CategoryNamesFieldName")] public IDictionary<string, string> Names { get; set; } } ``` Attribute: ``` public class ItemMaxLengthAttribute : ValidationAttribute { private readonly int _maxLength = int.MaxValue; public ItemMaxLengthAttribute(int maxLength) { _maxLength = maxLength; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { ... // I can get instance and it's type from validation context var instance = validationContext.ObjectInstance; // which is instance of ModelClass var instanceType = validationContext.ObjectType; //which is typeof(ModelClass) var dispayName = validationContext.DisplayName; //which is value of Display attribute ... } } ``` So the main idea is (I don't like it ether) get current property been validated by it's `DysplayName` attribute value (`dispayName`). I'm kind'a stuck here for a while. Maybe is there some other way to get property info of the property which is validating? P.S. I've already tried `MemberName` property, as Alexandre Rondeau suggested, but the problem is that `validationContext.MemberName = null` so it can't be used. Also MSDN says that this property represents an entity member name, not the name of a corresponding data field and I need the name of a corresponding data field.