(Solved) XmlSerializer and Rectangles/Vectors/Colors

I have a List<object> which contains various different data types including int, float, bool, Rectangle, Color, Vector2, and Vector3. Previously, in XNA 4.0, I was able to use an XmlSerializer to export all of these data types to (and import them from) an XML document. Now, in MonoGame 3.0, it no longer works with Rectangle, Color, Vector2, or Vector3. This is the error that I get for all of them:

System.InvalidOperationException: ‘There was an error generating the XML document.’
Inner Exception
InvalidOperationExcetion: The type Microsoft.Xna.Framework.Rectangle was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

I have tried putting [XmlInclude(typeof(Rectangle))] right above my class declaration, but this does nothing. Am I doing it wrong? Perhaps this has something to do with the fact that my List is of the generic object type?

That is the exact same error I’m getting right now in XNA 4.0 when trying to use XmlSerializer to write out a List<object> that contains any of our types, such as Color or Vector2.

        var objects = new List<object>();
        objects.Add(1);
        objects.Add(1.0f);
        objects.Add(true);
        objects.Add(Color.White);
        objects.Add(new Vector2(1.0f, 2.0f));
        objects.Add(new Vector3(1.0f, 2.0f, 3.0f));
        objects.Add(new Rectangle(1, 2, 3, 4));
        var xml = new XmlSerializer(objects.GetType());
        using (var stream = new FileStream("objects.xml", FileMode.Create))
        {
            xml.Serialize(stream, objects);
        }

Do you have any extra code in your XNA project for serializing those types using XmlSerializer that you may not have brought across to your MonoGame project?

Hmm. I don’t think so. I’m thinking it is just because the List is of the generic object type, but I’m still not sure. In my XNA project all the data I was exporting was in an actual field, ie:

public class Thingy
{
Color drawColor = Color.Red;
Rectangle initialFrame = new Rectangle(0, 0, 32, 32);

public void Export()
{
     Stream stream = File.Create(@"Stuff.xml");
     XmlSerializer xml = new XmlSerializer(typeof(Thingy));
     xml.Serialize(stream, this);
     stream.Close();
}

}

I can’t test it atm but shouldn’t you pass
Typeof (List< object > ) , objects.get types()
Or , type [] { typeof( , ) , ect }
Also I think a class needs a parameterless constructor to get serialized as well.
You should probably look up the msdn on getting started with serialization or google serializing a list of objects. I forget the rules for structs.

In my Monogame project, this is (more or less) what I have:

[XmlInclude(typeof(Rectangle))]
[XmlInclude(typeof(Color))]
[XmlInclude(typeof(Vector2))]
public static class Settings
{
    private static Dictionary<string, object> Data = new Dictionary<string, object>();
    [Serializable]
    public struct DataItem
    {
        public string Key;
        public object Value;
        public DataItem(string key, object value)
        {
            Key = key;
            Value = value;
        }
    }

    private static void ExportData()
    {
        List<DataItem> temp = new List<DataItem>(Data.Count);
        foreach (string key in Data.Keys)
            temp.Add(new DataItem(key, Data[key]));
        
        Stream stream = File.Create(@"Settings.xml");
        XmlSerializer serializer = new XmlSerializer(typeof(List<DataItem>));
        serializer.Serialize(stream, temp); // this is where the error occurs
        stream.Close();
    }

    public static void Initialize()
    {
       Data.Add("initial frame", new Rectangle(0, 0, 32, 32));
       Data.Add("frame count", 8);
       Data.Add("draw color", Color.Red);
       Data.Add("initial location", new Vector2(100, 200));
       Data.Add("move speed", 12.5f);
       Data.Add("is aggressive", false);

        ExportData();
    }
}

}

So I guess it’s not really a List<object> but a List<DataItem> where DataItem is a struct that contains an object as a field, which can be int, float, bool, Color, Rectangle, Vector2

Well i would make dataitem a class add a public constructor and add the additional array types to the second parameter of the xmlserializers constructor so it knows what’s in the array.
You might need to cast that list to a array or use xmlobjectwriter.
I’m not sure xmlserializer can even serialize a list or arraylist.
Your best bet is to look at examples there are tons if you google it.

D’oh. I didn’t realize there was a second parameter to the XmlSerializer constructor. That did it.

Previously, I did not have to do that to get it to work, but oh well.

Simply changing the declaration to this works (changing DataItem to a class is not necessary):

XmlSerializer serializer = new XmlSerializer(typeof(List<DataItem>), new Type { typeof(Rectangle), typeof(Vector2), typeof(Color)});

Thanks for your help!

Glad you got it to work.

@StaticRich Could you share what the output of your XML was? I’m running into the same issue using serializer.Deserialize