Newtonsoft가 상속 또는 하위 클래스 개체 목록을 올바르게 역 직렬화 할 수 있습니까? [복제]

Dec 08 2020

Newtonsoft (with TypeNameHandling.All)를 사용하여 List<Animal>a <Cat>와 a 를 포함하는 a 를 <Dog>직렬화하면 문자열을 다시 a로 역 직렬화하면 List<Animal>상속을 잃고 <Animals>.

Newtonsoft가 List상위 클래스 로 역 직렬화 될 때 하위 클래스를 보존 할 수있는 방법이 있습니까?

개체는 다음과 같습니다.

 public class Zoo
    {
        public List<Animal> Animals;

        public Zoo()
        {
            Animals = new List<Animal>();
        }
    }
    public class Animal
    {

    }

    public class Dog : Animal
    {

    }

    public class Cat : Animal
    {

    }
}

테스트는 다음과 같습니다.

static void Main(string[] args)
        {
            var zoo = new Zoo();
            var dog = new Dog();
            var cat = new Cat();
            zoo.Animals.Add(dog);
            zoo.Animals.Add(cat);

            var json = JsonConvert.SerializeObject(zoo, Formatting.None,
                new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.All
                });

            var newZoo = JsonConvert.DeserializeObject<Zoo>(json);
        }

원래 Zoo.Animal 목록은 다음과 같습니다 (개 및 고양이 유형에 유의).

이제 직렬화되면 하위 클래스가 올바르게 포함되었는지 확인할 수 있습니다. 비슷한 객체로 역 직렬화하기에 충분한 정보 여야합니다.

{
    "$type": "Sample.Sandbox.Zoo, Sample.Sandbox", "Animals": { "$type": "System.Collections.Generic.List`1[[Sample.Sandbox.Animal, Sample.Sandbox]], System.Private.CoreLib",
        "$values": [ { "$type": "Sample.Sandbox.Dog, Sample.Sandbox"
            },
            {
                "$type": "Sample.Sandbox.Cat, Sample.Sandbox"
            }
        ]
    }
}

이 직렬화 복원됩니다 때 단, Dog와는 Cat사라입니다. 그들은 단지입니다 Animals지금 :

Newtonsoft가 JSON을 올바르게 역 직렬화하고 하위 클래스 유형을 유지하는 방법이 있습니까?

팁에 감사드립니다.

답변

1 Richard Dec 08 2020 at 12:10

시리얼 라이저와 디시리얼라이저 모두에 설정을 추가해야합니다.

이 시도:

JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
var json = JsonConvert.SerializeObject(zoo,settings);    
var newZoo = JsonConvert.DeserializeObject<Zoo>(json,settings);
    
foreach (var currentAnimal in newZoo.Animals)
{ 
   Console.WriteLine(currentAnimal.GetType().Name);
}

출력해야 함 : 개 고양이