Robert Deml
Robert Deml

Reputation: 12532

How to XML Serialize a 'Type'

How do I serialize a 'Type'?

I want to serialize to XML an object that has a property that is a type of an object. The idea is that when it is deserialized I can create an object of that type.

public class NewObject
{
}

[XmlRoot]
public class XmlData
{
    private Type t;

    public Type T
    {
        get { return t; }
        set { t = value; }
    }
}
    static void Main(string[] args)
    {
        XmlData data = new XmlData();
        data.T = typeof(NewObject);
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(XmlData));
            try
            {
                using (FileStream fs = new FileStream("test.xml", FileMode.Create))
                {
                    serializer.Serialize(fs, data);
                }
            }
            catch (Exception ex)
            {

            }
        }
        catch (Exception ex)
        {

        }
    }

I get this exception: "The type ConsoleApplication1.NewObject was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."

Where do I put the [XmlInclude]? Is this even possible?

Upvotes: 12

Views: 24664

Answers (6)

M. Jahedbozorgan
M. Jahedbozorgan

Reputation: 7054

XML serialization serializes only the public fields and property values of an object into an XML stream. XML serialization does not include type information. For example, if you have a Book object that exists in the Library namespace, there is no guarantee that it will be deserialized into an object of the same type.

Source: Details of XML serialization | Microsoft Docs

Upvotes: 3

TheSean
TheSean

Reputation: 4566

Type class cannot be serialized because System.RuntimeType is not accessible to our code, it is an internal CLR type. You may work around this by using the type's name instead, like this:

public class c 
{       
    [XmlIgnore]
    private Type t;
    [XmlIgnore]
    public Type T {
        get { return t; }
        set { 
                t = value;
                tName = value.AssemblyQualifiedName;
            }
    }

    public string tName{
        get { return t.AssemblyQualifiedName; }
        set { t = Type.GetType(value);}
    }
}

Upvotes: 20

Mikael
Mikael

Reputation: 11

Ugly but it works. Make a Class which includes the object type and the serialized string.

ex

Class dummie
{
    Type objType;
    string xml;
}

Upvotes: 1

Robert Wagner
Robert Wagner

Reputation: 17793

The problem is that the type of XmlData.T is actually "System.RuntimeType" (a subclass of Type), which unfortunately is not public. This means there is no way of telling the serialise what types to expect. I suggest only serializing the name of the type, or fully qualified name as Jay Bazuzi suggests.

Upvotes: 1

Robert Deml
Robert Deml

Reputation: 12532

I ended up converting the Type name to a string to save it to XML.

When deserializing, I load all the DLLs and save the name of the type and type in a dictionary. When I load the XML with the Type Name, I can look up the name in the dictionary key and know the type based on the dictionary value.

Upvotes: 3

Filip Frącz
Filip Frącz

Reputation: 5947

You could potentially implement the IXmlSerializable interface and use Type.FullName (you may also need Type.AssemblyQualifiedName) for serialization and the Assembly.GetType(string) for deserialization of your type element.

Upvotes: 3

Related Questions