개발/C#&unity

C# JsonConverter 사용

로 얄 2024. 2. 17. 21:16
반응형

newtonsoft.json을 사용하다보면 class를 직렬화, 역직렬화할때 형태를 변형하거나 추가 작업을 실행해줘야 하는 경우가 있다. 이를 모든 코드에서 진행해야할 경우 유지보수시 실수가 나기 딱 좋은 부분이다.

이런 부분에 대해서는 JsonConveter를 사용하여 처리하는 것이 좋다.

예제를 만들기 위해 불필요한 변형을 해보자

class내의 int형 멤버 변수가 존재하는데 이를 string으로 변형하여 json을 만들어보자

[JsonConverter(typeof(JSonTestConverter))]
public class JsonTest
{
    public int a;

    public override string ToString()
    {
        return $"a = {a}";
    }
}


public class JSonTestConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        if (value is JsonTest source)
        {
            writer.WriteStartObject();
            writer.WritePropertyName(nameof(JsonTest.a));
            writer.WriteValue(source.a.ToString());
            writer.WriteEndObject();
        }
    }

    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
    {
        var result = new JsonTest();
        
        var jObject = JObject.Load(reader);
        if (jObject.TryGetValue(nameof(JsonTest.a), out var value))
        {
            var strValue = value.Value<string>();
            result.a = int.TryParse(strValue, out var i) ? i : 0;
        }

        return result;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(JsonTest).IsAssignableFrom(objectType);
    }
}

 

위와 같이 JsonConverter를 상속받아 재 구현하고 원하는 class혹은 class를 사용하는 멤버변수위에 attribute만 넣어주면 된다. read, write할때 JsonReader, JsonWriter를 직접사용하여 구현이 가능하지만, 복잡도가 올라갈 수록 JObject를 사용하여 처리하는게 가독성 및 유지보수 면에서 좋을 것으로 생각된다. 따라서 예제를 섞어서 사용해보았다.

 

아래 실제로 동작을 확인하기 위해 직렬화, 역직렬화를 진행해보면 결과는 다음과 같다.

 

var jsonTest  = new JsonTest
{
    a = 200
};

var jsonResult = JsonConvert.SerializeObject(jsonTest);
Console.WriteLine(jsonResult);

var jsonObject =  JsonConvert.DeserializeObject<JsonTest>(jsonResult);
Console.WriteLine(jsonObject);

 

결과

{"a":"200"}
a = 200

 

만약 컨버터가 없었다면 당연히 {"a":200}으로 json에 숫자가 들어갔을 것이다.

반응형