Reputation: 12465
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
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
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
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
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