Reputation: 2114
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"
}
}
Upvotes: 92
Views: 225815
Reputation: 28648
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.
Upvotes: 24
Reputation: 331
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.
Upvotes: 1
Reputation: 49042
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
Upvotes: 84
Reputation: 2338
use property UseSimpleDictionaryFormat
on DataContractJsonSerializer
and set it to true
.
Does the job :)
Upvotes: 16
Reputation: 145930
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"}
Upvotes: 7
Reputation: 160
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!
Upvotes: 2