반응형
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에 숫자가 들어갔을 것이다.
반응형
'개발 > C#&unity' 카테고리의 다른 글
C# 반올림, 올림, 버림 (0) | 2024.03.09 |
---|---|
Newtonsoft.Json 사용시 생성자에서 리스트를 초기화할때 중복으로 들어가는 문제 (0) | 2024.02.17 |