代码之家  ›  专栏  ›  技术社区  ›  mko

无法反序列化xdocument

  •  2
  • mko  · 技术社区  · 6 年前

    我正在尝试将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 回复  |  直到 6 年前
        1
  •  2
  •   dbc    6 年前

    诊断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 )以及每个项的一个元素,在项类型之后命名(默认)(此处也 库存 )演示小提琴1 here .

    如果您不想这样做,您需要添加 [XmlElement] public List<Inventory> 像这样:

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

    现在 库存 将在没有外部容器元素的情况下序列化,因此反序列化代码将成功。演示小提琴2 here .

    (或者,您可以构建 XDocument 具有必要的额外嵌套级别。)