Deserializing an object from XML in C# with derived classes

Viewed 365

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

1 Answers

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".

Related