How N level object convert to N level Dictionary<string,object> this object can be Enumerable<Dictionary<string,object>> or object (without Json.Net)

Viewed 18

How N level object convert to N level Dictionary<string,object> this object can be Enumerable<Dictionary<string,object>> or object and without Json.Net

input :

    var department = new
    {
        ID = "S001",
        Name = "HR",
        Users = new[]{
            new {ID="E001",Name="Jack"},
            new {ID="E002",Name="Terry"},
            new {ID="E003",Name="Jassie"},
        },
        ChildDepartments = new[] {"D004","D005","D006"}
    };

convert to data like

    var expectedResult = new Dictionary<string, object>
    {
        ["ID"] = "S001",
        ["Name"] = "HR",
        ["Users"] = new List<Dictionary<string, object>>{
            new Dictionary<string,object>{["ID"]="E001",["Name"]="Jack"},
            new Dictionary<string,object>{["ID"]="E002",["Name"]="Terry"},
            new Dictionary<string,object>{["ID"]="E003",["Name"]="Jassie"},
        },
        ["ChildDepartments"] = new[] {"D004","D005","D006"}
    };

Below is what I tried, only can support 2 level, it can't support than 2 level

internal static Dictionary<string, object> ToDictionary(object value)
{
    if (value == null)
        return new Dictionary<string, object>();
    else if (value is Dictionary<string, object> dicStr)
        return dicStr;
    else if (value is ExpandoObject)
        return new Dictionary<string, object>(value as ExpandoObject);

    if (IsStrongTypeEnumerable(value))
        throw new Exception("The parameter cannot be a collection type");
    else
    {
        Dictionary<string, object> reuslt = new Dictionary<string, object>();
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value);
        foreach (PropertyDescriptor prop in props)
        {
            object val1 = prop.GetValue(value);
            if (IsStrongTypeEnumerable(val1))
            {
                List<Dictionary<string, object>> sx = new List<Dictionary<string, object>>();
                foreach (object val1item in (IEnumerable)val1)
                {
                    if (val1 == null)
                    {
                        sx.Add(new Dictionary<string, object>());
                        continue;
                    }
                    else if (val1 is Dictionary<string, object> dicStr)
                    {
                        sx.Add(dicStr);
                        continue;
                    }
                    else if (val1 is ExpandoObject)
                    {
                        sx.Add(new Dictionary<string, object>(value as ExpandoObject));
                        continue;
                    }

                    PropertyDescriptorCollection props2 = TypeDescriptor.GetProperties(val1item);
                    Dictionary<string, object> reuslt2 = new Dictionary<string, object>();
                    foreach (PropertyDescriptor prop2 in props2)
                    {
                        object val2 = prop2.GetValue(val1item);
                        reuslt2.Add(prop2.Name, val2);
                    }
                    sx.Add(reuslt2);
                }
                reuslt.Add(prop.Name, sx);
            }
            else
            {
                reuslt.Add(prop.Name, val1);
            }
        }
        return reuslt;
    }
}
internal static bool IsStrongTypeEnumerable(object obj)
{
    return obj is IEnumerable && !(obj is string) && !(obj is char[]) && !(obj is string[]);
}
0 Answers
Related