views:

805

answers:

2

I really like the extension method that TWith2Sugars posted here. I ran into an odd problem though. When I put this into a shared class library and call the serialization function, I get the following error:

The type MyType was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

I looked around a bit and found that the XmlSerializer can only serialize types that it is aware of. I interpret this to mean classes that are in the class library, not the project that I build based off that libary.

Is there a way around this? Can this function be placed into a class library or does it need to be in each project that uses it?

Update:

I figured out what was causing the problem. I had the following code:

object o = new MyClass();
o.Serialize();

This was causing the error. When I changed the code to:

MyClass c = new MyClass();
c.Serialize();

Everything ran fine. So, lesson learned - don't try to (de)serialize generic objects. The thing I liked the most about the link I referenced was that I did not have to put any XML attribute tags on my classes. The extension method just worked.

For purposes of closing out the question, I will award the answer to whoever expands on Marc's answer (including Marc) with a code sample illustrating the use of [XmlInclude].

+1  A: 

Your understanding is wrong. What this error means is basically as follows: XML serializer cannot operate on class hierarchies unless you explicitly tell it what classes are there in the said hierarchy. Just add XmlInclude attribute for the type of each derived class to your base class and you're done.

Anton Gogolev
A: 

You can do this in this source by adding a reference to the second assembly and using [XmlInclude] - but this might quickly get you into a circular mess of projects. You can also specify these options at runtime, into the serializer's constructor:

using System;
using System.Xml.Serialization;
[Serializable] public class Foo { }
[Serializable] public class Bar : Foo {}

static class Program {
    static void Main()
    {
        XmlSerializer ser = new XmlSerializer(typeof(Foo),
            new Type[] { typeof(Bar) });
        ser.Serialize(Console.Out, new Bar());
    }
}

Re the extension method; you could add a params Type[] extraTypes, and pass extraTypes into the XmlSerializer - then you can use it either as you do now, or as .Serialize(typeof(Bar)).

Marc Gravell
The problem I am having is that the failure is occurring when trying to serialize Foo. Passing an extraType of object still gives the same error.
Jason Z