Is there an easy way to convert object properties to a dictionary

I have a database object (a row), that has lots of properties (columns) that map to form fields (asp:textbox, asp:dropdownlist etc). I would like to transform this object and properties into a dictionary map to make it easier to iterate.

Example:

Dictionary<string, string> FD = new Dictionary<string,string>();
FD["name"] = data.name;
FD["age"] = data.age;
FD["occupation"] = data.occupation;
FD["email"] = data.email;
..........

How would I do this easily, without manually typing out all the various 100s of properties?

Note: FD dictionary indices are same as database column names.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Assuming that data is some object and that you want to put its public properties into a Dictionary then you could try:

Original – here for historical reasons (2012):

Dictionary<string, string> FD = (from x in data.GetType().GetProperties() select x)
    .ToDictionary (x => x.Name, x => (x.GetGetMethod().Invoke (data, null) == null ? "" : x.GetGetMethod().Invoke (data, null).ToString()));

Updated (2017):

Dictionary<string, string> dictionary = data.GetType().GetProperties()
    .ToDictionary(x => x.Name, x => x.GetValue(data)?.ToString() ?? "");

Method 2

The HtmlHelper class allows a conversion of Anonymouns Object to RouteValueDictonary and I suppose you could use a .ToString() on each value to get the string repersentation:

 var linkAttributes = System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(linkHtmlAttributes);

The down side is this is part of the ASP.NET MVC Framework. Using a .NET Reflector, the code inside of the method is as follows:

public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }

You’ll see that this code is identical to the answer Yahia gave you, and his answer provides a Dictonary<string,string>. With the reflected code I gave you you could easily convert a RouteValueDictionary to Dictonary<string,string> but Yahia’s answer is a one liner.

EDIT – I’ve added the code for what could be a method to do your conversion:

EDIT 2 – I’ve added null checking to the code and used String.Format for the string value

    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }

And to go from a Dictionary to an object check http://automapper.org/ which was suggested in this thread
Convert dictionary to anonymous object

Method 3

var myDict = myObj.ToDictionary(); //returns all public fields & properties

.

public static class MyExtensions
{
    public static Dictionary<string, object> ToDictionary(this object myObj)
    {
        return myObj.GetType()
            .GetProperties()
            .Select(pi => new { Name = pi.Name, Value = pi.GetValue(myObj, null) })
            .Union( 
                myObj.GetType()
                .GetFields()
                .Select(fi => new { Name = fi.Name, Value = fi.GetValue(myObj) })
             )
            .ToDictionary(ks => ks.Name, vs => vs.Value);
    }
}

Method 4

Take a look at System.ComponentModel.TypeDescriptor.GetProperties( ... ). This is the way the normal data binding bits work. It will use reflection and return you a collection of property descriptors (which you can use to get the values). You can customize these descriptors for performace by implementing ICustomTypeDescriptor .


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x