4

I have a very simple XML file below:

<Job Name="test">
    <Pages>
        <MainPage Name="page1"/>
    </Pages>
</Job>

'MainPage' is a derived class of PageBase, with my class structure as below

public class Job
{
    [XmlAttribute]
    public string Name { get; set; }

    [XmlElement]
    public List<PageBase> Pages { get; set; }
}

[XmlInclude(typeof(MainPage))]
[XmlInclude(typeof(SubPage))]
public abstract class PageBase
{
    [XmlAttribute]
    public string Name { get; set; }        
}

public class MainPage : PageBase
{

}

public class SubPage : PageBase
{

}

And here is the sample code I use to deserialize:

var xml = "<Job Name=\"test\"><Pages><MainPage Name=\"page1\"></MainPage></Pages></Job>";
MemoryStream str = new MemoryStream();
StreamWriter writer = new StreamWriter(str);
writer.Write(xml);
writer.Flush();
str.Position = 0;

var serializer = new XmlSerializer(typeof(Job));
var job = (Job)serializer.Deserialize(str);

However, I get the below error - despite including my XmlInclude's on the PageBase type. What am I doing wrong? DotNetFiddle here: https://dotnetfiddle.net/UucVmX

Run-time exception (line 18): There is an error in XML document (1, 19).

Stack Trace:

[System.InvalidOperationException: The specified type is abstract: name='PageBase', namespace='', at .] at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read4_PageBase(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read5_Job(Boolean isNullable, Boolean checkType) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read6_Job()

[System.InvalidOperationException: There is an error in XML document (1, 19).] at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at Program.Main() :line 18

Chris
  • 7,415
  • 21
  • 98
  • 190
  • Does this answer your question? [XML Serialization and Inherited Types](https://stackoverflow.com/questions/20084/xml-serialization-and-inherited-types) This [thread](https://stackoverflow.com/questions/6737666/xml-serialization-problem-deserializing-an-abstract-property) will also be helpful – Pavel Anikhouski Feb 28 '20 at 09:03
  • Unfortunately not, as I already have XmlInclude's but they aren't working – Chris Feb 28 '20 at 09:16
  • You should implement `IXmlSerializable` for the abstract type, like it's explained in mentioned threads – Pavel Anikhouski Feb 28 '20 at 09:19
  • Isn't the point of XmlInclude to make this scenario 'just work' though, without having to implement this interface? – Chris Feb 28 '20 at 09:23
  • Create some test data in your classes and then serialize to see the xml output and what you code produces. The include requires type attribute. – jdweng Feb 28 '20 at 10:08

1 Answers1

0

Change your XML to:

<Job Name="test">
    <Pages>
        <PageBase xsi:type="MainPage" Name="page1"/>
    </Pages>
</Job>

Try to serialize your object first and check the XML it produces. You should see that the XML-Element will be PageBase and xsi:type="MainPage".

FlaGon
  • 104
  • 6