[Mono-list] Problem with XML Serialization under mono

Christian Hobelsberger hobi1972 at gmail.com
Wed Aug 20 07:11:27 EDT 2008


Hi,

i have some code which works well under microsoft .net, but completly fails
under mono ... maybe someone can give me a hint how to fix - or at
workaround!?

The purpose of the code is to have a class, which can store a item of a
instance of an unknown type - and produce a xml serialization from it.
Usually when you try to serialize a class with an unknown instance, you'll
get a "class ... not expected" exception from the serializer - as the can
only serialize classes, which he was aware of while he was created.
The "trick" is to use a wrapper class, which can handle the unknown classes
and tell the serializer to  replace the real object with that wrapper in the
serialization process.
(the concept was found here
http://www.codeproject.com/KB/XML/xmlserializerforunknown.aspx?fid=120909&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=1798222#xx1798222xx
)

With .net the below code works without problems and gives the
correct/expected result ... but using mono (1.9.1 under windows/linux)
results in
Unhandled Exception: System.InvalidOperationException: There was an error
generating the XML document. ---> System.InvalidCastException: Cannot cast
from source type to destination type.
  at
System.Xml.Serialization.XmlSerializationWriterInterpreter.WriteMemberElement
(System.Xml.Serialization.XmlTypeMapElementInfo elem, System.Object
memberValue) [0x00000]
  at
System.Xml.Serialization.XmlSerializationWriterInterpreter.WriteElementMembers
(System.Xml.Serialization.ClassMap map, System.Object ob, Boolean
isValueList) [0x00000]
...

Here is the code:

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace SerialMonoBug
{
    class Program
    {
        static void Main(string[] args)
        {
            String s = "";

            TestClass a = new TestClass();
            DerivedClass_1 d1 = new DerivedClass_1();

            a.Item = d1;
            s = a.ToString_2();

System.Console.WriteLine(String.Format("{0}\n------------------------\n",
s));
        }
    }

    public class UnknownItemSerializer : IXmlSerializable
    {
        public BaseClass Item;

        public UnknownItemSerializer() { }
        public UnknownItemSerializer(BaseClass item) { this.Item = item; }

        public static implicit operator UnknownItemSerializer(BaseClass p) {
            System.Console.WriteLine("converting to UnknownItemSerialzer");
            return p == null ? null : new UnknownItemSerializer(p);
        }

        public static implicit operator BaseClass(UnknownItemSerializer p) {
            System.Console.WriteLine("converting to BaseClass");
            return p == null ? null : p.Item;
        }

        public XmlSchema GetSchema() { return null; }// not implemented
        public void ReadXml(XmlReader reader) { return; } // not implemented

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteAttributeString("type", String.Format("{0}, {1}",
Item.GetType().ToString(), Item.GetType().Assembly.ToString()));
            new XmlSerializer(Item.GetType()).Serialize(writer, Item);
        }
    }

    public class TestClass
    {
        public BaseClass Item;

        public string ToString_2() {
            string result = "";

            using (System.IO.MemoryStream stream = new
System.IO.MemoryStream())
            using (System.IO.StreamReader sr = new
System.IO.StreamReader(stream))
            using (XmlTextWriter writer = new XmlTextWriter(stream,
System.Text.Encoding.UTF8))
            {
                XmlAttributes attrs = new XmlAttributes();
                XmlElementAttribute attr = new XmlElementAttribute();
                attr.ElementName = "UnknownItemSerializer";
                attr.Type = typeof(UnknownItemSerializer);
                attrs.XmlElements.Add(attr);
                XmlAttributeOverrides attrOverrides = new
XmlAttributeOverrides();
                attrOverrides.Add(typeof(TestClass), "Item", attrs);

                XmlSerializer serializer = new XmlSerializer(this.GetType(),
attrOverrides);

                serializer.Serialize(writer, this);

                stream.Position = 0;
                result = sr.ReadToEnd();
            }

            return result;
        }
    }

    public class BaseClass {
    }

    public class DerivedClass_1 : BaseClass {
        public int value = 10;
    }

    public class DerivedClass_2 : BaseClass {
        public string strValue = "testString";
    }
}


Anyone an idea what's going wrong here?

thanks
CHH
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-list/attachments/20080820/c6326c2c/attachment-0001.html 


More information about the Mono-list mailing list