Home > database >  Get property names of a object as a Dictionary<string,string> in .net
Get property names of a object as a Dictionary<string,string> in .net

Time:01-13

I working on a string tokenizer function.

This is the sample object

    var obj= new
    {
        Order= new
        {
            CustomerName = "John",
            OrderTotal= "10.50",
            Qty =2,
            Address= new
            {
                Street= "Park Road",
                Country= "UAS"
            }
        }
    };

I need to get property vs values onto Dictionary<string, string>

expecting result :

     <Order.CustomerName,"John">
     <Order.OrderTotal,"10.50">
     <Order.Qty ,"2">
     <Order.CustomerName.Address.Street,"Park Road">
     <Order.CustomerName.Address.Country,"USA">

This is how I tried

private Dictionary<string, string> GetValueByPropertyToken(object obj)
{
    var result = new Dictionary<string, string>();
    // get the type:
    var objType = obj.GetType();
    // iterate the properties
    var prop = (from property in objType.GetProperties() select property).ToList();

    foreach (var item in prop)
    {
        var name = item.Name;
        var nextProperty = item?.GetValue(obj);
    }

    return result;
}

CodePudding user response:

You can achieve this via recursion and reflection:

Extension.cs class:

public static class Extensions
    {
        /// <summary>
        /// Extension method for object to explode to dictionary.
        /// </summary>
        /// <param name="values"></param>
        /// <returns>Dictionary with key-value pairs for prefix and primite values</returns>
        public static IDictionary<string, object> ToDictionary(this object values)
        {
            var dict = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
            
            GetValues("", values, dict);

            return dict;
        }

        /// <summary>
        /// Recursively go through obj and explode into key-value pairs for prefix   value
        /// </summary>
        /// <param name="prefix">Prefix for key</param>
        /// <param name="obj">The object to explode</param>
        /// <param name="dict">The resulting dictionary</param>
        private static void GetValues(string prefix, object obj, Dictionary<string, object> dict)
        {
            var properties = TypeDescriptor.GetProperties(obj);
            
            // Base case
            if (properties.Count == 0) return;

            // Go through all children objects
            foreach (PropertyDescriptor property in properties)
            {
                // Get next object and prefix
                var nextObject = property.GetValue(obj);
                string nextPrefix = (String.IsNullOrEmpty(prefix) ? property.Name : $"{prefix}.{property.Name}");

                // If it´s generic we continue down the object
                // If it´s primitive we add it to the dictionary
                if (nextObject.GetType().IsGenericType)
                    GetValues(nextPrefix, nextObject, dict);
                else
                    dict.Add(nextPrefix, nextObject);
            }
        }
    }

Program.cs class:

private static void Main(string[] args)
    {
        var obj = new
        {
            Order = new
            {
                CustomerName = "John",
                OrderTotal = "10.50",
                Qty = 2,
                Address = new
                {
                    Street = "Park Road",
                    Country = "UAS"
                }
            }
        };

        var dict = obj.ToDictionary();

        foreach(string key in dict.Keys)
        {
            Console.WriteLine($"{key}: {dict[key]}");
        }
    }

The output:

Order.CustomerName: John
Order.OrderTotal: 10.50
Order.Qty: 2
Order.Address.Street: Park Road
Order.Address.Country: UAS

Be careful that this code probably won´t handle more complicated scenarios involving arrays and other complicated data structures. You will have to expand on this code to fulfill your needs.

CodePudding user response:

firslty, you did not add dictionary object (result), secondly for sub element you have to call it again.

public Dictionary<string,string> GetDictionaryByObject(object obj)
{
    {
        var dict = new Dictionary<string, string>();
        foreach (var prop in obj.GetType().GetProperties())
        {
            if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string))
            {
                dict.Add(prop.Name, prop.GetValue(obj).ToString());
            }
            else
            {
                var subDict = GetDictionaryByObject(prop.GetValue(obj));
                foreach (var subProp in subDict)
                {
                    dict.Add($"{prop.Name}.{subProp.Key}", subProp.Value);
                }
            }
        }
        return dict;
    }
}

Result:

enter image description here

  • Related