chustar
chustar

Reputation: 12465

Is it possible to get the properties and associated attributes of an object?

Is it possible to get the properties and their associated attributes as a collection or property set?

The properties of the object I'm looking at have attributes for use in JSON.NET, and I'd like to find out what they all are. Afterwards, I'll try to find out which of them are not null.

Here's a sample object:

[JsonObject]
    public class Conditions
    {
        [JsonProperty("opened_since")]
        public DateTime? OpenedSince { get; set; }
        [JsonProperty("added_until")]
        public DateTime? AddedUntil { get; set; }
        [JsonProperty("opened_until")]
        public DateTime? OpenedUntil { get; set; }
        [JsonProperty("archived_until")]
        public DateTime? ArchivedUntil { get; set;
    }

Upvotes: 3

Views: 5429

Answers (4)

Srikanth Venugopalan
Srikanth Venugopalan

Reputation: 9049

Something like this? If I understand right, you need all the properties of the class that are decorated by an attribute. I didn't want to include JSON.NET reference, so have used XmlText attribute instead.

    [Test]
    public void dummy()
    {
        var conditions = new Conditions();

        var propertyInfos = conditions.GetType().GetProperties();
        propertyInfos.ForEach(x =>
            {
                var attrs = x.GetCustomAttributes(true);
                if (attrs.Any(p => p.GetType() == typeof(XmlTextAttribute)))
                {
                    Console.WriteLine("{0} {1}", x, attrs.Aggregate((o, o1) => string.Format("{0},{1}",o,o1)));
                }
            });
    }

And the class looks like this -

[XmlType]
public class Conditions
{
    [XmlText]
    public DateTime? OpenedSince { get; set; }

    [XmlText]
    public DateTime? AddedUntil { get; set; }

    [XmlText]
    public DateTime? OpenedUntil { get; set; }

    [XmlText]
    public DateTime? ArchivedUntil { get; set; }

    public string NotTobeListed { get; set; }
}

Console Output:

System.Nullable`1[System.DateTime] OpenedSince System.Xml.Serialization.XmlTextAttribute
System.Nullable`1[System.DateTime] AddedUntil System.Xml.Serialization.XmlTextAttribute
System.Nullable`1[System.DateTime] OpenedUntil System.Xml.Serialization.XmlTextAttribute
System.Nullable`1[System.DateTime] ArchivedUntil System.Xml.Serialization.XmlTextAttribute

Note that NotToBeListed doesn't show up.

Upvotes: 1

Brian Rogers
Brian Rogers

Reputation: 129707

This will give you all the properties, their attributes and the values of the arguments for the attributes (note this solution assumes you are using .net framework version 4.5):

PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in props)
{
    Console.WriteLine("Property: " + prop.Name);
    foreach (CustomAttributeData att in prop.CustomAttributes)
    {
        Console.WriteLine("\tAttribute: " + att.AttributeType.Name);
        foreach (CustomAttributeTypedArgument arg in att.ConstructorArguments)
        {
            Console.WriteLine("\t\t" + arg.ArgumentType.Name + ": " + arg.Value);
        }
    }
}

Output:

Property: OpenedSince
        Attribute: JsonPropertyAttribute
                String: opened_since
Property: AddedUntil
        Attribute: JsonPropertyAttribute
                String: added_until
Property: OpenedUntil
        Attribute: JsonPropertyAttribute
                String: opened_until
Property: ArchivedUntil
        Attribute: JsonPropertyAttribute
                String: archived_until

Upvotes: 6

chustar
chustar

Reputation: 12465

I figured out the answer after reading Chris' answer above and Marc Gravell's answer to this question

I created this function to do it for me:

    public HastTable BuildRequestFromConditions(Conditions conditions)
    {
        var ht = new HashTable();
        var properties = conditions.GetType().GetProperties().Where(a => a.MemberType.Equals(MemberTypes.Property) && a.GetValue(conditions) != null);
        properties.ForEach(property => 
            {
                var attribute = property.GetCustomAttribute(typeof(JsonPropertyAttribute));
                var castAttribute = (JsonPropertyAttribute)attribute;

                ht.Add(castAttribute.PropertyName, property.GetValue(conditions));
            });
        return request;
    }

Upvotes: 2

Chris McKelt
Chris McKelt

Reputation: 1388

Try this

public static Hashtable ConvertPropertiesAndValuesToHashtable(this object obj)
    {
        var ht = new Hashtable();

        // get all public static properties of obj type
        PropertyInfo[] propertyInfos =
            obj.GetType().GetProperties().Where(a => a.MemberType.Equals(MemberTypes.Property)).ToArray();
        // sort properties by name
        Array.Sort(propertyInfos, (propertyInfo1, propertyInfo2) => propertyInfo1.Name.CompareTo(propertyInfo2.Name));

        // write property names
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
            ht.Add(propertyInfo.Name,
                   propertyInfo.GetValue(obj, BindingFlags.Public, null, null, CultureInfo.CurrentCulture));
        }

        return ht;
    }

Upvotes: 2

Related Questions