简体   繁体   English

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

[英]How do I convert a dictionary to a JSON String in C#?

I want to convert my Dictionary<int,List<int>> to JSON string.我想将我的Dictionary<int,List<int>>转换为 JSON 字符串。 Does anyone know how to achieve this in C#?有谁知道如何在 C# 中实现这一点?

This answer mentions Json.NET but stops short of telling you how you can use Json.NET to serialize a dictionary:这个答案提到了 Json.NET,但没有告诉你如何使用 Json.NET 来序列化字典:

return JsonConvert.SerializeObject( myDictionary );

As opposed to JavaScriptSerializer, myDictionary does not have to be a dictionary of type <string, string> for JsonConvert to work.与 JavaScriptSerializer 不同, myDictionary不必是<string, string>类型的字典才能让 JsonConvert 工作。

Serializing data structures containing only numeric or boolean values is fairly straightforward.序列化仅包含数字或布尔值的数据结构相当简单。 If you don't have much to serialize, you can write a method for your specific type.如果您没有太多要序列化的内容,您可以为您的特定类型编写一个方法。

For a Dictionary<int, List<int>> as you have specified, you can use Linq:对于您指定的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) + "}";
}

But, if you are serializing several different classes, or more complex data structures, or especially if your data contains string values , you would be better off using a reputable JSON library that already knows how to handle things like escape characters and line breaks.但是,如果您要序列化几个不同的类,或更复杂的数据结构,或者特别是如果您的数据包含字符串值,那么最好使用已经知道如何处理转义字符和换行符等问题的信誉良好的 JSON 库。 Json.NET is a popular option. Json.NET是一种流行的选择。

Json.NET probably serializes C# dictionaries adequately now, but when the OP originally posted this question, many MVC developers may have been using the JavaScriptSerializer class because that was the default option out of the box. Json.NET现在可能会充分序列化 C# 字典,但是当 OP 最初发布此问题时,许多 MVC 开发人员可能一直在使用JavaScriptSerializer类,因为这是开箱即用的默认选项。

If you're working on a legacy project (MVC 1 or MVC 2), and you can't use Json.NET, I recommend that you use a List<KeyValuePair<K,V>> instead of a Dictionary<K,V>> .如果您正在处理遗留项目(MVC 1 或 MVC 2),并且您不能使用 Json.NET,我建议您使用List<KeyValuePair<K,V>>而不是Dictionary<K,V>> . The legacy JavaScriptSerializer class will serialize this type just fine, but it will have problems with a dictionary.遗留的 JavaScriptSerializer 类可以很好地序列化这种类型,但它会遇到字典问题。

Documentation: Serializing Collections with Json.NET文档: 使用 Json.NET 序列化集合

Simple One-Line Answer简单的一行回答

( using System.Web.Script.Serialization ) using System.Web.Script.Serialization

This code will convert any Dictionary<Key,Value> to Dictionary<string,string> and then serialize it as a JSON string:此代码将任何Dictionary<Key,Value>转换为Dictionary<string,string> ,然后将其序列化为 JSON 字符串:

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

It is worthwhile to note that something like Dictionary<int, MyClass> can also be serialized in this way while preserving the complex type/object.值得注意的是,像Dictionary<int, MyClass>这样的东西也可以通过这种方式序列化,同时保留复杂的类型/对象。


Explanation (breakdown)说明(分解)

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

You can replace the variable yourDictionary with your actual variable.您可以将变量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.

We do this, because both the Key and Value has to be of type string, as a requirement for serialization of a Dictionary .我们这样做是因为 Key 和 Value 都必须是字符串类型,这是对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.
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()));
            }
        }
    }
}

This will write to the console:这将写入控制台:

[{\"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]}]

Sorry if the syntax is the tiniest bit off, but the code I'm getting this from was originally in VB :)对不起,如果语法是最小的一点,但我从中得到的代码最初是在 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);

In Asp.net Core use:在 Asp.net Core 中使用:

using Newtonsoft.Json

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

You can use System.Web.Script.Serialization.JavaScriptSerializer :您可以使用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);

It seems a lot of different libraries and what not have seem to come and go over the previous years.似乎有很多不同的图书馆和过去几年似乎没有的东西。 However as of April 2016, this solution worked well for me.但是,截至 2016 年 4 月,此解决方案对我来说效果很好。 Strings easily replaced by ints .字符串很容易被 ints 替换

TL/DR; TL/DR; Copy this if that's what you came here for:如果这就是您来这里的目的,请复制此内容:

    //outputfilename will be something like: "C:/MyFolder/MyFile.txt"
    void WriteDictionaryAsJson(Dictionary<string, List<string>> myDict, string outputfilename)
    {
        DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Dictionary<string, List<string>>));
        MemoryStream ms = new MemoryStream();
        js.WriteObject(ms, myDict); //Does the serialization.

        StreamWriter streamwriter = new StreamWriter(outputfilename);
        streamwriter.AutoFlush = true; // Without this, I've run into issues with the stream being "full"...this solves that problem.

        ms.Position = 0; //ms contains our data in json format, so let's start from the beginning
        StreamReader sr = new StreamReader(ms); //Read all of our memory
        streamwriter.WriteLine(sr.ReadToEnd()); // and write it out.

        ms.Close(); //Shutdown everything since we're done.
        streamwriter.Close();
        sr.Close();
    }

Two import points.两个进口点。 First, be sure to add System.Runtime.Serliazation as a reference in your project inside Visual Studio's Solution Explorer.首先,确保在 Visual Studio 的解决方案资源管理器中的项目中添加 System.Runtime.Serliazation 作为引用。 Second, add this line,其次,添加这一行,

using System.Runtime.Serialization.Json;

at the top of the file with the rest of your usings, so the DataContractJsonSerializer class can be found.在文件的顶部与您的其余使用,因此可以找到DataContractJsonSerializer类。 This blog post has more information on this method of serialization.这篇博文提供了有关这种序列化方法的更多信息。

Data Format (Input / Output)数据格式(输入/输出)

My data is a dictionary with 3 strings, each pointing to a list of strings.我的数据是一个包含 3 个字符串的字典,每个字符串都指向一个字符串列表。 The lists of strings have lengths 3, 4, and 1. The data looks like this:字符串列表的长度为 3、4 和 1。数据如下所示:

StringKeyofDictionary1 => ["abc","def","ghi"]
StringKeyofDictionary2 => ["String01","String02","String03","String04"]
Stringkey3 => ["someString"]

The output written to file will be on one line, here is the formatted output:写入文件的输出将在一行上,这是格式化的输出:

 [{
     "Key": "StringKeyofDictionary1",
     "Value": ["abc",
     "def",
     "ghi"]
 },
 {
     "Key": "StringKeyofDictionary2",
     "Value": ["String01",
     "String02",
     "String03",
     "String04",
 ]
 },
 {
     "Key": "Stringkey3",
     "Value": ["SomeString"]
 }]

Here's how to do it using only standard .Net libraries from Microsoft …以下是仅使用来自 Microsoft 的标准 .Net 库的方法……

using System.IO;
using System.Runtime.Serialization.Json;

private static string DataToJson<T>(T data)
{
    MemoryStream stream = new MemoryStream();

    DataContractJsonSerializer serialiser = new DataContractJsonSerializer(
        data.GetType(),
        new DataContractJsonSerializerSettings()
        {
            UseSimpleDictionaryFormat = true
        });

    serialiser.WriteObject(stream, data);

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

If your context allows it (technical constraints, etc.), use the JsonConvert.SerializeObject method from Newtonsoft.Json : it will make your life easier.如果您的上下文允许(技术限制等),请使用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"}

您可以使用JavaScriptSerializer

This is Similar to what Meritt has posted earlier.这与 Meritt 之前发布的内容类似。 just posting the complete code只是发布完整的代码

    string sJSON;
    Dictionary<string, string> aa1 = new Dictionary<string, string>();
    aa1.Add("one", "1"); aa1.Add("two", "2"); aa1.Add("three", "3");
    Console.Write("JSON form of Person object: ");

    sJSON = WriteFromObject(aa1);
    Console.WriteLine(sJSON);

    Dictionary<string, string> aaret = new Dictionary<string, string>();
    aaret = ReadToObject<Dictionary<string, string>>(sJSON);

    public static string WriteFromObject(object obj)
    {            
        byte[] json;
            //Create a stream to serialize the object to.  
        using (MemoryStream ms = new MemoryStream())
        {                
            // Serializer the object to the stream.  
            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
            ser.WriteObject(ms, obj);
            json = ms.ToArray();
            ms.Close();
        }
        return Encoding.UTF8.GetString(json, 0, json.Length);

    }

    // Deserialize a JSON stream to object.  
    public static T ReadToObject<T>(string json) where T : class, new()
    {
        T deserializedObject = new T();
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
        {

            DataContractJsonSerializer ser = new DataContractJsonSerializer(deserializedObject.GetType());
            deserializedObject = ser.ReadObject(ms) as T;
            ms.Close();
        }
        return deserializedObject;
    }

Just for reference, among all the older solutions: UWP has its own built-in JSON library, Windows.Data.Json .仅供参考,在所有较旧的解决方案中:UWP 有自己的内置 JSON 库Windows.Data.Json

JsonObject is a map that you can use directly to store your data: JsonObject是一个地图,您可以直接使用它来存储您的数据:

var options = new JsonObject();
options["foo"] = JsonValue.CreateStringValue("bar");
string json = options.ToString();

net core: System.Text.Json.JsonSerializer.Serialize(dict)网络核心:System.Text.Json.JsonSerializer.Serialize(dict)

improved mwjohnson's version:改进了 mwjohnson 的版本:

string WriteDictionaryAsJson_v2(Dictionary<string, List<string>> myDict)
{
    string str_json = "";
    DataContractJsonSerializerSettings setting = 
        new DataContractJsonSerializerSettings()
        {
            UseSimpleDictionaryFormat = true
        };

    DataContractJsonSerializer js = 
        new DataContractJsonSerializer(typeof(Dictionary<string, List<string>>), setting);

    using (MemoryStream ms = new MemoryStream())
    {                
        // Serializer the object to the stream.  
        js.WriteObject(ms, myDict);
        str_json = Encoding.Default.GetString(ms.ToArray());

    }
    return str_json;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM