列表属性未从XML反序列化填充

时间:2017-07-12 15:44:31

标签: c# xml wpf deserialization

我正在尝试将xml文件反序列化为c#类。我使用在线工具为我生成类,因为XML文件的结构非常复杂。除了将重复项目填充到主类的List属性中之外,这种方法运行良好。

我在WPF中使用DotNet 4.5,C#。

xml文件的简化版本如下:

<orderMessage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:gs1:ecom:order:xsd:3">
  <order xmlns="">
    <creationDateTime>2017-07-10T00:00:00</creationDateTime>
    <documentStatusCode>ORIGINAL</documentStatusCode>
    <documentActionCode>ADD</documentActionCode>
  </order>
  <order xmlns="">
    <creationDateTime>2017-07-10T00:00:00</creationDateTime>
    <documentStatusCode>ORIGINAL</documentStatusCode>
    <documentActionCode>ADD</documentActionCode>
  </order>
</orderMessage>

我使用的课程如下:

[XmlRoot(ElementName = "order")]
public class Order
{
    [XmlElement(ElementName = "creationDateTime")]
    public string CreationDateTime { get; set; }
    [XmlElement(ElementName = "documentStatusCode")]
    public string DocumentStatusCode { get; set; }
    [XmlElement(ElementName = "documentActionCode")]
    public string DocumentActionCode { get; set; }
    [XmlAttribute(AttributeName = "xmlns")]
    public string Xmlns { get; set; }
}

[XmlRoot(ElementName = "orderMessage", Namespace = "urn:gs1:ecom:order:xsd:3")]
public class OrderMessage
{
    [XmlElement(ElementName = "order")]
    public List<Order> Order { get; set; }
    [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Xsd { get; set; }
    [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Xsi { get; set; }
    [XmlAttribute(AttributeName = "xmlns")]
    public string Xmlns { get; set; }
}

反序列化代码如下:

        XmlSerializer serializer = new XmlSerializer(typeof(OrderMessage));

        StreamReader reader = new StreamReader(filename);
        OrderMessage newOrderMessage;
        try
        {
            newOrderMessage = (OrderMessage)serializer.Deserialize(reader);
        }
        catch (Exception e)
        {
            throw e;
        }
        reader.Close();

当我运行代码时,它运行没有错误,但我最终得到一个空列表。 xml中还有其他结构(没有重复的结构 - 因此没有列表属性),这些结构填充没有我省略的问题。

我已经查看了一些类似于我的问题,但他们似乎提出了我使用的相同方法。

我无法更改XML,因为它来自第三方。

如果有人能指出我正确的方向,我将不胜感激。

BTW - 我知道捕获一个错误然后抛出它是没有用的,但我只是添加一个断点,所以我可以查看内部异常,如果有的话。一旦我的流程正常工作,我将使错误处理更有意义。

1 个答案:

答案 0 :(得分:2)

问题是您的Order属性 - 命名空间将继承自OrderMessage,因此当它应为空时为urn:gs1:ecom:order:xsd:3。您必须明确指定。

您还可以从模型中删除一堆与命名空间相关的属性。这就是你所需要的:

[XmlRoot("orderMessage", Namespace = "urn:gs1:ecom:order:xsd:3")]
public class OrderMessage
{
    [XmlElement("order", Namespace = "")]
    public List<Order> Orders { get; set; }
}

public class Order
{
    [XmlElement("creationDateTime")]
    public string CreationDateTime { get; set; }

    [XmlElement("documentStatusCode")]
    public string DocumentStatusCode { get; set; }

    [XmlElement("documentActionCode")]
    public string DocumentActionCode { get; set; }
}

顺便说一句,您的反序列化代码中的throw e;可能不是您想要做的(请参阅this question)。鉴于您实际上没有处理异常,在这种情况下您可以完全删除try / catch。

您还应将StreamReader括在using块中,以确保在使用后将其处理。