C #에서 사전을 JSON 문자열로 어떻게 변환합니까?


131

Dictionary<int,List<int>>JSON 문자열 로 변환하고 싶습니다 . C #에서 이것을 달성하는 방법을 아는 사람이 있습니까?


3
newtonSoft.json nuget 패키지를 사용하십시오. JsonConvert.SerializeObject (yourObject)
RayLoveless

답변:


118

숫자 또는 부울 값만 포함하는 데이터 구조 직렬화 하는 것은 매우 간단합니다. 직렬화 할 것이 많지 않은 경우 특정 유형에 대한 메소드를 작성할 수 있습니다.

A의 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 은 널리 사용되는 옵션입니다.


66
이 솔루션은 순진합니다. 실제 json 직렬화 라이브러리를 사용하십시오.
jacobsimeon

131
@ 야콥-순진? 아야. 개인적으로, 하나의 짧고 간단한 방법으로 필요한 모든 것을 달성 할 수있을 때 다른 어셈블리를 포함시키는 것을 정당화 할 수 없습니다 .
gilly3

16
gilly3 코멘트에 하나 더 +. 언젠가 Windows Phone에서 코딩 중입니다. 당신은 zlip, 트위터, 구글, 오디오 프로세싱 물건, 이미지 프로세싱 물건을 추가하고 있습니다. 간단한 방법과 소셜 미디어 상호 작용을위한 기본적인 HttpRequests를 사용하는 것이 좋습니다. 어셈블리를 추가 할 때는 항상 버그와 라이트 버전을 얻을 수없는 문제를 해결해야합니다. 그런데 json libs에는 이와 같은 순진한 방법이 있으며 마술은 없습니다.
Léon Pelletier

14
열려있는 모든 프로젝트에는 다음과 같은 내용의 페이지가 있어야합니다. "대부분의 경우이 10 줄만 실행하면됩니다. 코드는 다음과 같습니다."
Léon Pelletier

31
dict.add ( "RandomKey \" ","RandomValue \ ""); BOOOOOOOOOOOOOOOOM. 순진합니다. 실제 json 직렬화 라이브러리를 사용하십시오.
Sleeper Smith

112

이 답변은 Json.NET에 대해 언급하지만 Json.NET을 사용하여 사전을 직렬화하는 방법에 대한 정보 는 부족합니다.

return JsonConvert.SerializeObject( myDictionary );

JavaScriptSerializer와 달리 JsonConvert가 작동하기 위해 myDictionary사전 유형일 <string, string>필요 는 없습니다 .


71

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는 Javascript로 다시 읽을 때 c # 사전을 열거 가능한 컬렉션 유형으로 직렬화하는 것을 처리하지 않는 것으로 보입니다. 오히려 C # 컬렉션의 각 쌍이 개체의 일반 속성 / 값인 개체를 컬렉션처럼 쉽게 열거 할 수없는 개체로 만듭니다. 따라서 nuget의 나쁜 버전이 없으면 Json.NET은 여전히 ​​충분하지 않습니다.이 점에서.
StingyJack

어 그래. 나는 이미 비슷한 일을하고 있었지만 다른 방법을 찾으려고 노력 하면서이 문제를 발견했습니다. 다른 사람들 에게이 항목에 대한 Json.NET 토끼 구멍을 피하는 것이 유용하다고 생각했습니다 (그렇지 않으면 큰 효과가 있습니다).
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()));
            }
        }
    }
}

콘솔에 쓸 것입니다 :

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

간단한 한 줄 답변

( using System.Web.Script.Serialization)

이 코드는 any 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.

우리는 키와 값이 모두 문자열 유형이어야하기 때문에 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.

C #에 JavaScriptSerializer가 없습니다.
Jonny

1
@Jonny 참조 어셈블리가 없습니다. System.Web.Extensions msdn.microsoft.com/en-us/library/…
aminhotob

System.Web.ExtensionsClient Framework 버전이 아니지만 정식 버전이 필요 하다는 것을 읽었 습니다.
vapcguy

제한된 응용 프로그램의 솔루션 일 수 있지만 객체 속성이 유형 문자열이 아닌 경우 모든 값을 문자열 유형으로 설정하면 올바른 JSON이 생성되지 않습니다.
Suncat2000

1
이 주제에 대한 최고의 답변.
T.Todua

12

구문이 가장 작은 비트 인 경우 미안하지만이 코드를 원래 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
ArgumentException이 발생합니다. 'System.Collections.Generic.Dictionary`2 유형은 사전의 직렬화 / 직렬화에 지원되지 않으며 키는 문자열 또는 객체 여야합니다.
Pavel Chuchuva


7

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는 타사이지만 MS가 자사 제품에 널리 사용하고 채택했습니다. nuget.org/packages/Newtonsoft.Json
Skorunka František

7

당신은 사용할 수 있습니다 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

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

이것을 결합 Dictionary<string, dynamic>하고 intergers, floats, booleans, strings, nulls 및 하나의 객체와 같은 모든 JSON 기본 유형을 가질 수 있습니다 . +1
Christos Lytras

1

JavaScriptSerializer를 사용할 수 있습니다 .


사전은 직렬화 할 수 있습니까?
Numenor

나는 이것이 효과가 있다고 생각했을 것입니다-string json = serializer.Serialize ((object) dict);
Twelve47

1
@Numenor 예, 키 AND 값이 유형 인 경우에만 가능합니다 string. 당신이보고 싶다면 여기에 포함 된 답변을 게시했습니다.
HowlinWulf

@HowlinWulf 더 정확하게 말하면 값이 문자열 일 필요는 없습니다. 그러나 열쇠의 경우 분명히 정수가 될 수는 없습니다. 문자열은 키로 가장 잘 작동합니다.
Gyum Fox

1
@ Twelve47 링크가 이동 된 경우 샘플 사용을 포함해야합니다. 그렇지 않으면이 대답은 언젠가 쓸모 없게 될 수 있습니다.
vapcguy

1

그것은 많은 다른 도서관처럼 보이고 지난 몇 년 동안 오지 않았던 것 같습니다. 그러나 2016 년 4 월 현재이 솔루션은 저에게 효과적이었습니다. 문자열은 int로 쉽게 대체됩니다 .

TL / DR; 그것이 당신이 여기 온 것이라면 이것을 복사하십시오 :

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

두 개의 수입 지점. 먼저 Visual Studio의 솔루션 탐색기 내 프로젝트에서 System.Runtime.Serliazation을 참조로 추가해야합니다. 둘째,이 줄을 추가하십시오.

using System.Runtime.Serialization.Json;

파일의 맨 위에 나머지 용도와 함께 DataContractJsonSerializer클래스를 찾을 수 있습니다. 이 블로그 게시물 에는이 직렬화 방법에 대한 자세한 정보가 있습니다.

데이터 형식 (입력 / 출력)

내 데이터는 3 개의 문자열이있는 사전이며 각각은 문자열 목록을 나타냅니다. 문자열 목록의 길이는 3, 4 및 1입니다. 데이터는 다음과 같습니다.

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

파일에 기록 된 출력은 한 줄에 표시되며 형식화 된 출력은 다음과 같습니다.

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

0

이것은 Meritt가 이전에 게시 한 것과 유사합니다. 그냥 완전한 코드를 게시

    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

문맥에 따라 (기술적 제약 등) 허용되는 경우 Newtonsoft.JsonJsonConvert.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"}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.