C #으로 JSON을 구문 분석하려면 어떻게해야합니까?


455

다음 코드가 있습니다.

var user = (Dictionary<string, object>)serializer.DeserializeObject(responsecontent);

입력 responsecontent이 JSON이지만 객체로 올바르게 구문 분석되지 않았습니다. 직렬화를 제대로 해제하려면 어떻게해야합니까?



34
거기 Json에서 System.Web.Helpers거기에, JsonQueryStringConverterSystem.ServiceModel.Web, 거기 JavascriptSerializerSystem.Web.Script.Serialization, DataContractJsonSerializerSystem.Runtime.Serialization.Json, 도대체 MS도 타사를 포함하기로 결정했다 Json.NET자사의 ASP.NET 웹 API에. 충분하지 않다고 생각하면 MS가 등장 System.Json하지만 현재는 소비에 적합하지 않습니다. 가는 길 Microsoft는가는 길 .... 가장 잘 보이는 네임 스페이스로 선택합니다.
nawfal

4
@fusi 나머지는 별도의 어셈블리에 있습니다. Google은 네임 스페이스 / 클래스 이름이며 어셈블리는 msdn 설명서에 있습니다. 해당 어셈블리에 대한 참조를 추가하십시오.
nawfal

1
단지 전체에, 또한 거기 JsonValueWindows.Data.Json있는 유일한 윈도우 8과 이상입니다. 나는 그것을 사랑 해요. MS는 임무
중이다

5
NewtonSoft는 그들의 사이트에 비교 페이지가 있습니다 (편향 될 수 있지만 여전히 흥미 롭습니다) : newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm . 내가 특히 좋아 무의미한 사전 직렬화 행 :
오핫 슈나이더

답변:


365

Json.NET (Newtonsoft.Json NuGet 패키지)을 사용하지 않는다고 가정합니다 . 이 경우에는 시도해야합니다.

다음과 같은 기능이 있습니다.

  1. LINQ to JSON
  2. .NET 객체를 JSON으로 빠르게 변환하고 다시 되돌릴 수있는 JsonSerializer
  3. Json.NET은 선택적으로 디버깅 또는 표시를 위해 잘 형식화되고 들여 쓰기 된 JSON을 생성 할 수 있습니다.
  4. JsonIgnore 및 JsonProperty와 같은 속성을 클래스에 추가하여 클래스 직렬화 방법을 사용자 정의 할 수 있습니다.
  5. JSON과 XML 간 변환 기능
  6. .NET, Silverlight 및 Compact Framework와 같은 여러 플랫폼 지원

아래 예를 보십시오 . 이 예에서 JsonConvert클래스는 객체를 JSON으로 또는 JSON에서 변환하는 데 사용됩니다. 이를 위해 두 가지 정적 메소드가 있습니다. 그들은 있습니다 SerializeObject(Object obj)DeserializeObject<T>(String json):

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string json = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "Expiry": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);

18
var목표의 전체 구조를 모르는 경우 유형 변수로 역 직렬화 할 수 있습니까 ? 특히, Rally User Stories를 사용하고 있으며 객체로 변환하고 싶습니다.
Pedro Dusso

16
@VANDERWEYENJonathan-최신 웹 브라우저에서 JSON.parse (string) 및 JSON.stringify (object)는 날짜를 ISO8601 문자열로 처리하며 위의 답변에 표시된 형식입니다. 사람들이 관련이없는 것으로 판단하기 전에 표준을 업데이트 할 수 있습니다. 사람들은 표준보다 필요한 날짜가 훨씬 더 필요합니다.
Peter Wone

3
@PeterWone : 아니요, 날짜가 아닌 문자열을JSON.parse('{"Expiry": "2008-12-28T00:00:00"}').Expiry 반환합니다 . 그것은 할 수 있습니다 로 바뀌 를 통해 ,하지만 날짜에 대해 아무것도 모른다. 패턴에 대해 각각의 모든 문자열 값을 확인한 리바이 버를 전달해야합니다. "2008-12-28T00:00:00"Datenew Date(str)JSON.parse
TJ Crowder

3
3.703 초는 3s 및 703ms와 같고 구분 기호는 소수점이므로 이것은 소수점 이하 세 자리입니다.
Peter Wone

38
왜 모두 관련 포함한와 같은 문제가 있습니까 require, include, import또는 using그들의 대답에 문을. 그 한 줄이 아프겠습니까?
Tomáš Zato-복원 모니카

285

여기에 답변 된 것처럼 -JSON을 C # 동적 객체로 직렬화 해제 하시겠습니까?

Json.NET을 사용하는 것은 매우 간단합니다.

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

또는 Newtonsoft.Json.Linq 사용 :

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

13
@MaxHodges, 당신이 맞아요. JSON 문자열 값을 구문 분석하는 방법을 보여주기 위해 인라인 "매직 문자열"을 사용했습니다. 큰 따옴표를 이스케이프 처리하여 복잡하게 보이기를 원하지 않았습니다. 실제 코드에는 일반적으로 어딘가에서 변수로 얻거나 매개 변수로 전달되는 JSON 문자열이 있습니다.
Dmitry Pavlov

4
.net 4가 없으면 '동적'키워드가 없습니다. 선언에 'var stuff'를 사용할 수 있으며 각각 'stuff [ "Name"]'및 'stuff [ "Address"] [ "City"]'가있는 'stuff.Name'및 'stuff.Address.City'대신 .

1
@Fil 그것은 타입의 값을 제공하며 object,에서 인덱싱을 사용할 수 없습니다 object.
Alex

138

타사 라이브러리 사용 하지 않는 옵션은 다음과 같습니다 .

// For that you will need to add reference to System.Runtime.Serialization
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }"), new System.Xml.XmlDictionaryReaderQuotas());

// For that you will need to add reference to System.Xml and System.Xml.Linq
var root = XElement.Load(jsonReader);
Console.WriteLine(root.XPathSelectElement("//Name").Value);
Console.WriteLine(root.XPathSelectElement("//Address/State").Value);

// For that you will need to add reference to System.Web.Helpers
dynamic json = System.Web.Helpers.Json.Decode(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }");
Console.WriteLine(json.Name);
Console.WriteLine(json.Address.State);

System.Web.Helpers.Json에 대한 자세한 정보는 링크를 참조하십시오 .

업데이트 : 요즘 가장 쉬운 방법 Web.HelpersNuGet 패키지 를 사용하는 것 입니다.


이전 Windows 버전에 신경 쓰지 않으면 Windows.Data.Json네임 스페이스 의 클래스를 사용할 수 있습니다 .

// minimum supported version: Win 8
JsonObject root = Windows.Data.Json.JsonValue.Parse(jsonString).GetObject();
Console.WriteLine(root["Name"].GetString());
Console.WriteLine(root["Address"].GetObject()["State"].GetString());

ASP.NET 웹 사이트 (4.5)에 System.Web.Helpers가 표시되지 않는 이유는 무엇입니까? XElement, XPathSelectElement가 내 VisualStudio에 알려져 있지 않습니다. 그것을 교육하는 방법?
Budda

글쎄, 당신은 해당 라이브러리에 대한 참조를 추가해야합니다 (위의 의견에 쓰여진 것처럼), 자세한 내용은이 기사 를 참조하십시오. 또한이 질문 이 흥미로울 수 있습니다.
qqbenq

2
여기에 설명 된 Web.Helpers 메서드를 사용했지만이 게시물로 해결 된 문제가 발생했습니다. stackoverflow.com/questions/7066726/…
Alex

1
System.Runtime.Serialization.Json을 사용하여 다음 네임 스페이스를 사용하여 WPF.By로 작업합니다. System.Xml.XPath 사용; System.Xml.Linq 사용;
Shahid Neermunda

3
Json.Net은 더 이상 타사 구성 요소가 아닙니다. Microsoft는 요즘 자체적으로 사용합니다. Web API의 기본 serilizer입니다.
Liam

62

.NET 4를 사용할 수있는 경우 http://visitmix.com/writings/the-rise-of-json(archive.org)을 확인하십시오.

해당 사이트의 스 니펫은 다음과 같습니다.

WebClient webClient = new WebClient();
dynamic result = JsonValue.Parse(webClient.DownloadString("https://api.foursquare.com/v2/users/self?oauth_token=XXXXXXX"));
Console.WriteLine(result.response.user.firstName);

마지막 Console.WriteLine은 꽤 달콤합니다 ...


죄송합니다. 처음에 답변 한 이후로 변경된 것 같습니다. 주변을 둘러보고 어떤 라이브러리가 올바른지 확인해야합니다.
ElonU Webdev

7
이 라이브러리를 찾으시기 바랍니다. 편집 : 이것이 이것입니다 : dynamicjson.codeplex.com ?
user989056

1
ElonU 클래스가 여기에서 의미하는 바를 모르겠지만 Windows.Data.Json에는 "JsonValue"(Windows 8 이상에만 해당-이상)가 있으며 System.Json에는 동일한 "JsonValue"가 있습니다. 하나님 만이 나올 것인지 아십니다. Json과 관련하여 MS는 나를 혼란스럽게합니다.
nawfal

35

타사 라이브러리가 필요하지 않지만 System.Web.Extensions에 대한 참조 는 JavaScriptSerializer입니다. 이것은 3.5 이래로 새로운 기능은 아니지만 매우 알려지지 않은 내장 기능입니다.

using System.Web.Script.Serialization;

..

JavaScriptSerializer serializer = new JavaScriptSerializer();
objectString = serializer.Serialize(new MyObject());

그리고 다시

MyObject o = serializer.Deserialize<MyObject>(objectString)

2
이것은 매우 좋지만 웹 구성 요소가 필요하므로 불행히도 Windows XP의 마지막 .NET 버전 인 .NET 4.0 클라이언트 프로파일에서는 작동하지 않습니다. .NET의 전체 설치가 가능하지만 많은 사람들이 클라이언트 프로필 만 사용합니다. 반대로 System.Runtime.Serialization.Json.DataContractJsonSerializer는 클라이언트 프로필에서도 지원됩니다.
Al Kepp

3
@ fr34kyn01535 : Windows XP는 데스크톱에서 두 번째로 많은 시장 점유율을 차지합니다. 관련이 있습니다.
DonkeyMaster

JavaScriptSerializer를 사용하여 객체의 직렬화를 해제하면 작동했지만 날짜가 잘못 직렬화 해제되었습니다. 2018 년 4 월 19 일 12:00 AM 이었지만 2018 년 4 월 18 일 08:00 PM으로 역 직렬화되었습니다. NewtonSoft.Json.JsonConvert가 예상대로 직렬화를 해제했습니다.
Rich


16

System.Json이 지금 작동합니다 ...

너겟 설치 https://www.nuget.org/packages/System.Json

PM> Install-Package System.Json -Version 4.5.0

샘플 :

// PM>Install-Package System.Json -Version 4.5.0

using System;
using System.Json;

namespace NetCoreTestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Note that JSON keys are case sensitive, a is not same as A.

            // JSON Sample
            string jsonString = "{\"a\": 1,\"b\": \"string value\",\"c\":[{\"Value\": 1}, {\"Value\": 2,\"SubObject\":[{\"SubValue\":3}]}]}";

            // You can use the following line in a beautifier/JSON formatted for better view
            // {"a": 1,"b": "string value","c":[{"Value": 1}, {"Value": 2,"SubObject":[{"SubValue":3}]}]}

            /* Formatted jsonString for viewing purposes:
            {
               "a":1,
               "b":"string value",
               "c":[
                  {
                     "Value":1
                  },
                  {
                     "Value":2,
                     "SubObject":[
                        {
                           "SubValue":3
                        }
                     ]
                  }
               ]
            }
            */

            // Verify your JSON if you get any errors here
            JsonValue json = JsonValue.Parse(jsonString);

            // int test
            if (json.ContainsKey("a"))
            {
                int a = json["a"]; // type already set to int
                Console.WriteLine("json[\"a\"]" + " = " + a);
            }

            // string test
            if (json.ContainsKey("b"))
            {
                string b = json["b"];  // type already set to string
                Console.WriteLine("json[\"b\"]" + " = " + b);
            }

            // object array test
            if (json.ContainsKey("c") && json["c"].JsonType == JsonType.Array)
            {
                // foreach loop test
                foreach (JsonValue j in json["c"])
                {
                    Console.WriteLine("j[\"Value\"]" + " = " + j["Value"].ToString());
                }

                // multi level key test
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][0]["Value"].ToString());
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][1]["Value"].ToString());
                Console.WriteLine("json[\"c\"][1][\"SubObject\"][0][\"SubValue\"]" + " = " + json["c"][1]["SubObject"][0]["SubValue"].ToString());
            }

            Console.WriteLine();
            Console.Write("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

1
Json.NET/Newtonsoft.Json/"Newtson.Json "및 이전 버전의 System.Json에 대한 수많은 결과가 더 이상 사용되지 않는 이후에 최신 System.Json을 올바르게 사용하는 방법의 예를 찾으려고 여기에 왔습니다. 감사합니다.
monkey0506

1
이것은 큰 도움이되었습니다. 대단히 감사합니다.
MAK

10

이 도구를 사용하여 json을 기반으로 클래스를 생성하십시오.

http://json2csharp.com/

그런 다음 클래스를 사용하여 json을 직렬화 해제하십시오. 예:

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}


string json = @"{
  'Email': 'james@example.com',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// james@example.com

참조 : https://forums.asp.net/t/1992996.aspx?Nested+Json+Deserialization+to+C+object+and+using+that+that+object https://www.newtonsoft.com/json/help /html/DeserializeObject.htm


9

다음 코드를 시도하십시오.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
JArray array = new JArray();
using (var twitpicResponse = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(twitpicResponse.GetResponseStream()))
{
    JavaScriptSerializer js = new JavaScriptSerializer();
    var objText = reader.ReadToEnd();

    JObject joResponse = JObject.Parse(objText);
    JObject result = (JObject)joResponse["result"];
    array = (JArray)result["Detail"];
    string statu = array[0]["dlrStat"].ToString();
}

감사합니다. JSON.NET으로는 쉽게 사용할 수없는 변수를 사용하고 싶기 때문에 [ "result"+ variable] 부분이 필요했습니다.
PHPGuru

이 줄이 무엇을하고 있습니까 ... JavaScriptSerializer js = new JavaScriptSerializer (); 미리 감사드립니다.
크리스 카티 냐니

9

System.Text.Json

.NET core 3.0에는 System.Text.Json기본적 으로 내장되어있어 JSON 직렬화 해제 / 직렬화 할 수 있습니다. 라이브러리가 제공되므로 타사 라이브러리를 사용 .

클래스를 JSON 문자열로 직렬화하려면 다음을 수행하십시오.

var json = JsonSerializer.Serialize(order);

JSON을 강력한 형식의 클래스로 역 직렬화하려면 다음을 수행하십시오.

var order = JsonSerializer.Deserialize<Order>(json);

따라서 아래와 같은 수업이 있다면 :

public class Order
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    public decimal Balance { get; set; }
    public DateTime Opened { get; set; }
}

var json = JsonSerializer.Serialize(order);
// creates JSON ==>
{
    "id": 123456,
    "orderNumber": "ABC-123-456",
    "balance": 9876.54,
    "opened": "2019-10-21T23:47:16.85",
};

var order = JsonSerializer.Deserialize<Order>(json);
// ==> creates the above class

주의해야 할 것은 자신의 코드를 사용할 때 JSON 속성을 자동으로 처리 System.Text.Json 하지 않는다는 것입니다camelCase (단, MVC / WebAPI 요청 및 모델 바인더 사용시).

이 문제를 해결하려면 JsonSerializerOptions매개 변수 로 전달해야합니다 .

JsonSerializerOptions options = new JsonSerializerOptions
{        
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,  // set camelCase       
    WriteIndented = true                                // write pretty json
};

// pass options to serializer
var json = JsonSerializer.Serialize(order, options);
// pass options to deserializer
var order = JsonSerializer.Deserialize<Order>(json, options);

System.Text.Json 은 Nu-get 패키지 System.Text.Json 으로 .Net Framework 및 .Net Standard에서도 사용할 수 있습니다.


1
수업이 없으면 어떻게 되나요? json 데이터에 무엇을 포함 시킬지 모호하게 알고 있다면 어떨까요? 아니면 키가 전혀 없다면?
Cherona

@Cherona 사용 JsonDocument.Parse.
haldo

5

msdn 사이트 의 다음 내용은 원하는 내용에 대한 기본 기능을 제공하는 데 도움 이 된다고 생각합니다. Windows 8에 지정되어 있습니다. 사이트에서 이러한 예제 중 하나가 아래에 나열되어 있습니다.

JsonValue jsonValue = JsonValue.Parse("{\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]}");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");

Windows.Data.JSON 네임 스페이스를 사용합니다 .


6
훌륭

나는 그것의 더 이상 지원 생각하지 지금이 newtonsoft JSON DLL icouldnt windows.data.json 찾을
virtouso

3
@virtouso, watbywbarif가 지적한 것처럼 실제로는 새로운 것이지만 Microsoft의 최소한의 지원은 Windows 8에서만 작동합니다.
TargetofGravity

4

다음 확장을 사용할 수 있습니다

public static class JsonExtensions
{
    public static T ToObject<T>(this string jsonText)
    {
        return JsonConvert.DeserializeObject<T>(jsonText);
    }

    public static string ToJson<T>(this T obj)
    {
        return JsonConvert.SerializeObject(obj);
    } 
}

0

내가 본 가장 좋은 대답은 @MD_Sayem_Ahmed라고 생각합니다.

귀하의 질문은 "Json을 C #으로 구문 분석하는 방법"이지만 Json을 디코딩하려는 것 같습니다. 해독하고 싶다면 Ahmed의 대답이 좋습니다.

ASP.NET Web Api에서이 작업을 수행하려는 경우 가장 쉬운 방법은 할당하려는 데이터를 보유하는 데이터 전송 개체를 만드는 것입니다.

public class MyDto{
    public string Name{get; set;}
    public string Value{get; set;}
}

Fiddler를 사용하는 경우 애플리케이션 / json 헤더를 요청에 추가하기 만하면됩니다. 그런 다음 ASP.NET 웹 API에서 다음과 같이 사용합니다.

//controller method -- assuming you want to post and return data
public MyDto Post([FromBody] MyDto myDto){
   MyDto someDto = myDto;
   /*ASP.NET automatically converts the data for you into this object 
    if you post a json object as follows:
{
    "Name": "SomeName",
      "Value": "SomeValue"
}
*/
   //do some stuff
}

이것은 Web Api에서 일할 때 많은 도움이되었고 인생을 아주 쉽게 만들었습니다.


0
         string json = @"{
            'Name': 'Wide Web',
            'Url': 'www.wideweb.com.br'}";

        JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
        dynamic j = jsonSerializer.Deserialize<dynamic>(json);
        string name = j["Name"].ToString();
        string url = j["Url"].ToString();

-1
var result = controller.ActioName(objParams);
IDictionary<string, object> data = (IDictionary<string, object>)new System.Web.Routing.RouteValueDictionary(result.Data);
Assert.AreEqual("Table already exists.", data["Message"]);

2
코드를 게시하는 대신 솔루션을 더 잘 설명하는 것이 좋습니다. 어떻게 대답해야합니까?를 읽을 수 있습니다 .
Massimiliano Kraus

System.Web프로젝트 참조에 반드시 포함시켜야 합니다.
Ohad Cohen

-3
 using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(user)))
 {
    // Deserialization from JSON  
    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UserListing))
    DataContractJsonSerializer(typeof(UserListing));
    UserListing response = (UserListing)deserializer.ReadObject(ms);

 }

 public class UserListing
 {
    public List<UserList> users { get; set; }      
 }

 public class UserList
 {
    public string FirstName { get; set; }       
    public string LastName { get; set; } 
 }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.