将 Dictionary 序列化为{ key: value,... }而不是{ key: key,value: value,... }

是否可以使用 DataContractJsonSerializer将.Net Dictionary < Key,Value > 序列化为 JSON,其格式如下:

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

我使用 Dictionary < K,V > ,因为没有预定义的输入结构。

我只对 DataContractJsonSerializer的结果感兴趣!我已经找到了一个“替代”示例,但是在输出中有一个额外的“数据”,如果字典 < K,String > 是,那么转义也是假的。


我已经找到了解决方案,多么需要! 首先,一个可序列化的“ dictionary”类: (当然,这个示例只以一种方式工作,但是我不需要反序列化)

[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 ]; }
}
}

用法:

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();
}
}

结果就是:

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

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!

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"}

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

use property UseSimpleDictionaryFormat on DataContractJsonSerializer and set it to true.

Does the job :)

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.

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.