如何在C#中将字典转换为JSON字符串?

185
我想将我的Dictionary<int,List<int>>转换为JSON字符串。有人知道如何在C#中实现吗?

5
使用Newtonsoft.Json NuGet包。JsonConvert.SerializeObject(yourObject)。 - RayLoveless
16个回答

179

这个答案提到了Json.NET,但没有告诉你如何使用Json.NET来序列化一个字典:


return JsonConvert.SerializeObject( myDictionary );
与JavaScriptSerializer不同的是,myDictionary 不必是类型为 <string, string> 的字典才能使 JsonConvert 正常工作。

我有一个字典 result = new Dictionary<string, object>(); 当我使用 JsonConvert.SerializeObject(result) 进行序列化时,它会将数字从 1 转换为 1.0。你有什么办法可以避免这种情况发生吗? - Mali Tbt

143

仅包含数字或布尔值的数据结构序列化相对简单。如果您需要序列化的内容不多,可以为您特定的类型编写一个方法。

对于您指定的 Dictionary<int, List<int>>,您可以使用 Linq:

string MyDictionaryToJson(Dictionary<int, List<int>> dict)
{
    var entries = dict.Select(d =>
        string.Format("\"{0}\": [{1}]", d.Key, string.Join(",", d.Value)));
    return "{" + string.Join(",", entries) + "}";
}

但是,如果你要序列化几个不同的类或更复杂的数据结构,特别是当你的数据包含字符串值时,最好使用一个可靠的JSON库,它已经知道如何处理转义字符和换行符。 Json.NET 是一个受欢迎的选择。


88
这种解决方案充其量是天真的。使用一个真正的 JSON 序列化库。 - jacobsimeon
148
@Jacob - Naive?哎呀。就我个人而言,我无法证明在我只需要使用一个简短而简单的方法就可以完成任务时,包含“另一个”汇编是有道理的。 - gilly3
18
再补充一下gilly3的评论。有时候你会编写Windows Phone的代码,需要添加zlip、twitter、google、音频处理和图像处理等功能。如果您的使用方式比较简单,最好实现简单的方法以及用于社交媒体互动的基本HttpRequests。每次添加程序集时,您都必须处理错误,并且无法获取精简版。顺便说一句,在json库中,也有简单的方法,没有什么魔法。 - Léon Pelletier
15
每个开放式项目都应该有一个页面,告诉你:“嘿,大部分时间,你只需要执行这10行算法。这是代码。” - Léon Pelletier
40
dict.add("RandomKey"", "RandomValue"");这段代码很幼稚,最好使用真正的JSON序列化库。 - Sleeper Smith
显示剩余9条评论

76

Json.NET 可能已经能够充分地序列化 C# 字典,但在 OP 最初发布这个问题时,许多 MVC 开发人员可能使用 JavaScriptSerializer 类,因为它是开箱即用的默认选项。

如果你正在处理旧项目(MVC 1 或 MVC 2),且不能使用 Json.NET,我建议你使用 List<KeyValuePair<K,V>> 而不是 Dictionary<K,V>>。旧版 JavaScriptSerializer 类会很好地序列化该类型,但对字典则存在问题。

文档: 使用 Json.NET 序列化集合


3
适用于asp.net mvc3和mvc4用户的完美答案。 - Gomes
JsonConvert.SerializeObject似乎无法将C#字典序列化为可枚举集合类型,以便在读回JavaScript时使用。相反,它创建了一个对象,在该对象中,C#集合中的每个键值对现在都是对象中的普通属性/值,无法像集合一样轻松枚举。因此,除非我从NuGet获取了错误版本,否则Json.NET在这方面仍然不够好。 - StingyJack
哦,是的。我已经在做类似的事情了,但试图找到另一种方法,然后偶然发现了这个。我觉得让其他人知道可以避免为此项陷入Json.NET的兔子洞(否则效果很好)。 - StingyJack

27

简单一行回答

(使用 System.Web.Script.Serialization)

这段代码将把任何 Dictionary<Key,Value> 转换为 Dictionary<string,string>,然后将其序列化为 JSON 字符串:

var json = new JavaScriptSerializer().Serialize(yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()));

值得注意的是,像Dictionary<int,MyClass>这样的东西也可以以这种方式进行序列化,同时保留复杂类型/对象。


解释(分解)

var yourDictionary = new Dictionary<Key,Value>(); //This is just to represent your current Dictionary.

您可以将变量yourDictionary替换为您实际使用的变量。

var convertedDictionary = yourDictionary.ToDictionary(item => item.Key.ToString(), item => item.Value.ToString()); //This converts your dictionary to have the Key and Value of type string.

我们这样做的原因是,因为键和值都必须是字符串类型,这是序列化 Dictionary 的要求。

var json = new JavaScriptSerializer().Serialize(convertedDictionary); //You can then serialize the Dictionary, as both the Key and Value is of type string, which is required for serialization.

1
我在我的C#中没有JavaScriptSerializer。 - Jonny
2
@Jonny,你缺少引用程序集 System.Web.Extensions https://msdn.microsoft.com/zh-cn/library/system.web.script.serialization.javascriptserializer.aspx - aminhotob
可能是某些应用的解决方案,但如果任何对象属性不是字符串类型,则将所有值强制转换为字符串类型不会产生正确的JSON。 - Suncat2000
1
这个主题的最佳答案。 - T.Todua
1
这应该是答案。 - GunWanderer
显示剩余3条评论

26
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Json;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, List<int>> foo = new Dictionary<int, List<int>>();

            foo.Add(1, new List<int>( new int[] { 1, 2, 3, 4 }));
            foo.Add(2, new List<int>(new int[] { 2, 3, 4, 1 }));
            foo.Add(3, new List<int>(new int[] { 3, 4, 1, 2 }));
            foo.Add(4, new List<int>(new int[] { 4, 1, 2, 3 }));

            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<int, List<int>>));

            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, foo);
                Console.WriteLine(Encoding.Default.GetString(ms.ToArray()));
            }
        }
    }
}

这将会在控制台输出:

[{\"Key\":1,\"Value\":[1,2,3,4]},{\"Key\":2,\"Value\":[2,3,4,1]},{\"Key\":3,\"Value\":[3,4,1,2]},{\"Key\":4,\"Value\":[4,1,2,3]}]

15

如果语法有一点点错误,请见谅,因为我从最初的VB代码中获取了这段代码 :)

using System.Web.Script.Serialization;

...

Dictionary<int,List<int>> MyObj = new Dictionary<int,List<int>>();

//Populate it here...

string myJsonString = (new JavaScriptSerializer()).Serialize(MyObj);

3
抛出了ArgumentException异常:类型'System.Collections.Generic.Dictionary`2'不支持字典的序列化/反序列化,键必须是字符串或对象。 - Pavel Chuchuva
请参见https://dev59.com/7HA65IYBdhLWcg3wrgsa。 - Pavel Chuchuva

15
如果您的场景允许(技术限制等),请使用Newtonsoft.Json中的JsonConvert.SerializeObject方法:它将使您的生活更轻松。
Dictionary<string, string> localizedWelcomeLabels = new Dictionary<string, string>();
localizedWelcomeLabels.Add("en", "Welcome");
localizedWelcomeLabels.Add("fr", "Bienvenue");
localizedWelcomeLabels.Add("de", "Willkommen");
Console.WriteLine(JsonConvert.SerializeObject(localizedWelcomeLabels));

// Outputs : {"en":"Welcome","fr":"Bienvenue","de":"Willkommen"}

12

在 Asp.net Core 中使用:

using Newtonsoft.Json

var obj = new { MyValue = 1 };
var json = JsonConvert.SerializeObject(obj);
var obj2 = JsonConvert.DeserializeObject(json);

我引用了 System.Core,然后尝试引用 using Newtonsoft.Json,但是没有成功。我认为 Newtonsoft 是一个第三方库。 - vapcguy
2
@vapcguy 是的,Newtonsoft是第三方库,但被广泛使用和采用,也被微软在他们的产品中使用。https://www.nuget.org/packages/Newtonsoft.Json/ - Skorunka František

9

Net Core: 使用System.Text.Json.JsonSerializer.Serialize方法对字典进行序列化。


8
您可以使用 System.Web.Script.Serialization.JavaScriptSerializer:
Dictionary<string, object> dictss = new Dictionary<string, object>(){
   {"User", "Mr.Joshua"},
   {"Pass", "4324"},
};

string jsonString = (new JavaScriptSerializer()).Serialize((object)dictss);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接