JSON 데이터 직렬화 및 역직렬화하기 (Json.NET vs JavaScriptSerializer)
데이터를 json 형태로 주고 받는 것은 업무를 하다보면 일상적이다.
특히 자바에서는 그렇다고 하는데,
나의 경우 업무 중 c#를 많이 써서 c# 기준 json 데이터 직렬화 및 역직렬화를 정리하고자 한다.
리피터 사용을 줄이고, json으로 많이 써보는 연습도 해야겠다!!
앞으로 소개할 json 데이터 직렬화 및 역직렬화는 Json.NET과 JavaScriptSerializer 두 가지며,
Json.NET의 경우 'C# 교과서'를 참고했다.
Json.NET :: JSON 데이터 직렬화 및 역직렬화하기
JSON(JavaScript Object Notation) 데이터는 최근 프로그래밍에서 많이 사용하는 데이터 구조입니다.
C# 개체를 JSON 문자열로 변환하는 내용을 직렬화(serialize)라고 하며,
그 반대로 JSON 문자열을 C# 개체로 변환하는 것을 역직렬화(deserialize)라고 합니다.
• 직렬화: C# 개체를 JSON 데이터로 변환
• 역직렬화: JSON 데이터를 C# 개체로 변환
이러한 JSON 직렬화 및 역직렬화를 편리하게 사용할 수 있는 API는 JSON.NET 이름의 다음 URL에 있는 NuGet 패키지를 활용합니다.
https://www.nuget.org/packages/Newtonsoft.Json/
Newtonsoft.Json 13.0.2
Json.NET is a popular high-performance JSON framework for .NET
www.nuget.org
Json.NET :: JSON 데이터 다루기
JSON 데이터를 다루는 다음 내용을 C# 인터렉티브에서 단계별로 실행해 보세요. 프로젝트 기반 소스는 JsonConvertDemo.cs 파일에 있습니다.
1. 먼저 JSON.NET을 사용하려면 Newtonsoft.Json.dll 파일을 NuGet 패키지 관리자를 사용하여 참조해야 합니다. C# 인터렉티브에서는 다음 코드로 참조 가능합니다.
> #r "Newtonsoft.Json"
2. DLL 파일을 참조한 후 코드 위쪽의 네임스페이스를 참조합니다.
> using Newtonsoft.Json;
3. 샘플 클래스인 Shirt를 다음과 같이 만듭니다.
> public class Shirt
. {
. public string Name { get; set; }
. public DateTime Created { get; set; }
. public List<string> Sizes { get; set; }
. }
4. 먼저 C# 개체를 JSON 데이터로 변환하는 직렬화 예제를 구현하겠습니다. 직렬화는 JsonConvert 클래스의 SerializeObject() 메서드를 사용합니다.
> //① 직렬화(serialize) 데모
. Shirt shirt1 = new Shirt
. {
. Name = "Red Shirt",
. Created = new DateTime(2020, 01, 01),
. Sizes = new List<string> { "Small" }
. };
. string json1 = JsonConvert.SerializeObject(shirt1, Formatting.Indented);
. Console.WriteLine(json1);
{
"Name": "Red Shirt",
"Created": "2020-01-01T00:00:00",
"Sizes": [
"Small"
]
}
앞 실행 결과처럼 shirt1의 C# 개체는 json1의 JSON 데이터로 변환된 것을 알 수 있습니다.
5. 이번에는 JSON 데이터를 C# 개체로 변환하는 역직렬화를 구현하겠습니다. 역직렬화는 JsonConvert 클래스의 DeserializeObject() 메서드를 사용합니다.
> //② 역직렬화(deserialize) 데모
. string json2 = @"{
. 'Name': 'Black Shirt',
. 'Created': '2020-12-31T00:00:00',
. 'Sizes': ['Large', 'Small' ]
. }";
. Shirt shirt2 = JsonConvert.DeserializeObject<Shirt>(json2);
. Console.WriteLine($"{shirt2.Name} - {shirt2.Created}");
Black Shirt - 2020-12-31 오전 12:00:00
> Console.WriteLine(string.Join(",", shirt2.Sizes.ToArray()));
Large,Small
Json2 문자열에 저장된 JSON 데이터를 형태가 같은 Shirt 개체로 변환하여 각 속성 값을 출력한 것처럼 JSON.NET을 사용하면 쉽게 직렬화 및 역직렬화를 구현할 수 있습니다.
닷넷에서는 많은 수의 XML과 JSON 관련 API를 제공하는데, 필요할 때마다 이들을 모두 호출해서 사용할 수 있어야 합니다. 이 책을 모두 학습한 후 웹과 모바일 프로그래밍을 좀 더 공부하고 싶을 때는 관련 도서나 마이크로소프트 Docs 온라인 설명서로 XML과 JSON 관련 API들을 자세히 알아보길 권장합니다.
(이제 JavaScriptSerializer다!!)
JavaScriptSerializer 클래스
WinForms, 콘솔, 혹은 WPF 프로그램을 비롯한 .NET Application에서 .NET에 Built-in 된 클래스를 사용해서 간단히 JSON을 사용하려면 JavaScriptSerializer 클래스를 사용할 수 있다. JavaScriptSerializer 클래스는 .NET 3.5 이상에서 사용할 수 있는 클래스로서 System.Web.Extensions.dll 을 참조하여 사용한다. 만약 .NET 버전이 3.5 미만인 경우 JSON.NET를 사용한다.
.NET 객체를 JSON 포맷의 문자열로 만들기 위해서는 (이를 Serialization 이라 한다) JavaScriptSerializer 의 Serialize() 메소드를 사용한다. 또한 반대로 JSON 문자열을 다시 .NET 객체로 복원하기 위해서는 (이를 Deserialization 이라 한다) JavaScriptSerializer 의 Deserialize 메서드를 사용한다. 아래 예제는 Person 이라는 .NET 클래스 객체를 JSON 포맷으로 변형했다가 이를 다시 복원하는 샘플 코드이다.
예제
namespace jsonApp
{
// 1. System.Web.Extensions.dll 참조 (.NET 3.5+)
using System.Web.Script.Serialization;
// JavaScriptSerializer 를 이용한 Json 예제
class JsonUsingJavaScriptSerializer
{
public void DoTest()
{
// 2. JSON string 만들기
var p = new Person { Id = 1, Name = "Alex" };
var jss = new JavaScriptSerializer();
string jsonString = jss.Serialize(p);
System.Diagnostics.Debug.WriteLine(jsonString);
// 3. JSON string으로부터 Object 가져오기
Person pObj = jss.Deserialize<Person>(jsonString);
System.Diagnostics.Debug.WriteLine(pObj.Name);
}
}
class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
JavaScriptSerializer의 문제점
JavaScriptSerializer는 사용하기 간편하고 .NET에 이미 내장된 클래스라는 장점을 가지고 있지만, 반면 2가지 큰 단점을 가지고 있다.
(1) 날짜형 데이타 처리 : JavaScriptSerializer는 날짜형 데이타를 출력할 때 (많은 일반 브라우져와 외부 Serializer들이 채택하는) ISO 8601 표준을 따르지 않고, Unix timestamp에 기초한 MS 고유의 날짜 포맷('\/Date(ticks)\/' (예)'/Date(1419494400000)/' )으로 출력하는 문제점이 있다. 만약 ASP.NET AJAX의 Microsoft Ajax Library를 사용한다면 이러한 날짜 포맷은 자동으로 JavaScript Date 객체로 변형되지만, Microsoft Ajax Library를 사용하지 않는 경우 개발자는 JavaScript에서 전달받는 JSON 날짜 데이타에 대해 특별한 변형을 취해 주어야 한다. 이러한 문제점을 해결하는 Workaround로서 서버 상에서 날짜를 문자열로 변형하여 보내는 방법이 있다.
(2) Circular Reference (순환 참조) : JavaScriptSerializer는 JSON 객체들이 Circular Reference를 하고 있을 때 이를 핸들링하지 못하는 단점이 있다. 아래 예제는 Circular Reference의 예를 나타낸 것으로 A는 B를 참조하고 B는 C를 그리고 다시 C는 A를 참조하고 있다. 이러한 Circular Reference 상황에서 JSON을 사용하기 위해서는 JSON.NET을 이용한다.
Json.NET vs JavaScriptSerializer 중 무얼 쓸지는 자유겠지만,
Json.NET Documentation에서 비교해둔 사진과 링크를 첨부한다.
나의 경우 Json.NET를 더 사용할 것 같다!
https://www.newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm
