Get Values From Complex Class Using Reflection
c#, reflection, xml
Solution
You are trying to type cast a complex values type to string value so you lost the data. Instead use following code:
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.Name = "Person One";
person.Location = "India";
person.Emails = new PersonEmails();
person.Phones = new PersonPhones();
person.Emails.Emails = new PersonEmail[] { new PersonEmail() { Type = "Official", Value = "xyz@official.com" }, new PersonEmail() { Type = "Personal", Value = "xyz@personal.com" } };
person.Phones.Phones = new PersonPhone[] { new PersonPhone() { Type = "Official", Value = "789-456-1230" }, new PersonPhone() { Type = "Personal", Value = "123-456-7890" } };
List<ObjectField> fields = new List<ObjectField>();
fields = GetPropertyValues(person);
}
static List<ObjectField> GetPropertyValues(object obj)
{
List<ObjectField> propList = new List<ObjectField>();
foreach (PropertyInfo pinfo in obj.GetType().GetProperties())
{
var value = pinfo.GetValue(obj, null);
if (pinfo.PropertyType.IsArray)
{
var arr = value as object[];
for (var i = 0; i < arr.Length; i++)
{
if (arr[i].GetType().IsPrimitive)
{
propList.Add(new ObjectField() { Name = pinfo.Name + i.ToString(), Value = arr[i].ToString() });
}
else
{
var lst = GetPropertyValues(arr[i]);
if (lst != null && lst.Count > 0)
propList.AddRange(lst);
}
}
}
else
{
if (pinfo.PropertyType.IsPrimitive || value.GetType() == typeof(string))
{
propList.Add(new ObjectField() { Name = pinfo.Name, Value = value.ToString() });
}
else
{
var lst = GetPropertyValues(value);
if (lst != null && lst.Count > 0)
propList.AddRange(lst);
}
}
}
return propList;
}
}
Problem
I have a class, which is created and populated from an xml string, I've simplified it for example purposes: ``` [XmlRoot("Person")] public sealed class Person { [XmlElement("Name")] public string Name { get; set; } [XmlElement("Location")] public string Location { get; set; } [XmlElement("Emails", Type = typeof(PersonEmails)] public PersonEmails Emails { get; set; } } public class PersonEmails { [XmlElement("Email", Type = typeof(PersonEmail))] public PersonEmail[] Emails { get; set; } } public class PersonEmail { [XmlAttribute("Type")] public string Type { get; set; } [XmlText] public string Value { get; set; } } ``` To extract the information, I'm trying to load them into another class, which is simply: ``` public class TransferObject { public string Name { get; set; } public ObjectField[] Fields { get; set; } } public class ObjectField { public string Name { get; set; } public string Value { get; set; } } ``` I'm only populating "Fields" from the other object, which would simply be (Name = "Location", Value = "London"), but for Emails, (Name = "Email"+Type, Value = jeff@here.com) Currently I can populate all the other fields, but I'm stuck with Emails, and knowing how to dig deep enough to be able to use reflection (or not) to get the information I need. Currently I'm using: ``` Person person = Person.FromXmlString(xmlString); List<ObjectField> fields = new List<ObjectField>(); foreach (PropertyInfo pinfo in person.getType().GetProperties() { fields.Add(new ObjectField { Name = pinfo.Name, Value = pinfo.getValue(person, null).ToString(); } ``` How can I expand on the above to add all my emails to the list?