Làm cách nào để chuyển đổi từ điển thành Chuỗi JSON trong C #?


130

Tôi muốn chuyển đổi Dictionary<int,List<int>>chuỗi JSON của tôi . Có ai biết làm thế nào để đạt được điều này trong C #?


3
Sử dụng gói nuget newtonSoft.json. JsonConvert.SerializeObject (yourObject)
RayLovless

Câu trả lời:


118

Việc sắp xếp các cấu trúc dữ liệu chỉ chứa các giá trị số hoặc boolean khá đơn giản. Nếu bạn không có nhiều thứ tự để tuần tự hóa, bạn có thể viết một phương thức cho loại cụ thể của bạn.

Đối với một Dictionary<int, List<int>>như bạn đã chỉ định, bạn có thể sử dụng 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) + "}";
}

Nhưng, nếu bạn đang tuần tự hóa một số lớp khác nhau hoặc cấu trúc dữ liệu phức tạp hơn hoặc đặc biệt là nếu dữ liệu của bạn chứa các giá trị chuỗi , bạn nên sử dụng thư viện JSON có uy tín, biết cách xử lý những thứ như ký tự thoát và ngắt dòng. Json.NET là một lựa chọn phổ biến.


66
Giải pháp này là ngây thơ nhất. Sử dụng một thư viện serialization json thực sự.
jacobsimeon

131
@Jacob - Ngây thơ? Ôi. Cá nhân, tôi không thể biện minh cho việc bao gồm một hội đồng khác khi tất cả những gì tôi cần làm có thể được thực hiện bằng một phương pháp ngắn và đơn giản.
gilly3

16
Thêm một bình luận trên gilly3. Đôi khi bạn đang mã hóa trên Windows Phone. Bạn đang thêm zlip, twitter, google, công cụ xử lý âm thanh, công cụ xử lý hình ảnh. Bạn nên thực hiện phương pháp đơn giản như nó và một số httpRequests cơ bản để tương tác phương tiện truyền thông xã hội nếu việc sử dụng của bạn đơn giản. Khi thêm một hội đồng, bạn luôn phải đối phó với các lỗi và với việc không thể có được một phiên bản lite. Nhân tiện, bên trong libs json, có những phương pháp ngây thơ như thế này và không có phép thuật.
Léon Pelletier

14
Cần có một trang trên mỗi dự án mở cho bạn biết: "Này, hầu hết thời gian, bạn sẽ chỉ muốn thực hiện 10 dòng này. Đây là mã."
Léon Pelletier

31
dict.add ("RandomKey \" "," RandomValue \ ""); BOOOOOOOOOOOOOOOOM. Ngây thơ nhất. Sử dụng một thư viện serialization json thực sự.
ngủ Smith

112

Câu trả lời này đề cập đến Json.NET nhưng không nói cho bạn biết làm thế nào bạn có thể sử dụng Json.NET để tuần tự hóa một từ điển:

return JsonConvert.SerializeObject( myDictionary );

Trái ngược với JavaScriptSerializer, myDictionarykhông phải là một từ điển loại <string, string>để JsonConvert hoạt động.


71

Bây giờ Json.NET có thể tuần tự hóa từ điển C # đầy đủ, nhưng khi OP ban đầu đăng câu hỏi này, nhiều nhà phát triển MVC có thể đã sử dụng JavaScriptSerializer lớp vì đó là tùy chọn mặc định ngoài hộp.

Nếu bạn đang làm việc trên một dự án cũ (MVC 1 hoặc MVC 2) và bạn không thể sử dụng Json.NET, tôi khuyên bạn nên sử dụng List<KeyValuePair<K,V>>thay vì mộtDictionary<K,V>> . Lớp JavaScriptSerializer kế thừa sẽ tuần tự hóa loại này tốt, nhưng nó sẽ có vấn đề với một từ điển.

Tài liệu: Bộ sưu tập nối tiếp với Json.NET


3
Câu trả lời hoàn hảo cho người dùng asp.net mvc3 và mvc4
Gomes

JsonConvert.SerializeObject không xuất hiện để xử lý tuần tự hóa từ điển c # thành một loại bộ sưu tập có thể đếm được khi đọc lại vào Javascript. Thay vào đó, nó tạo một đối tượng trong đó mỗi cặp trong bộ sưu tập C # bây giờ là một thuộc tính / giá trị đơn giản trong một đối tượng, không thể dễ dàng liệt kê như một bộ sưu tập. Vì vậy, trừ khi tôi có một phiên bản xấu từ nuget, Json.NET vẫn chưa đầy đủ. Về vấn đề này.
StingyJack

Ồ, vâng. Tôi đã làm một điều tương tự rồi, nhưng cố gắng tìm ra một cách khác, và vấp phải điều này. Tôi cảm thấy có thể hữu ích khi cho người khác biết để tránh lỗ thỏ Json.NET cho mặt hàng này (hoạt động rất tốt).
StingyJack

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

Điều này sẽ ghi vào bàn điều khiển:

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

19

Câu trả lời một dòng đơn giản

( using System.Web.Script.Serialization)

Mã này sẽ chuyển đổi bất kỳ Dictionary<Key,Value>sang Dictionary<string,string>và sau đó tuần tự hóa nó thành một chuỗi JSON:

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

Điều đáng lưu ý là một cái gì đó giống như Dictionary<int, MyClass>cũng có thể được tuần tự theo cách này trong khi vẫn bảo tồn loại / đối tượng phức tạp.


Giải thích (sự cố)

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

Bạn có thể thay thế biến yourDictionarybằng biến thực tế của bạn.

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.

Chúng tôi làm điều này, bởi vì cả Khóa và Giá trị phải thuộc kiểu chuỗi, như một yêu cầu để tuần tự hóa a 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.

Tôi không có JavaScriptSerializer trong C # của mình.
Jonny

1
@Jonny bạn đang thiếu lắp ráp tham chiếu System.Web.Extensions msdn.microsoft.com/en-us/l
Library / ám

Tôi đã đọc rằng System.Web.Extensionskhông có trong phiên bản Khung khách hàng, nhưng cũng yêu cầu phiên bản đầy đủ.
vapcguy

Có thể là một giải pháp cho các ứng dụng hạn chế, nhưng buộc tất cả các giá trị phải nhập chuỗi sẽ không mang lại JSON chính xác nếu bất kỳ thuộc tính đối tượng nào không phải là chuỗi kiểu.
Suncat2000

1
câu trả lời tốt nhất về chủ đề này.
T.Todua

12

Xin lỗi nếu cú ​​pháp là bit nhỏ nhất, nhưng mã tôi nhận được từ ban đầu trong 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);

2
Nó ném ArgumentException: Gõ 'System.Collections.Generic.Dixi`2 không được hỗ trợ để tuần tự hóa / giải tuần tự hóa từ điển, các khóa phải là chuỗi hoặc đối tượng.
Pavel Chuchuva


7

Trong Asp.net Core sử dụng:

using Newtonsoft.Json

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

Tôi tham khảo System.Corevà sau đó cố gắng tham khảo using Newtonsoft.Jsonvà không có niềm vui. Tôi nghĩ Newtonsoftlà một thư viện của bên thứ 3.
vapcguy

2
@vapcguy Có, Newtonsoft là bên thứ 3 nhưng cũng được sử dụng rộng rãi và cũng được MS áp dụng trong các sản phẩm của họ. nuget.org/packages/Newtonsoft.Json
Skorunka František

7

Bạn có thể sử dụng 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);

2

Đây là cách thực hiện bằng cách chỉ sử dụng các thư viện .Net tiêu chuẩn từ Microsoft '

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

Chúng ta có thể kết hợp điều này với Dictionary<string, dynamic>và có tất cả các kiểu nguyên thủy JSON như intergers, float, booleans, chuỗi, thậm chí null và trong một đối tượng. +1
Christos Lytras

1

Bạn có thể sử dụng JavaScriptSerializer .


từ điển nối tiếp là gì?
Numenor

Tôi đã nghĩ rằng điều này sẽ làm việc - chuỗi json = serializer.Serialize ((object) dict);
Mười hai47

1
@Numenor Có, chúng là như vậy, nhưng chỉ khi Khóa VÀ Giá trị thuộc loại string. Tôi đã đăng một câu trả lời ở đây bao gồm điều đó, nếu bạn muốn có một cái nhìn.
HowlinWulf

@HowlinWulf để chính xác hơn, giá trị không phải là một chuỗi. Nhưng đối với chìa khóa, nó chắc chắn không thể là một int. Chuỗi hoạt động tốt nhất như là chìa khóa.
Cáo Gyum

1
@ Twelve47 Nên bao gồm một cách sử dụng mẫu, trong trường hợp liên kết đó đã được di chuyển. Nếu không, câu trả lời này có thể trở nên vô dụng, một ngày nào đó.
vapcguy

1

Có vẻ như rất nhiều thư viện khác nhau và những gì dường như không đến và đi trong những năm trước. Tuy nhiên, kể từ tháng 4 năm 2016, giải pháp này đã làm việc tốt với tôi. Chuỗi dễ dàng thay thế bởi ints .

TL / DR; Sao chép này nếu đó là những gì bạn đến đây:

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

Hai điểm nhập khẩu. Trước tiên, hãy chắc chắn thêm System.R.78.Serliazation làm tài liệu tham khảo trong dự án của bạn bên trong Solution Explorer của Visual Studio. Thứ hai, thêm dòng này,

using System.Runtime.Serialization.Json;

ở đầu tập tin với phần còn lại của việc sử dụng của bạn, vì vậy DataContractJsonSerializerlớp có thể được tìm thấy. Bài đăng blog này có thêm thông tin về phương pháp tuần tự hóa này.

Định dạng dữ liệu (Đầu vào / Đầu ra)

Dữ liệu của tôi là một từ điển có 3 chuỗi, mỗi chuỗi chỉ vào một danh sách các chuỗi. Danh sách các chuỗi có độ dài 3, 4 và 1. Dữ liệu trông như thế này:

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

Đầu ra được ghi vào tệp sẽ nằm trên một dòng, đây là đầu ra được định dạng:

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

0

Điều này tương tự như những gì Meritt đã đăng trước đó. chỉ cần đăng mã hoàn chỉnh

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

0

Nếu ngữ cảnh của bạn cho phép nó (các ràng buộc kỹ thuật, v.v.), hãy sử dụng JsonConvert.SerializeObjectphương pháp từ Newtonsoft.Json : nó sẽ giúp cuộc sống của bạn dễ dàng hơn.

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"}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.