1

In C# I have a dictionary like:

Dictionary<string,string> dict=new Dictionary<string,string>(); dict.Add("User.Info","Your info"); dict.Add("User.Profile","Profile"); dict.Add("Menu.System.Task","Tasks"); var output=dict??? return Json(output); 

And I would like to change something like:

"User": { "Info": "Your info", "Profile": "Profile" }, "Menu": { "System": { "Task": "Tasks" } } } 

Split the key by dot,then convert into nested key value pair, because I'm doing the language resource files for angular2,and is there any way to archieve this?thanks

4 Answers 4

3

Using a recursive function you can do this, supporting any number of "key levels" (any number of dots)

Function:

private static void SetValues(string[] keys, int keyIndex, string value, IDictionary<string, object> parentDic) { var key = keys[keyIndex]; if (keys.Length > keyIndex + 1) { object childObj; IDictionary<string, object> childDict; if (parentDic.TryGetValue(key, out childObj)) { childDict = (IDictionary<string, object>)childObj; } else { childDict = new Dictionary<string, object>(); parentDic[key] = childDict; } SetValues(keys, keyIndex + 1, value, childDict); } else { parentDic[key] = value; } } 

Example:

 Dictionary<string, string> dict = new Dictionary<string, string>(); dict.Add("User.Info", "Your info"); dict.Add("User.Profile", "Profile"); dict.Add("Menu.System.Task", "Tasks"); dict.Add("Menu.System.Configuration.Number", "1"); dict.Add("Menu.System.Configuration.Letter", "A"); var outputDic = new Dictionary<string, object>(); foreach (var kvp in dict) { var keys = kvp.Key.Split('.'); SetValues(keys, 0, kvp.Value, outputDic); } var json = JsonConvert.SerializeObject(outputDic); 

Output:

{ "User": { "Info": "Your info", "Profile": "Profile" }, "Menu": { "System": { "Task": "Tasks", "Configuration": { "Number": "1", "Letter": "A" } } } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Great!but finally I found there would be a problem is each must have same number of level,ex dict.Add("User.Profile", "Profile"); dict.Add("User.Profile.Title", "Your profile"); this will occur error,so finally I got remove all the dot and use simple string.
The structure wouldn't make in the given example? You would want a property user.profile, with a value "profile", but also a property use.profile, which had a dictionary of values such as title and "your profile"?
3

You can achieve by overriding the WriteJson method in JsonConverter.

class CustomJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { bool result = typeof(Dictionary<string,string>).IsAssignableFrom(objectType); return result; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { JObject jo = new JObject(); foreach (var item in (Dictionary<string,string>)value) { if (item.Key.Contains(".")) { if (jo.Property(item.Key.Split('.')[0].ToString()) == null) { jo.Add(item.Key.Split('.')[0], new JObject() { { item.Key.Split('.')[1], item.Value } }); } else { var result = jo.Property(item.Key.Split('.')[0].ToString()).Value as JObject; ; result.Add(item.Key.Split('.')[1], item.Value); } } else { jo.Add(item.Key, item.Value); } } jo.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } } 

Example:

 Dictionary<string, string> dict = new Dictionary<string, string>(); dict.Add("User.Info", "Your info"); dict.Add("User.Profile", "Profile"); dict.Add("Menu.System.Task", "Tasks"); JsonSerializerSettings obj = new JsonSerializerSettings(); obj.Converters.Add(new CustomJsonConverter()); var output1 = JsonConvert.SerializeObject(dict,obj); 

Output:

{"User":{"Info":"Your info","Profile":"Profile"},"Menu":{"System":"Tasks"}} 

Comments

0

Here is one way via using multiple levels:

 Dictionary<string, object> dict = new Dictionary<string, object>(); var user = new Dictionary<string, string>(); user.Add("Info", "Your info"); user.Add("Profile", "Profile"); var menu = new Dictionary<string, object>(); var system = new Dictionary<string, string>(); system.Add("Task", "Tasks"); menu.Add("System", system); dict.Add("User", user); dict.Add("Menu", menu); string output = JsonConvert.SerializeObject(dict); Console.WriteLine(output); 

Output:

{"User":{"Info":"Your info","Profile":"Profile"},"Menu":{"System":{"Task":"Tasks "}}}

p/s: You need to add reference Newtonsoft.Json to run this example. Reference link: Serializing and Deserializing JSON

Hope this helps!

Comments

0

maybe you can to see about "System.Dynamic.ExpandoObject"

1 Comment

It should be a comment not an answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.