Newtonsoft. Json .JsonConvert.DeserializeObject в Newtonsoft. Json .Linq.JObject проблемы - PullRequest
1 голос
/ 27 февраля 2020

Я работаю над проектом C#.

[
  {"FirstName":"XYZ","LastName":"SSS"},
  {"FirstName":"ABC","LastName":"NNN"}
]

Каждая строка представляет объект класса ChildDTO.

Я читаю вышеуказанные данные из файла и пытаюсь десериализовать в объект ParentCollection, как показано ниже:

string file = System.IO.File.ReadAllText("Children_CA.txt");
ParentCollection pCollection = Newtonsoft.Json.JsonConvert.DeserializeObject<ParentCollection>(file);

Мои классы DTO такие, как показано ниже:

[Serializable]
public class ParentCollection : CollectionBase
{    
  public void Add(ChildDTO dto)
  {
      //List is from Systems.Collections.CollectionBase class
      List.Add(dto);
  }
}

[Serializable]
public class ChildDTO
{
   // properties like FirstName and LastName goes here
}

Я не могу изменить свои классы DTO, так как они старые и уже находятся в производстве с последние 20 лет и многие приложения используют их.

Когда я вижу Quick Watch на pCollection, я замечаю, что в коллекции есть объекты типа Newtonsoft. Json .Linq.JObject. Я надеюсь иметь объекты типа ChildDTO

enter image description here

Пожалуйста, дайте мне знать, какую ошибку я делаю.

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Проблема в том, что CollectionBase и, соответственно, ваш ParentCollection класс, не являются обобщенными c, поэтому Json. Net не знает, что элементы в коллекции должны быть ChildDTO объекты. Поскольку он не знает, к какому типу относятся предметы, он просто использует JObject. Вы можете решить проблему, используя пользовательский класс JsonConverter, например:

class ParentCollectionConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(ParentCollection);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        ParentCollection pc = new ParentCollection();
        JArray array = JArray.Load(reader);
        foreach (var item in array)
        {
            pc.Add(item.ToObject<ChildDTO>());
        }
        return pc;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Чтобы использовать конвертер, передайте его в DeserializeObject<T> следующим образом:

ParentCollection pCollection = 
    JsonConvert.DeserializeObject<ParentCollection>(json, new ParentCollectionConverter());

Рабочая демонстрация здесь : https://dotnetfiddle.net/3GM22c

0 голосов
/ 27 февраля 2020

Доброе утро. Если вам нужен список ChildDto, пожалуйста, преобразуйте его в список. Пожалуйста, обратитесь к коду и изображению ниже. Большое спасибо.

            string file = System.IO.File.ReadAllText("Children_CA.txt");
            var results1 = JsonConvert.DeserializeObject<List<ChildDTO>>(file);

Code with output Image

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...