I have the requirement to return the result of my ViewModel as a Dictionary of KeyValue pairs. My view model comprises of multiple classes and can have null values in properties. I need to return only values which are not null and non-zero in case of double/string
types. Following is the class I created:
public static class ObjectExtensions
{
public static IDictionary<string, dynamic> ConvertToDictionary(this object source, BindingFlags bindingAttribute = BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public)
{
IDictionary<string, dynamic> dictionary = new Dictionary<string, dynamic>();
PropertyInfo[] properties = source.GetType().GetProperties(bindingAttribute);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.PropertyType == typeof(System.String) ||
propertyInfo.PropertyType == typeof(System.Int16) ||
propertyInfo.PropertyType == typeof(System.Int32) ||
propertyInfo.PropertyType == typeof(System.Int64) ||
propertyInfo.PropertyType == typeof(System.Double) ||
propertyInfo.PropertyType == typeof(System.Decimal) ||
propertyInfo.PropertyType == typeof(System.Guid)
)
{
dynamic propertyValue = propertyInfo.GetValue(source, null);
if (propertyValue != null)
{
if (propertyValue.GetType() == typeof(double))
{
propertyValue = Math.Round(propertyValue, 4);
}
dictionary.Add(propertyInfo.Name, propertyValue);
}
}
else if (propertyInfo.PropertyType.IsGenericType)
{
dynamic propertyValue = propertyInfo.GetValue(source, null);
if (propertyValue != null)
{
if (propertyValue.GetType() == typeof(double))
{
propertyValue = Math.Round(propertyValue, 4);
}
dictionary.Add(propertyInfo.Name, propertyValue);
}
}
else
{
dynamic complexPropertyValue = propertyInfo.GetValue(source, null);
if (complexPropertyValue != null)
{
PropertyInfo[] complexProperties = complexPropertyValue.GetType().GetProperties();
foreach (PropertyInfo complexPropertyInfo in complexProperties)
{
dynamic propertyValue = complexPropertyInfo.GetValue(complexPropertyValue, null);
if (propertyValue != null)
{
if (propertyValue.GetType() == typeof(double))
{
propertyValue = Math.Round(propertyValue, 4);
}
dictionary.Add(complexPropertyInfo.Name, propertyValue);
}
}
}
}
}
FormatDictionary(dictionary);
return dictionary;
}
private static IDictionary<string, dynamic> FormatDictionary(IDictionary<string, dynamic> source)
{
foreach (var item in source)
{
if (item.Value.GetType() == typeof(int) || item.Value.GetType() == typeof(double))
{
if (item.Value == 0)
{
source.Remove(item);
}
}
if (item.Value.GetType() == typeof(string))
{
if (string.IsNullOrWhiteSpace(item.Value))
{
source.Remove(item);
}
}
}
return source;
}
}
Is it the right approach. Any feedback will be appreciated.
foreach loops
to check for nested properties. \$\endgroup\$