C# JSON Serialization of Dictionary into {key:value, ...} instead of {key:key, value:value, ...}

C#JsonSerializationDictionary

C# Problem Overview


Is it possible to serialize a .Net Dictionary<Key,Value> into JSON with DataContractJsonSerializer that is of the format:

{
  key0:value0,
  key1:value1,
  ...
}

I use Dictionary <K,V>, because there is not predefined structure of the inputs.

I'm interesting just for DataContractJsonSerializer result! I've already found a "Surrogate" example, but there is an additional "data" in the output, and if the dictionary <K, String> is, the escaping is false too.


I've found the solution, what a needed! First of all, a serializable "dictionary" class: (Of course, this sample works just in one way, but I dont't need deserialization)

[Serializable]
public class MyJsonDictionary<K, V> : ISerializable {
	Dictionary<K, V> dict = new Dictionary<K, V>();
	
	public MyJsonDictionary() { }

	protected MyJsonDictionary( SerializationInfo info, StreamingContext context ) {
		throw new NotImplementedException();
	}

	public void GetObjectData( SerializationInfo info, StreamingContext context ) {
		foreach( K key in dict.Keys ) {
			info.AddValue( key.ToString(), dict[ key ] );
		}
	}

	public void Add( K key, V value ) {
		dict.Add( key, value );
	}
	
	public V this[ K index ] {
		set { dict[ index ] = value; }
		get { return dict[ index ]; }
	}
}

Usage:

public class MainClass {
	public static String Serialize( Object data ) {
		var serializer = new DataContractJsonSerializer( data.GetType() );
		var ms = new MemoryStream();
		serializer.WriteObject( ms, data );

		return Encoding.UTF8.GetString( ms.ToArray() );
	}

	public static void Main() {
		MyJsonDictionary<String, Object> result = new MyJsonDictionary<String, Object>();
		result["foo"] = "bar";
		result["Name"] = "John Doe";
		result["Age"] = 32;
		MyJsonDictionary<String, Object> address = new MyJsonDictionary<String, Object>();
		result["Address"] = address;
		address["Street"] = "30 Rockefeller Plaza";
		address["City"] = "New York City";
		address["State"] = "NY";

		Console.WriteLine( Serialize( result ) );

		Console.ReadLine();
	}
}

And the result:

{
      "foo":"bar",
      "Name":"John Doe",
      "Age":32,
      "Address":{
         "__type":"MyJsonDictionaryOfstringanyType:#Json_Dictionary_Test",
         "Street":"30 Rockefeller Plaza",
         "City":"New York City",
         "State":"NY"
      }
   }

C# Solutions


Solution 1 - C#

Json.NET does this...

Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("key1", "value1");
values.Add("key2", "value2");

string json = JsonConvert.SerializeObject(values);
// {
//   "key1": "value1",
//   "key2": "value2"
// }

More examples: Serializing Collections with Json.NET

Solution 2 - C#

use property UseSimpleDictionaryFormat on DataContractJsonSerializer and set it to true.

Does the job :)

Solution 3 - C#

I'm using out of the box MVC4 with this code (note the two parameters inside ToDictionary)

 var result = new JsonResult()
 {
     Data = new
     {
         partials = GetPartials(data.Partials).ToDictionary(x => x.Key, y=> y.Value)
     }
 };

I get what's expected:

{"partials":{"cartSummary":"\u003cb\u003eCART SUMMARY\u003c/b\u003e"}}

Important: WebAPI in MVC4 uses JSON.NET serialization out of the box, but the standard web JsonResult action result doesn't. Therefore I recommend using a custom ActionResult to force JSON.NET serialization. You can also get nice formatting

Here's a simple actionresult JsonNetResult

http://james.newtonking.com/archive/2008/10/16/asp-net-mvc-and-json-net.aspx

You'll see the difference (and can make sure you're using the right one) when serializing a date:

Microsoft way:

 {"wireTime":"\/Date(1355627201572)\/"}

JSON.NET way:

 {"wireTime":"2012-12-15T19:07:03.5247384-08:00"}

Solution 4 - C#

In .NET 5 and later, you can simply write:

using System;
using System.Collections.Generic;
					
public class Program
{
	public static void Main()
	{
		Dictionary<string, string> values = new();
        values.Add("key1", "value1");
        values.Add("key2", "value2");

        string json = System.Text.Json.JsonSerializer.Serialize(values);
		Console.WriteLine(json);
	}
}

to get {"key1":"value1","key2":"value2"}.

No external dependency is needed.

Solution 5 - C#

Unfortunately, this is not currently possible in the latest version of DataContractJsonSerializer. See: http://connect.microsoft.com/VisualStudio/feedback/details/558686/datacontractjsonserializer-should-serialize-dictionary-k-v-as-a-json-associative-array

The current suggested workaround is to use the JavaScriptSerializer as Mark suggested above.

Good luck!

Solution 6 - C#

The MyJsonDictionary class worked well for me EXCEPT that the resultant output is XML encoded - so "0" becomes "0030". I am currently stuck at .NET 3.5, as are many others, so many of the other solutions are not available to me. "Turns the pictures" upside down and realized I could never convince Microsoft to give me the format I wanted but...

string json = XmlConvert.DecodeName(xmlencodedJson);

TADA!

The result is what you would expect to see - regular human readable and non-XML encoded. Works in .NET 3.5.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAaaaaaaaView Question on Stackoverflow
Solution 1 - C#James Newton-KingView Answer on Stackoverflow
Solution 2 - C#Maziar TaheriView Answer on Stackoverflow
Solution 3 - C#Simon_WeaverView Answer on Stackoverflow
Solution 4 - C#MartyIXView Answer on Stackoverflow
Solution 5 - C#Justin FylesView Answer on Stackoverflow
Solution 6 - C#Mark Z. KumlerView Answer on Stackoverflow