반응형

이번에는 Newtonsoft.Json에 대해서 소개하도록 하겠습니다.

 

 

System.Text.Json으로도 json데이터를 처리할 수 있지만

너무나 편리하고 기존에 만들어진 소스에서 많이 사용하고 있어서 사용하게 되었고 설명드리고자 합니다.

 

 

요즘에는 xml을 거의 사용하지 않고 json으로 데이터를 주고받으면서

 

많이 사용하고 있죠

 

using Newtonsoft.Json;

으로 설치한 nuget 패키지를 사용할 파일에서 import하시면 사용가능합니다.

 

Newtonsoft.Json의 주요기능

 

문자열로 변환 가능한 클래스를 json 데이터로 변환하는 것

json 형태의 문자열을 클래스로 변환하는 것입니다.

 

 

 

먼저 예시로 사용할 클래스를 만들어보도록 하겠습니다.

( 참고로 github에 올려두었습니다. 원본 소스가 궁금하신분들은 여기서 내려받거나 복사하시면 되겠습니다. - msab2170/tistory50_Newtonsoft.Json_Example: 티스토리 블로그 50번 글 소스파일 (github.com)

 

GitHub - msab2170/tistory50_Newtonsoft.Json_Example: 티스토리 블로그 50번 글 소스파일

티스토리 블로그 50번 글 소스파일. Contribute to msab2170/tistory50_Newtonsoft.Json_Example development by creating an account on GitHub.

github.com

 

class Example
{
    public List<Fruit> Fruits;
    public string Str;
    public int Number = 0;
    public int NumberDefault0 = 0;
    public bool IsOk;
    public string? NullableStr;
    public int? NullableInteger;
}

class Fruit
{
    public string Name;
    public int price;
}

 

 

그리고 아래는 실행할 소스 입니다.

 

using Newtonsoft.Json;

Example example = new()
{
    Str = "문자열",
    Number = 10,
    NumberDefault0 = 0,
    IsOk = true,
    NullableStr = null,
    NullableInteger = null
};

var exampleJson0 = JsonConvert.SerializeObject(example);
var exampleJson1 = JsonConvert.SerializeObject(example, Formatting.None);
var exampleJson2 = JsonConvert.SerializeObject(example, Formatting.Indented);
var exampleJson3 = JsonConvert.SerializeObject(example, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var exampleJson4 = JsonConvert.SerializeObject(example, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
var exampleJson5 = JsonConvert.SerializeObject(example, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
var exampleJson6 = JsonConvert.SerializeObject(example, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

Console.WriteLine($"exampleJson0: {exampleJson0}");
Console.WriteLine($"exampleJson1: {exampleJson1}");
Console.WriteLine($"exampleJson2: {exampleJson2}");
Console.WriteLine($"exampleJson3: {exampleJson3}");
Console.WriteLine($"exampleJson4: {exampleJson4}");
Console.WriteLine($"exampleJson5: {exampleJson5}");
Console.WriteLine($"exampleJson5: {exampleJson6}");

 

아래는 실행 결과값입니다.

exampleJson0: {"Fruits":null,"Str":"문자열","Number":10,"NumberDefault0":0,"IsOk":true,"NullableStr":null,"NullableInteger":null}
exampleJson1: {"Fruits":null,"Str":"문자열","Number":10,"NumberDefault0":0,"IsOk":true,"NullableStr":null,"NullableInteger":null}
exampleJson2: {
  "Fruits": null,
  "Str": "문자열",
  "Number": 10,
  "NumberDefault0": 0,
  "IsOk": true,
  "NullableStr": null,
  "NullableInteger": null
}
exampleJson3: {"Str":"문자열","Number":10,"NumberDefault0":0,"IsOk":true}
exampleJson4: {"Str":"문자열","Number":10,"IsOk":true}
exampleJson5: {
  "Str": "문자열",
  "Number": 10,
  "IsOk": true
}
exampleJson5: {
  "Str": "문자열",
  "Number": 10,
  "NumberDefault0": 0,
  "IsOk": true
}

JsonConvert.SerializeObject(example); 했을때 default로 들어가는 설정들이 보이시나요?

 

위에 적은 예시에서 exampleJson 뒤에 붙은 숫자대로 설명하겠습니다.

 

0. 기본적으로 JsonConver.SerializeObject() 내에 별다른 설정 값이 없다면

 

Example 클래스를 토대로 json형태로 변환하는데

null값이 있으면 "변수명":null로 입력이 된다는 것을 알 수 있고,

클래스의 모양을 무시하고 한 줄에 출력된다는 것을 알 수 있습니다.

 

 

1. 을 보면 JsonConvert.SerializeObject(example, Formatting.None); 가 0의 예시와 동일하다는 것을 알 수 있죠,

이를 토대로 우리는

 

클래스 모양을 무시하고 한 줄로 치는 값은 Formatting형 값인 Formatting.None이라는 것을 알 수 있습니다.

 

 

2.에서는 Formatting형 값을 Formatting.Indented로 주자 클래스 모양처럼 보기 쉽게 문자열이 변형됨을 알 수 있습니다.

가독성을 높인 대신에 쓸데없이 라인을 많이 잡아먹는다는 단점이 있습니다.

 

제 경험상 주고받을때는 굳이 공간을 더 쓸 필요없기 때문에 한줄로 주로 사용하는 경우가 많았고

로그로 남길때는 라인수냐 가독성이냐 일부 논의를 할 수 있지만 역시 한 줄로 사용하는 경우가 많았습니다.

 

 

3번과 4번은 설계에 따라서 많이 사용하기도 합니다.

JsonConvert.SerializeObject(example, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

 

JsonConvert.SerializeObject 함수의 세번째 변수자리에는 JsonSerializerSettings 클래스 변수를 사용하는데 이는 변환시 필터작업?을 포함합니다.

 

JsonSerializerSettings  내에는 대표적으로 3번과 4번에 쓰인 NullValueHandlingDefaultValueHandling 가 있습니다.

사용 형식은 위 예제대로

new JsonSerializerSettings {

    NullValueHandling = NullValueHandling.Ignore

}

의 방식이고 쉼표로 구분해 둘 또는 다른 설정과 같이 쓸 수도 있으며,

 

 

NullValueHandling.Ignore은 변환하고자하는 인스턴스 내 변수 값이 null 이면 이를 없는 셈치고 json으로 변환합니다.

3번과 6번을 보면 null 값이 담겨있는 Fruits와 NullableStr, NullableInteger 가 사라졌다는 것을 알 수 있습니다.

반대 값은 NullValueHandling.Include 이며 이는 디폴트값이라 따로 지정할 필요는 없습니다.

 

 

DefaultValueHandling도 마찬가지 기능입니다. Ignore와 Include가 있으며 비교대상이 null에서 지정한 기본값으로 변했습니다. int는 보통 기본값이 0이고 그외는 null 이기 때문에 지정해놓은 기본값이 없다면 null인 경우에 무시됩니다.

 

4번과 5번을 보면 null값과 기본값으로 지정한 값 모두 사라졌다는 것을 알 수 있습니다.

 

 

JsonSerializerSettings 에는 그 외에도 StringEscapeHandling, TypeNameHandling, Converters 등이 있는데 제가 사용해본적은 없기 때문에 이번 설명에서는 제외하였습니다.

 

 

JsonConvert.SerializeObject() 에 대한 설명이었습니다.

-----------------------------------------------------------------------------------------------------------------

인스턴스를 json형태로 변환했는데 json형태의 문자열을 클래스의 인스턴스로 변환하는 것도 있어야겠죠?

 

우선 이해를 돕기 위한 코드를 작성하겠습니다.

 

class Example
{
    public List<Fruit> Fruits;
    public string Str;
    public int Number = 0;
    public int NumberDefault0 = 0;
    public bool IsOk;
    public string? NullableStr;
    public int? NullableInteger;

    public override string? ToString() => JsonConvert.SerializeObject(this);
    public string? ToStringJson() => JsonConvert.SerializeObject(this, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore});
    public string? ToString2() =>
        "Fruits=" + (Fruits == null ? "null" : Fruits.ToString()) +
        "\n&Number=" + Number +
        "\n&NumberDefault0=" + NumberDefault0 +
        "\n&IsOk=" + IsOk +
        "\n&NullableStr=" + (NullableStr == null ? "null" : NullableStr.ToString()) +
        "\n&NullableInteger=" + (NullableInteger == null ? "null" : NullableInteger.ToString());
}

class Fruit
{
    public string Name;
    public int price;
}

Example 클래스를 출력 가능하게 바꾸는 클래스를 기본 ToString()을 override 한것 외에도 두개를 더 만들었고

 

 

다음은 실행 코드 입니다.

Example example = new()
{
    Str = "문자열",
    Number = 10,
    NumberDefault0 = 0,
    IsOk = true,
    NullableStr = null,
    NullableInteger = null
};

// 1.------------------------------------------------
var exampleJson0 = JsonConvert.SerializeObject(example);
Console.WriteLine($"example: {example}");
Console.WriteLine($"example.ToStringJson(): {example.ToStringJson()}");
Console.WriteLine($"example.ToString2(): {example.ToString2()}");

// 2.------------------------------------------------
var ex0 = JsonConvert.DeserializeObject(exampleJson0);
Console.WriteLine($"{ex0.GetType().Name}: {ex0}");
//Console.WriteLine($"ex0.ToStringJson(): {ex0.ToStringJson()}");
//Console.WriteLine($"ex0.ToString2(): {ex0.ToString2()}");

// 3.------------------------------------------------
var ex1 = JsonConvert.DeserializeObject<Example>(exampleJson0);
Console.WriteLine($"{ex1.GetType().Name}: {ex1}");
Console.WriteLine($"ex1.ToStringJson(): {ex1.ToStringJson()}");
Console.WriteLine($"ex1.ToString2(): {ex1.ToString2()}");

실행 코드에서

 

우선 설명드릴 내용은 json 형태의 string문자열을 객체로 변환하는 함수는 

 

JsonConvert.DeserializeObject(json문자열)

JsonConvert.DeserializeObject<T>(json문자열); 

 

 

1. 단락은 example 인스턴스를 json으로 변환하여 exampleJson0 인스턴스에 string 문자열로 담았던 내용이구요

2. 는 JsonConvert.DeserializeObject() 를 이용해서 다시 객체로 만든 것입니다.

2.에 하단부는 왜 주석처리를 해놨냐, JsonConvert.DeserializeObject()로 리턴 받은 ex0의 객체는 Example클래스의 인스턴스가 아니기 때문입니다.

 

더 정확히 말하면 타입을 지정하지 않아 JObject형태가 되버린 ex0은

Object클래스의 메소드인 .ToString()은 쓸 수 있으나

Example클래스의 메소드인 ToStringJson()와 ToString2()를 사용할 수 없기 때문입니다.

 

이를 보정하기 위한 3.은 json문자열을 원하는 클래스타입을 제네릭으로 작성하면 해당 클래스타입으로 받아옵니다.

따라서 Example? 형태이며, Example클래스의 메소드를 모두 사용할 수 있게 됩니다.

 

받아오는 형태를 모르는 것이 아니라면 꼭 제네릭으로 사용하시는 것을 권장드립니다.

 

 

이것으로 Newtonsoft.Json 에대한 설명을 마칩니다. 

부족한 부분이나 문의는 댓글로 남겨 주시면 반영하도록 노력하겠습니다. 

반응형

+ Recent posts