2

Similar: How I can find Data Annotation attributes and their parameters using reflection

However, when attempting to gather the custom attribute, I always get back the same result. An empty ScriptIgnore.

PropertyInfo[] Properties = Entity.GetType().GetProperties();
foreach (PropertyInfo Property in Properties)

Upon debug, this line of code

var annotes = Property.GetCustomAttributes(typeof(ScriptIgnoreAttribute), false);

(I also tried using true)

looks like this

annotes | {System.Web.Script.Serialization.ScriptIgnoreAttribute[0]}

However, Property is defined as a class property like this

public virtual Lot Lot { get; set; }

There is no [ScriptIgnore] attribute attached. Moreover, when I have tried this on Property when it was defined like this

[ScriptIgnore]
public virtual ICollection<Lot> Lots { get; set; }

I get back the same result as above

annotes | {System.Web.Script.Serialization.ScriptIgnoreAttribute[0]}

How can I use reflection to determine if an attribute exists? Or other means if possible, I also tried

var attri = Property.Attributes;

but it did not contain any attributes.

Community
  • 1
  • 1
Travis J
  • 81,153
  • 41
  • 202
  • 273

2 Answers2

5

The following code works:

using System.Web.Script.Serialization;
public class TestAttribute
{
  [ScriptIgnore]
  public string SomeProperty1 { get; set; }

  public string SomeProperty2 { get; set; }

  public string SomeProperty3 { get; set; }

  [ScriptIgnore]
  public string SomeProperty4 { get; set; }
}

Define a static extension:

public static class AttributeExtension
{
  public static bool HasAttribute(this PropertyInfo target, Type attribType)
  {
    var attribs = target.GetCustomAttributes(attribType, false);
    return attribs.Length > 0;
  }
}

Put the following sample code into a method and it picks up the attribute correctly - including ICollection by the way:

  var test = new TestAttribute();
  var props = (typeof (TestAttribute)).GetProperties();
  foreach (var p in props)
  {
    if (p.HasAttribute(typeof(ScriptIgnoreAttribute)))
    {
      Console.WriteLine("{0} : {1}", p.Name, attribs[0].ToString());
    }
  }

  Console.ReadLine();

NOTE: if you're using EF dynamic proxy classes, I think you will need to use ObjectContext.GetObjectType() to resolve to the original class before you can get the attributes, since the EF-generated proxy class will not inherit the attributes.

code4life
  • 15,655
  • 7
  • 50
  • 82
  • I tried this: `var objType = ObjectContext.GetObjectType(typeof( T )); var propers = objType.GetProperties();` and it worked. Thank you very much. – Travis J Sep 20 '12 at 20:39
1
var props = type.GetProperties()
                .Where(p => p.GetCustomAttributes().Any(a => a is ScriptIgnoreAttribute))
                .ToList();
L.B
  • 114,136
  • 19
  • 178
  • 224
  • "No overload for `GetCustomAttributes` takes 0 arguments." – Travis J Sep 20 '12 at 19:23
  • @TravisJ I tested it before posting and it works for me. Anyway, Try `GetCustomAttributes(false)` – L.B Sep 20 '12 at 19:30
  • - It does compile with `(false)`, however it is still empty. I think this might be a result of being lazy loaded by Entity Framework and not a fault of your code. – Travis J Sep 20 '12 at 19:34
  • @TravisJ, I tested it again, and I can get the props with `ScriptIgnore` attributes. – L.B Sep 20 '12 at 19:37
  • - This is an issue with the way I am getting the type. EF returns a dynamic proxy and reflection doesn't seem to always play nicely with them. – Travis J Sep 20 '12 at 19:40
  • @TravisJ: if EF is returning a dynamic proxy, then you have to use `ObjectContext.GetObjectType()` to resolve back to the original class type and then extract the attributes. – code4life Sep 20 '12 at 19:58