JSON 과 AJAX 그리고 C#




Intro

 오랜만에 포스팅을 합니다. 그 동안 너무 바빠서 글쓸 시간이 없었네요.
아시다시피 핑계입니다 ㅎ;;

아무튼 오늘은 JSON(JavaScript Object Notation)에 대해서 알아볼까 합니다.
제가 JSON(제이슨 : 13일의 금요일만 되면 나오는 그분과 이름이 같네요)을 처음 접한건 2007년으로 기억합니다.
AJAX 가 한창 대두되었을 때, JSON 에 대해서 보았거든요.

당시에는 SOAP 형태로 메세지를 주고 받았기 때문에, JSON 에 대해서 큰 관심도 필요성도 느끼지 못했습니다.
네이버, 구글과 같은 대부분의 회사에서도 AJAX 페이지 정보를 XML 형태로 넘겨 주었습니다. 다시말해 JSON 을 사용하는 사례는 별로 없었지요.

그런데 갑자기 왜 JSON 에 관심을 가지느냐~
얼마전 재미삼아 카카오톡을 까보고 있는데, JSON 으로 메세지를 주고 받는것 아닙니까?!
요즘은 JSON 을 많이 쓰더군요.

그래서 한번 살펴볼까 합니다.
참고로 매우 쉽습니다.



JSON 이란?


JSON (an acronym for JavaScript Object Notation pronounced /ˈdʒeɪsən/) is a lightweight text-based open standard designed for human-readable data interchange. It is derived from the JavaScript programming language for representing simple data structures and associative arrays, called objects. Despite its relationship to JavaScript, it is language-independent, with parsers available for most programming languages.

The JSON format was originally specified by Douglas Crockford, and is described in RFC 4627. The official Internet media type for JSON is application/json. The JSON filename extension is .json.

The JSON format is often used for serializing and transmitting structured data over a network connection. It is primarily used to transmit data between a server and web application, serving as an alternative to XML.

위키백과(위키피디아)에 보면 위와 같이 정의되어 있습니다.

1. 문자 기반으로 한 데이타 표현하는 방식이다.
2. 객체를 나타내는 JavaScript 의 문법이다.
3. 언어에 독립적이기 때문에, 어느 언어에서든지 파싱이 가능하다.
4. 미디어 타입으로는 application/json 을 사용하며, 파일 확장자는 .json 이다.
5. 웹상에서 데이타를 주고 받는데 많이 사용된다.

이 정도로 요약할 수 있겠네요.



Syntax 살펴보기
 
먼저 우리에게 익숙한 XML 형태의 데이타를 먼저 살펴보도록 하겠습니다.


<person>
  <firstName>John</firstName>
  <lastName>Smith</lastName>
  <age>25</age>
  <address>
    <streetAddress>21 2nd Street</streetAddress>
    <city>New York</city>
    <state>NY</state>
    <postalCode>10021</postalCode>
  </address>
  <phoneNumber type="home">212 555-1234</phoneNumber>
  <phoneNumber type="fax">646 555-4567</phoneNumber>
</person> 


이 자료를 JSON 으로 표현하면 아래와 같습니다


{
     "firstName": "John",
     "lastName": "Smith",
     "age": 25,
     "address":
     {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": "10021"
     },
     "phoneNumber":
     [
         {
           "type": "home",
           "number": "212 555-1234"
         },
         {
           "type": "fax",
           "number": "646 555-4567"
         }
     ]
 } 




감이 오시나요?

기본적으로 {} 를 감싸서 데이타를 표현하고 배열은 [] 를 가지고 나타냅니다.
키:값 쌍으로 나타낸다고 생각하시면 됩니다.

XML 과 비교했을 때, 가장 큰 장점은 데이타 크기가 줄어든다는 것과 자바스크립트의 eval 을 통해서 바로 실행가능하다라는 거죠.
하지만 eval 을 사용할 경우 보안상 이슈가 있기 때문에, 되도록 사용하지 않고 별도의 파서를 사용하는 방식을 권장합니다.
아무튼 심플합니다!



C# 에서 JSON 사용하기

 JSON 을 C# 에서 파싱하는 방법에 대해서 구글링 해보면 많은 글이 나타납니다.
흔히들 JSON 오픈 라이브러리를 사용하는 방식들이죠.
또한 라이브러리도 엄청나게 많습니다.
json 공식 홈페이지에서도 C# 용 파서를 제공해 주지요.

하지만!
저는 기본적으로 .NET 에서 제공해 주는 것 이외에 별도 라이브러리를 사용하는 것을 좋아하지 않습니다.
왜냐면, 프레임워크에 버젓이 있는데, 괜히 dll 을 추가해서 사용하면
라이센스 문제, 용량 증가, 파일수 증가, dll 누락문제
등등 귀찮은 일들이 많이 생기기 때문이죠.

아무튼, 저는 .NET 3.5 프레임워크 이상부터 포함된 내장객체를 사용하여 JSON 을 serialize / deserialize 해 보도록 하겠습니다.


1. 프로젝트에 System.ServiceModel.Web / System.Runtime.Serializations 을 참조(Reference)추가합니다.





2. 샘플코드


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

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

namespace JsonSample
{
    class Program
    {
        static void Main(string[] args) {
            Person p = new Person();
            p.name = "John";
            p.age = 42;

            // Serialize
            MemoryStream stream1 = new MemoryStream();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
            ser.WriteObject(stream1, p);

            // 출력
            stream1.Position = 0;
            StreamReader sr = new StreamReader(stream1);
            Console.Write("JSON from of Person objet: ");
            Console.WriteLine(sr.ReadToEnd());


            // Deserialize
            stream1.Position = 0;
            Person p2 = ser.ReadObject(stream1) as Person;

            // 출력
            String result = String.Format(
                "Deserialized back, got name={0}, age={1}", p2.name, p2.age);
            Console.WriteLine(result);

            stream1.Close();
            sr.Close();
        }
    }

    [Serializable]
    internal class Person
    {
        internal string name;
        internal int age;
    }

} 





Epilogue

매우 간단하죠?

MemoryStream stream1 = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
ser.WriteObject(stream1, p);

를 통해서 Serialize 하고,

stream1.Position = 0;
Person p2 = ser.ReadObject(stream1) as Person;

를 통해서 Deserialize 합니다.