将字典的C#JSON序列化为{key:value,…}而不是{key:key,value:value,…}


71

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

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

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

我对DataContractJsonSerializer的结果很感兴趣!我已经找到一个“代理”示例,但是输出中还有一个附加的“数据”,如果字典<K,String>是,转义也是假的。


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

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

7
您要限制在DataContractJsonSerializer什么特定原因上?每次进行比较时(这是几次:我非常“喜欢”我的序列化器),这是.NET中最不推荐使用的JSON工具。我总是看JavaScriptSerializer或JSON.Net
Marc Gravell

您在什么情况下使用此功能?这就是WCF应用程序,ASP.NET应用程序或其他东西。您是否正在以自己调用WriteObject的方式使用DataContractJsonSerilizer或某个框架正在为您执行此操作?
Shiv Kumar,

您的帖子中不清楚的是您想要1个JSON对象,其属性(及其值)是字典中的名称/值对。这是错误的,因为它不能是JSON数组,因为您不能拥有一个JSON数组,其中数组中的每个元素具有不同的属性名称。因此,您可以清楚要获取的实际格式吗?
Shiv Kumar

1
有人发现相反吗?像这样,如何使其MyJsonDictionary正确反序列化?
drzaus

5
您不应该在编辑中回答自己的问题。而是实际添加答案,请编辑您的问题并添加答案作为答案
Liam 2013年

Answers:


60

Json.NET做到了...

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

更多示例:使用Json.NET序列化集合


第二行应该是string values = JsonConvert.SerializeObject(values);
sandeep talabathula

13

UseSimpleDictionaryFormat在上使用属性DataContractJsonSerializer并将其设置为true

做工作:)


序列化HTTP响应时,如何为wcf的默认行为设置该设置?
万隆

为我工作,谢谢!我不得不使用config.Formatters.JsonFormatter.UseDataContractJsonSerializer = true;WebApiConfig.cs
SharpC

5

我正在使用现成的MVC4代码(请注意其中的两个参数ToDictionary

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

我得到了预期的结果:

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

重要提示:MVC4中的WebAPI开箱即用使用JSON.NET序列化,但是标准WebJsonResult操作结果却没有。因此,我建议使用自定义ActionResult强制JSON.NET序列化。您还可以获得很好的格式

这是一个简单的动作结果 JsonNetResult

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

序列化日期时,您会看到不同之处(并可以确保使用的是正确的):

微软方式:

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

JSON.NET方式:

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


0

MyJsonDictionary类对我来说效果很好,除了结果输出是XML编码的-因此“ 0”变为“ 0030 ”。目前,我和其他许多人一样仍停留在.NET 3.5上,因此许多其他解决方案对我不可用。“翻过来的图片”,我意识到我永远无法说服微软给我我想要的格式,但是...

string json = XmlConvert.DecodeName(xmlencodedJson);

TADA!

结果就是您期望看到的-常规的人类可读和非XML编码。在.NET 3.5中工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.