2016-03-07 5 views
3

У меня есть простой пример того, что я свалился с моего реального кода. Проблема в том, что я могу создать класс C# ниже, если я могу явно назначить тип в иерархии классов. Но мой массив панелей не создает подклассу TwoColumnPanel. Вместо этого я получаю только одну панель в списке панелей.Попытка десериализации массива xml в классы C# с подклассами

[TestMethod] 
    public void XmlRepoCreatesTestRepo() 
    { 
     object obj; 
     using (XmlReader reader = XmlReader.Create(new StringReader(TestXml))) 
     { 
      reader.MoveToContent(); 
      switch (reader.Name) 
      { 
       case "TestRepo": 
        obj = new XmlSerializer(typeof(TestRepo)).Deserialize(reader); 
        break; 
       default: 
        throw new NotSupportedException("Unexpected: " + reader.Name); 
      } 
     } 
    } 

    public string TestXml = @"<TestRepo> 
           <Name>Wandercoder Was Here</Name> 
           <Page> 
            <Panel> 
             <ColumnAttribute>1</ColumnAttribute> 
            </Panel> 
            <TwoColumnPanel> 
             <ColumnAttribute>2</ColumnAttribute> 
            </TwoColumnPanel> 
            <Panels> 
             <Panel> 
              <ColumnAttribute>1</ColumnAttribute> 
             </Panel> 
             <TwoColumnPanel> 
              <ColumnAttribute>2</ColumnAttribute> 
             </TwoColumnPanel> 
            </Panels> 
           </Page> 
          </TestRepo>"; 
} 

[DataContract] 
[Serializable] 
public class TestRepo 
{ 
    [DataMember] 
    public string Name { get; set; } 
    [DataMember] 
    public Page Page { get; set; } 
} 
[DataContract] 
[Serializable] 
public class Page 
{ 
    //This works. 
    [DataMember] 
    public Panel Panel { get; set; } 
    //This works, too. 
    [DataMember] 
    public TwoColumnPanel TwoColumnPanel { get; set; } 
    //For this one, however, I only get the one Panel when I deserialize. 
    //Why doesn't it properly deserialize the TwoColumnPanel specified in the xml above. 
    [DataMember] 
    public List<Panel> Panels { get; set; } 
} 
[DataContract] 
[Serializable] 
public class Panel 
{ 
    [DataMember] 
    public int ColumnAttribute { get; set; } 
} 
[DataContract] 
[Serializable] 
[XmlRoot("Panel")] 
public class TwoColumnPanel : Panel 
{ 
    public TwoColumnPanel() 
    { 
     ColumnAttribute = 2; 
    } 
} 

ответ

3
[DataContract] 
[Serializable] 
public class Page 
{ 
    //This works. 
    [DataMember] 
    public Panel Panel { get; set; } 
    //This works, too. 
    [DataMember] 
    public TwoColumnPanel TwoColumnPanel { get; set; } 
    //For this one, however, I only get the one Panel when I deserialize. 
    //Why doesn't it properly deserialize the TwoColumnPanel specified in the xml above. 
    [DataMember] 
    [XmlArray("Panels")] 
    [XmlArrayItem("TwoColumnPanel", typeof(TwoColumnPanel))] 
    [XmlArrayItem("Panel", typeof(Panel))] 
    public List<Panel> Panels { get; set; } 
} 
2

Try используя XmlArrayItem атрибут:

[DataMember] 
[XmlArrayItem("Panel", typeof(Panel))] 
[XmlArrayItem("TwoColumnPanel", typeof(TwoColumnPanel))] 
public List<Panel> Panels { get; set; }