[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);

이로 인해 파생 클래스의 올바른 역 직렬화가 수행됩니다. 단점은 사용중인 모든 개체의 이름을 지정하므로 개체를 넣는 목록의 이름이 지정된다는 것입니다.


답변

질문이 매우 인기가 있기 때문에 유형 속성 이름과 해당 값을 제어하려는 경우 수행 할 작업을 추가하는 것이 유용 할 수 있습니다.

긴 방법은 JsonConvertertype 속성을 수동으로 확인하고 설정하여 직렬화를 처리 (역) 할 사용자 지정을 작성하는 것입니다 .

더 간단한 방법은 속성을 통해 모든 상용구를 처리 하는 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"}
]


답변