1

I've encountered a situation where XmlSerializer can't deserialize back its own output. The data structure basically consists of a root class Project containing a ProjectItems property (of a custom collection type) holding individual items. Some items may contain nested items recursively.

public class Project
{
    [XmlElement("ProjectItem")]
    public ProjectItemCollection { get; set; }
}

The XML produced by XmlSerializer looks like this:

<Project>
    <ProjectItem xsi:type="ContentOrganizationPlanProjectItem">
        <ProjectItem xsi:type="FolderProjectItem">
        </ProjectItem>
        <ProjectItem xsi:type="FolderProjectItem">
        </ProjectItem>
    </ProjectItem>
</Project>

Note: All unimportant stuff is removed from the code examples.

Originally I had the ProjectItem class decorated with XmlInclude attributes to cover all the various types of items that may occur in the data structure. That worked fine.

However, as it needs to be extensible from independent assemblies, I had to replace these attributes with a dynamically constructed array of all possible types passed to XmlSerializer constructor's extraTypes parameter using this SO answer.

Again—serialization works just fine. The problem is that when I try to deserialize it back, XmlSerializer throws an InvalidCastException saying:

Unable to cast object of type 'System.Xml.XmlNode[]' to type 'Whatever.ProjectItem'.

How do I make XmlSerializer deserialize its own output it this case?


Side note: I can't withstand dancing the XmlSerializer bullets anymore—Trinity, help!

Community
  • 1
  • 1
Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90

2 Answers2

1

The problem was trivial indeed:

public class Project
{
    [XmlElement("ProjectItem", typeof(ProjectItem))]
    public ProjectItemCollection { get; set; }
}

Specifying the typeof(ProjectItem) in XmlElement is useless for serialization. However, it's crucial for deserialization.

Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
0

If you continue to struggle with the XmlSerializer, you might find the XAML serialization (which is moved out of WPF and now is completly available in it's own System.Xaml.dll) helpful. It is really powerful and extendable.

J. Tihon
  • 4,439
  • 24
  • 19
  • 1
    Thanks for the tip. I'll definitely check it out. Actually I was—again—pretty damn close to writing a `XmlSerializer` replacement. It just plain sucks. – Ondrej Tucny Feb 27 '11 at 21:07