简体   繁体   English

如何通过其中一个属性的值使用反射来获取属性名称,或者如何获取当前正在验证的数据属性的属性信息?

[英]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?

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: 问题是我想根据属性名称和无效匹配属性索引或键动态生成成员名称(我想验证IEnumerables或IDictionaries),如Names[0]Names[1]Names[key]等。例如:

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 ). 所以主要的想法是(我不喜欢它)以获取当前属性的DysplayName属性值( 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? 也许是否有其他方法来获取正在验证的属性的属性信息?

PS I've already tried MemberName property, as Alexandre Rondeau suggested, but the problem is that validationContext.MemberName = null so it can't be used. PS我已经尝试过MemberName属性,正如Alexandre Rondeau所说,但问题是validationContext.MemberName = null因此无法使用。 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 . MSDN也这个属性代表一个实体成员名,而不是相应数据字段 的名称,我需要相应数据字段 的名称

Using that code, both test passes, so the MemberName isn't null. 使用该代码,两个测试传递,因此MemberName不为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'");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM