Невозможно десериализовать XDocument - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь десериализовать XDocument в класс, который содержит массив / список. Проблема в том, что этот код не может это сделать, я всегда получаю класс Response без каких-либо элементов инвентаризации (не ноль, но количество = 0)

Вот мой метод испытаний:

public void GetObj()
{
    var xe = new XElement("Inventory");
    var xe2 = new XElement("Id", "23");
    xe.Add(xe2);

    var list = new List<XElement>();
    list.Add(xe);
    list.Add(xe);

    var doc = new XDocument(new XElement("Response", list));

    var obj = doc.Deserialize<Response>();
}

А вот мои методы и модели расширения:

public static class XDocumentExtensions
{
    public static T Deserialize<T>(this XDocument doc)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

        using (var reader = doc.Root.CreateReader())
        {
            return (T)xmlSerializer.Deserialize(reader);
        }
    }

    public static XDocument Serialize<T>(this T value)
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

        XDocument doc = new XDocument();
        using (var writer = doc.CreateWriter())
        {
            xmlSerializer.Serialize(writer, value);
        }

        return doc;
    }
}

public class Response
{
    public List<Inventory> Inventory { get; set; }
}

public class Inventory
{
    public int Id { get; set; }
}

1 Ответ

0 голосов
/ 16 ноября 2018

Самый простой способ диагностировать проблему с десериализацией XML - это создать экземпляр вашей модели в памяти и сериализовать его, а затем сравнить выходной XML с требуемым вводом.Таким образом, если я сделаю:

Console.WriteLine(new Response { Inventory = new List<Inventory> { new Inventory { Id = 23 } } }.Serialize() );

Выходной XML:

<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Inventory>
    <Inventory>
      <Id>23</Id>
    </Inventory>
  </Inventory>
</Response>

Как вы можете видеть, есть дополнительный уровень вложенности <Inventory> элементов.Это происходит потому, что по умолчанию XmlSerializer сериализует коллекции с внешним элементом элемента контейнера, названным в честь сериализованного члена (здесь Inventory), а также с элементом для каждого элемента, названного (по умолчанию) после типа элемента (здесьтакже Inventory).Демонстрационная скрипка # 1 здесь .

Если вы не хотите этого, вам нужно добавить [XmlElement] к public List<Inventory> примерно так:

public class Response
{
    [XmlElement]
    public List<Inventory> Inventory { get; set; }
}

Теперь Inventory будет сериализован без внешнего элемента контейнера, и ваш код десериализации будет успешно выполнен.Демонстрационная скрипка # 2 здесь .

(В качестве альтернативы вы можете создать свой XDocument с необходимым дополнительным уровнем вложенности.)

...