Reputation: 580
I need to get the Name and Value of all properties of each object. Some of them are reference type so if I get the following objects:
public class Artist {
public int Id { get; set; }
public string Name { get; set; }
}
public class Album {
public string AlbumId { get; set; }
public string Name { get; set; }
public Artist AlbumArtist { get; set; }
}
When getting the properties from the Album
object I would need also to get the values of properties AlbumArtist.Id
and AlbumArtist.Name
which are nested.
I have the following code so far, but it triggers the System.Reflection.TargetException when trying to get the value of the nested ones.
var valueNames = new Dictionary<string, string>();
foreach (var property in row.GetType().GetProperties())
{
if (property.PropertyType.Namespace.Contains("ARS.Box"))
{
foreach (var subProperty in property.PropertyType.GetProperties())
{
if(subProperty.GetValue(property, null) != null)
valueNames.Add(subProperty.Name, subProperty.GetValue(property, null).ToString());
}
}
else
{
var value = property.GetValue(row, null);
valueNames.Add(property.Name, value == null ? "" : value.ToString());
}
}
So in the If
statement I just check if the property is under the namespace of my reference types, if it is I should get all the nested properties values but that's where the exception is raised.
Upvotes: 3
Views: 8070
Reputation: 9040
This fails because you are trying to get an Artist
property on a PropertyInfo
instance:
if(subProperty.GetValue(property, null) != null)
valueNames.Add(subProperty.Name, subProperty.GetValue(property, null).ToString());
As I understand you need the values from the Artist
instance which is nested inside the row
object (which is an Album
instance).
So you should change this:
if(subProperty.GetValue(property, null) != null)
valueNames.Add(subProperty.Name, subProperty.GetValue(property, null).ToString());
to this:
var propValue = property.GetValue(row, null);
if(subProperty.GetValue(propValue, null) != null)
valueNames.Add(subProperty.Name, subProperty.GetValue(propValue, null).ToString());
Full (with a little change to avoid calling GetValue when we don't need)
var valueNames = new Dictionary<string, string>();
foreach (var property in row.GetType().GetProperties())
{
if (property.PropertyType.Namespace.Contains("ATG.Agilent.Entities"))
{
var propValue = property.GetValue(row, null);
foreach (var subProperty in property.PropertyType.GetProperties())
{
if(subProperty.GetValue(propValue, null) != null)
valueNames.Add(subProperty.Name, subProperty.GetValue(propValue, null).ToString());
}
}
else
{
var value = property.GetValue(row, null);
valueNames.Add(property.Name, value == null ? "" : value.ToString());
}
}
Also, you may run into situations when the property names are duplicated, so your IDictionary<,>.Add
will fail. I suggest to use something more reliable naming here.
For example: property.Name + "." + subProperty.Name
Upvotes: 5