Use reflection to get a property attribute using a method called from a setter

Note. This is the answer to the previous question .

I decorate the setter property with the attribute TestMaxStringLengththat is used in the method called from the installer for verification.

Currently, the property is as follows:

public string CompanyName
{
    get
    {
        return this._CompanyName;
    }
    [TestMaxStringLength(50)]
    set
    {
        this.ValidateProperty(value);
        this._CompanyName = value;
    }
}

But I would prefer it to look like this:

[TestMaxStringLength(50)]
public string CompanyName
{
    get
    {
        return this._CompanyName;
    }
    set
    {
        this.ValidateProperty(value);
        this._CompanyName = value;
    }
}

The code for ValidatePropertythat is responsible for finding the setter attributes:

private void ValidateProperty(string value)
{
    var attributes = 
       new StackTrace()
           .GetFrame(1)
           .GetMethod()
           .GetCustomAttributes(typeof(TestMaxStringLength), true);
    //Use the attributes to check the length, throw an exception, etc.
}

How can I change the code ValidatePropertyto search for property attributes instead of the set method?

+5
source share
3 answers

, PropertyInfo MethodInfo . , , , , .. - :

var method = new StackTrace().GetFrame(1).GetMethod();
var propName = method.Name.Remove(0, 4); // remove get_ / set_
var property = method.DeclaringType.GetProperty(propName);
var attribs = property.GetCustomAttributes(typeof(TestMaxStringLength), true);

, .

, StackTrace - .

+7

, , , . , StackTrace.

void ValidateProperty(string value)
{
    var setter = (new StackTrace()).GetFrame(1).GetMethod();

    var property = 
        setter.DeclaringType
              .GetProperties()
              .FirstOrDefault(p => p.GetSetMethod() == setter);

    Debug.Assert(property != null);

    var attributes = property.GetCustomAttributes(typeof(TestMaxStringLengthAttribute), true);

    //Use the attributes to check the length, throw an exception, etc.
}
+2

, , , .

...

public class MaxStringLengthAttribute : Attribute
{
    public int MaxLength { get; set; }
    public MaxStringLengthAttribute(int length) { this.MaxLength = length; }
}

... a POCO , ...

public class MyObject
{
    [MaxStringLength(50)]
    public string CompanyName { get; set; }
}

... , .

public class PocoValidator
{
    public static bool ValidateProperties<TValue>(TValue value)
    {
        var type = typeof(TValue);
        var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var prop in props)
        {
            var atts = prop.GetCustomAttributes(typeof(MaxStringLengthAttribute), true);
            var propvalue = prop.GetValue(value, null);

            // With the atts in hand, validate the propvalue ...
            // Return false if validation fails.
        }

        return true;
    }
}
+2
source

All Articles