[c#] Json.net은 파생 유형을 직렬화 / 역 직렬화합니까?
json.net (newtonsoft)
문서를 살펴보고 있지만 이것에 대한 내용이나 최선의 방법을 찾을 수 없습니다.
public class Base
{
public string Name;
}
public class Derived : Base
{
public string Something;
}
JsonConvert.Deserialize<List<Base>>(text);
이제 직렬화 된 목록에 Derived 개체가 있습니다. 목록을 역 직렬화하고 파생 된 형식을 다시 가져 오는 방법은 무엇입니까?
답변
text
이 시나리오에서와 같이 유형을 저장하는 경우 JsonSerializerSettings
.
참조 : Newtonsoft JSON.NET을 사용하여 JSON을 IEnumerable <BaseType>으로 역 직렬화하는 방법
하지만 조심하세요. 다른 것을 사용 하면 보안 취약점에 노출TypeNameHandling = TypeNameHandling.None
될 수 있습니다 .
답변
유형 이름 처리를 활성화하고이를 설정 매개 변수로 (비) 직렬화기에 전달해야합니다.
Base object1 = new Base() { Name = "Object1" };
Derived object2 = new Derived() { Something = "Some other thing" };
List<Base> inheritanceList = new List<Base>() { object1, object2 };
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string Serialized = JsonConvert.SerializeObject(inheritanceList, settings);
List<Base> deserializedList = JsonConvert.DeserializeObject<List<Base>>(Serialized, settings);
이로 인해 파생 클래스의 올바른 역 직렬화가 수행됩니다. 단점은 사용중인 모든 개체의 이름을 지정하므로 개체를 넣는 목록의 이름이 지정된다는 것입니다.
답변
질문이 매우 인기가 있기 때문에 유형 속성 이름과 해당 값을 제어하려는 경우 수행 할 작업을 추가하는 것이 유용 할 수 있습니다.
긴 방법은 JsonConverter
type 속성을 수동으로 확인하고 설정하여 직렬화를 처리 (역) 할 사용자 지정을 작성하는 것입니다 .
더 간단한 방법은 속성을 통해 모든 상용구를 처리 하는 JsonSubTypes 를 사용 하는 것입니다.
[JsonConverter(typeof(JsonSubtypes), "Sound")]
[JsonSubtypes.KnownSubType(typeof(Dog), "Bark")]
[JsonSubtypes.KnownSubType(typeof(Cat), "Meow")]
public class Animal
{
public virtual string Sound { get; }
public string Color { get; set; }
}
public class Dog : Animal
{
public override string Sound { get; } = "Bark";
public string Breed { get; set; }
}
public class Cat : Animal
{
public override string Sound { get; } = "Meow";
public bool Declawed { get; set; }
}
답변
이 JsonKnownTypes를 사용하면 사용하는 것과 매우 유사하며 json에 판별자를 추가합니다.
[JsonConverter(typeof(JsonKnownTypeConverter<BaseClass>))]
[JsonKnownType(typeof(Base), "base")]
[JsonKnownType(typeof(Derived), "derived")]
public class Base
{
public string Name;
}
public class Derived : Base
{
public string Something;
}
당신이 직렬화 할 때 이제 JSON에서 개체가 추가됩니다 "$type"
함께 "base"
하고 "derived"
가치가 직렬화에 사용됩니다
직렬화 된 목록 예 :
[
{"Name":"some name", "$type":"base"},
{"Name":"some name", "Something":"something", "$type":"derived"}
]