简体   繁体   中英

C# Deserialize dictionary with complex properties names to JSON string

I have the following dictionary, each dictionary key potentially needs to be split by '.' and represented as json object/property/array etc.

var data = new Dictionary<string, string>()
            {
                { "items.item.id", "1" },
                { "items.item.name", "test" },
                { "items.item.lines[0].id", "1" },
                { "items.item.lines[0].name", "testName" },
                { "items.item.lines[1].id", "2" },
                { "items.item.fixture.id", "fid1" }
            };

So the first two entries in the property name are the root item representation, and items that contain [.*] - are array items that could contain their own properties or nested objects. The last entry represents the property name. If we have an entry between root and property items.item. fixture .id, we should represent this as the nested object.

I need to deserialize it to JSON and get the following as a result:

{
    "id": "1",
    "name": "test",
    "lines": [{
            "id": "1",
            "name": "testName"
        },
        {
            "id": "2"
        }
    ],
    "fixture": {
        "id": "fid1"
    }
}

I'm trying to do it this way, but stuck

public static string DictionaryToJson(Dictionary<string, string> dict, Dictionary<string, string> typesMapping, string mainEntityName = "item")
        {
            JObject jo = new JObject();

            foreach (var pair in dict)
            {
                bool mainPropertyChecked = false;

                string[] array = pair.Key.Split('.');
                for (int i = 0; i < array.Length; i++)
                {
                    string prop = array[i];
                    if (string.Equals(mainEntityName, prop, StringComparison.OrdinalIgnoreCase))
                    {
                        mainPropertyChecked = true;
                    }

                    if (!mainPropertyChecked)
                        continue;

                    if (prop.EndsWith("]"))
                    {
                        JArray arrayProp = new JArray();
                        // Array item processing
                    }
                    
                    
                }
            }
            
            return jo.ToString();
        }

try this

    var origJsonObj = JObject.FromObject(data);
    var jsonObj = new JObject();

    foreach (var prop in origJsonObj.Properties())
    {
        var arr = prop.Name.Replace("items.item.", "").Split('.');
        var name = arr[0];

        if (arr.Length == 1)
        {
            jsonObj.Add(name, prop.Value);
            continue;
        }
    
        if (name.Contains("["))
        {
            name = name.Substring(0, name.IndexOf("["));
            var index = Convert.ToInt16(arr[0].Substring(arr[0].IndexOf("[") + 1).Replace("]", ""));

            if (jsonObj[name] == null) jsonObj[name] = new JArray();

            JObject jo = null;
            while (((JArray)jsonObj[name]).Count() < index + 1)
            {
                jo = new JObject();
                ((JArray)jsonObj[name]).Add(jo);
            }
            jo = (JObject)jsonObj[name].ElementAt(index);
            jo.Add(arr[1], prop.Value);
            continue;
        }
        if (jsonObj[name] == null) jsonObj.Add(new JProperty(name, new JObject()));
        ((JObject)jsonObj[name]).Add(arr[1], prop.Value);
    }

result

{
  "id": "1",
  "name": "test",
  "lines": [
    {
      "id": "1",
      "name": "testName"
    },
    {
      "id": "2"
    }
  ],
  "fixture": {
    "id": "fid1"
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM