Xmlserializer won't deserialize Vector2

Have finally rebuilt my game with the latest versions. Am using Monogame 3.6 for Visual Studio 2017.
Now my xml deserializing no longer works. It has been working for years with previous versions. Apparently it cannot deserialize Vector2.

Here is my C# code:
///


/// Game Initialization Class
///

[Serializable()]
public class GameInit
{
public string gamename
{ get; set; }

    public string initfolder
    { get; set; }

    public string initfilename
    { get; set; }

    public Vector2 viewportresolution
    { get; set; }

    public Vector2 virtualresolution
    { get; set; }

    /// <summary>
    /// Constructs Initialization Object
    /// </summary>
    public GameInit()
    {

    }
}

Here is my xml

<?xml version="1.0" encoding="utf-8"?>


ParaformGame
GameScreens
ParaformScreenMainMenu.xml

800
480


800
550

gameInit.virtualresolution contains error CS0103: The name ‘DebugDisplayString’ does not exist in the current context

What has changed from previous versions of monogame?

Yeah, I would just advise using ints for width and height of each and then just create the Vectors from those.

Point might be serializeable? Not sure about that.

Thanks spool for your reply.
For several years, I have used xmlserializer to serialize and deserialize vector2, point and colour as well as arrays and classes. But under monogame 3.7 it no longer works. What version of monogame supports xmlserializer?

I just ran the following test with MonoGame 3.6…

            Vector2 data = new Vector2(0.123f, 456.789f);
            Debug.WriteLine("ToString: " + data.ToString());
            XmlSerializer xs = new XmlSerializer(typeof(Vector2));
            StringBuilder sb = new StringBuilder();
            using (StringWriter sw = new StringWriter(sb))
                xs.Serialize(sw, data);

            string dataString = sb.ToString();
            Debug.WriteLine("Serialized: " + dataString);

            Vector2 restoredData = Vector2.Zero;
            using (StringReader sr = new StringReader(dataString))
                restoredData = (Vector2)xs.Deserialize(sr);

            Debug.WriteLine("Restored: " + restoredData.ToString());

I got the following output:

ToString: {X:0.123 Y:456.789}
Serialized: <?xml version="1.0" encoding="utf-16"?>
<Vector2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <X>0.123</X>
  <Y>456.789</Y>
</Vector2>
Restored: {X:0.123 Y:456.789}

It looks like your XML file is missing some data? If this used to work before, that’s quite strange… and I don’t really have an answer for you. I might suggest that you check out Json.Net though. They’ve got a package you can download via NuGet and I’ve found it’s a little more robust at serializing and deserializing data.

*Edit: Ahhhh, your XML is probably just fine but the quote thing strips away the angle brackets when you quote it. Anyway, maybe compare your code to mine? Maybe there’s something that’s no longer supported.

Could it be the CultureInfo issue? I had something like that in the Mercury Particle Engine, years ago. It stores floats in the language and format of the current culture.
In german we write “1.000,50” but in englisch “1,000.50”

Thank you so much for the reply.

This test works because you serialized and then deserialized so xmlserializer knew what a vector2 looked like.

I am not sure how xmlserializer keeps track of extra types. I think that when I originally built my xml files I specified the extra types. By the way I have dozens of xml files. I found a post that said that you could not serialize and deserialize from your project. You have to create a separate project with the classes in it. Then it will work. This apparently applies to monogame. I will try that tomorrow.

Thanks.

Thank you. This may be the case. But since I’ve been working with these xml files for over five years without a problem it must have something to do with how xmlserializer works under monogame.

I’m not so sure… I updated my test to the following:

    [Serializable()]
    public class Data
    {
        public string Text { get; set; }
        public Vector2 Location { get; set; }

        public override string ToString()
        {
            return string.Format("{{Text={0}, Location={1}}}", this.Text, this.Location.ToString());
        }
    }
            {
                Debug.WriteLine("Test 1");
                Debug.WriteLine("======");
                Data data = new Data() { Text = "Blah", Location = new Vector2(0.123f, 456.789f) };
                Debug.WriteLine("ToString: " + data.ToString());
                XmlSerializer xs = new XmlSerializer(typeof(Data));
                StringBuilder sb = new StringBuilder();
                using (StringWriter sw = new StringWriter(sb))
                    xs.Serialize(sw, data);

                string dataString = sb.ToString();
                Debug.WriteLine("Serialized: " + dataString);

                Data restoredData = null;
                using (StringReader sr = new StringReader(dataString))
                    restoredData = (Data)xs.Deserialize(sr);

                Debug.WriteLine("Restored: " + restoredData.ToString());
            }

            {
                Debug.WriteLine("Test 2");
                Debug.WriteLine("======");
                string dataString =
                      @"<Data xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">"
                    + @"  <Text>Blah</Text>"
                    + @"  <Location>"
                    + @"    <X>0.123</X>"
                    + @"    <Y>456.789</Y>"
                    + @"  </Location>"
                    + @"</Data>";

                XmlSerializer xs = new XmlSerializer(typeof(Data));
                Data restoredData = null;
                using (StringReader sr = new StringReader(dataString))
                    restoredData = (Data)xs.Deserialize(sr);

                Debug.WriteLine("Restored: " + restoredData.ToString());
            }
Test 1
======
ToString: {Text=Blah, Location={X:0.123 Y:456.789}}
Serialized: <?xml version="1.0" encoding="utf-16"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Text>Blah</Text>
  <Location>
    <X>0.123</X>
    <Y>456.789</Y>
  </Location>
</Data>
Restored: {Text=Blah, Location={X:0.123 Y:456.789}}
Test 2
======
Restored: {Text=Blah, Location={X:0.123 Y:456.789}}

I even commented out Test 1 and tried with just reading in a string, which should be the very same as what you have, and it still worked.

Can you please edit your post and remove your XML file, then repaste it in. Once you’ve done this, select it and click the “Preformatted text” button on the formatting bar? It looks like when you quote something it strips out some of the formatting and codes, which makes it hard to read :smiley: Sorry if there’s something I’m missing… we’ll get to the bottom of this!

Also, what I find odd is that the error says the name “DebugDisplayString” doesn’t exist… I don’t see that anywhere in your code. Is that error from an exception, or just something that dumps to the log?

Thanks for working on this. I will try and post my xml. In the meantime what do you think of this post:

Here is my xml unedited.

<?xml version="1.0" encoding="utf-8"?>
<GameInit   xsi:type="GameInit"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <gamename>ParaformGame</gamename>
  <initfolder>GameScreens</initfolder>
  <initfilename>ParaformScreenMainMenu.xml</initfilename>
  <viewportresolution>
    <X>800</X>
    <Y>480</Y>
  </viewportresolution>
  <virtualresolution>
    <X>800</X>
    <Y>550</Y>
  </virtualresolution>
  <XLinkInit xsi:type="XLinkInit">
    <type>XLink</type>
    <name>rootLink</name>
    <enabled>true</enabled>
    <visible>false</visible>
    <screenlinkname>MainScreenParaformScreenMainMenu</screenlinkname>
    <gamemode>0</gamemode>
    <mode>0</mode>
    <gamescreenname>Colorgon.MainScreen</gamescreenname>
    <initfilepresent>true</initfilepresent>
    <initfilename>GameScreens/ParaformScreenMainMenu.xml</initfilename>
    <state>0</state>
    <eventname></eventname>
  </XLinkInit>
</GameInit>

Here is my class:
///


/// Game Initialization Class
///

[Serializable()]
public class GameInit
{
public string gamename
{ get; set; }

public string initfolder
{ get; set; }

public string initfilename
{ get; set; }

public Vector2 viewportresolution
{ get; set; }

public Vector2 virtualresolution
{ get; set; }

public XLinkInit xlink
{ get; set; }

/// <summary>
/// Constructs Initialization Object
/// </summary>
public GameInit()
{

}

}

Xmlserializer puts the following string in the field virtualResolution = error CS0103: The name ‘DebugDisplayString’ does not exist in the current context.
This occurs in all the extra type fields Vector2, Vector3 and Color.

I’m using this for my Vector2 serialization:

 [Serializable]
    public class Vector2Surrogate
    {
        [XmlElement(ElementName = "X")]  
        public float X { get; set; }
        [XmlElement(ElementName = "Y")]  
        public float Y { get; set; }

        public static implicit operator Vector2Surrogate(Vector2 vector)
        {
            return new Vector2Surrogate(vector.X, vector.Y);
        }

        public static implicit operator Vector2(Vector2Surrogate surrogate)
        {
            return new Vector2(surrogate.X, surrogate.Y);
        }

        public Vector2Surrogate(float x, float y)
        {
            X = x;
            Y = y;
        }

    }

And then:

RuntimeTypeModel.Default.Add(typeof(Vector2), false).SetSurrogate(typeof(Vector2Surrogate));

Thanks for the reply.
I have no trouble importing Vector2. This all worked previously to rebuilding my project in the latest versions.
So, the question is what am I doing different now?

Well it appears that it is not xmlserializer at all.

I created a variable
public Vector2 virtualRes;
assigned
virtualRes = new Vector2(800, 400);
ran it
variable contains
virtualRes = error CS0103: The name ‘DebugDisplayString’ does not exist in the current context

How can this be?

Am I referencing a Monogame assembly that does not support Vector2?
`

I hadn’t had a chance to come back to this over the weekend, but it looks like you’ve made a pretty valuable discovery!

That’s very strange… and again, I’m really curious as to what DebugDisplayString is. I can recommend a couple of courses of action…

  1. Try this in a fresh MonoGame project. If the issue still occurs, it’s a problem with MonoGame. If it doesn’t, it’s a problem with your own code project.
  2. Do a search of DebugDisplayString, try to find out where that comes from. I think there’s a way to search in the ObjectBrowser so that you can look for stuff in your referenced assemblies? Worst case, you can always do a text search on the XML documents that come with your referenced assemblies.
  3. Start removing assemblies and commenting out code until your simple Vector2 check works. This is kind of a huge pain and probably a last resort.

Start with 1 though… if it’s a problem with MonoGame, at least on your machine, not much point in doing the other two :slight_smile:

Thanks, lots of good suggestions.
Not sure what is going on. I now can’t even get into my code. I keep getting this error on my game object:
System.NullReferenceException: ‘Object reference not set to an instance of an object.’
When I try to set a reference to a monogame assembly visual studio keeps changing the reference to something else.

A while back a friend linked me to this. I think you may need this right now…
https://www.reddit.com/r/Otters/

I find, now and then, we software developers just need to look at a few cute animals now and again. The alternative? A rage meltdown the likes of which the world has never seen! :stuck_out_tongue:

That’s rough! I swear, some days you try to fix one thing and it just chains into many more things. You might try hand editing the csproj file and setting the references up manually yourself. Not ideal but it might get Visual Studio stop doing whatever it’s doing :frowning:

Thanks I needed that.
I started with programming in 1968 with PL1 on an IBM 360 model 40.

I have decided to rebuild everything from scratch. It will take me some time.
Thanks again.

1 Like

Now I am back to the Xmlserializer. It now deserializes Vector2 properly but wont deserialize my derived class.
How do I tell it that this is a derived class?

    /// <summary>
    /// Game Initialization Class
    /// </summary>
    [Serializable()]
    [XmlInclude(typeof(GameInit))]
    [XmlInclude(typeof(XLinkInit))]
    [XmlInclude(typeof(ControlInit))]
    public class GameInit
    {
        public string gamename
        { get; set; }

        public string initfolder
        { get; set; }

        public string initfilename
        { get; set; }

        public Vector2 viewportresolution
        { get; set; }

        public Vector2 virtualresolution
        { get; set; }

        public XLinkInit xlink
        { get; set; }

        /// <summary>
        /// Constructs Initialization Object
        /// </summary>
        public GameInit()
        {

        }
    }

[XmlInclude(typeof(ControlInit))]
[XmlInclude(typeof(XLinkInit))]
public class XLinkInit : ControlInit
{

///


/// XLink
///

public string screenlinkname
{ get; set; }

public int gamemode
{ get; set; }

public int mode
{ get; set; }

public string gamescreenname
{ get; set; }

public bool initfilepresent
{ get; set; }

public string initfilename
{ get; set; }

public int state
{ get; set; }

public string eventname
{ get; set; }

/// <summary>
/// Constructs a new Link
/// </summary>
public XLinkInit()
{

    [XmlInclude(typeof(ControlInit))]
    [XmlInclude(typeof(XLinkInit))]
    public class ControlInit
    {
        public string name
        { get; set; }

        public string type
        { get; set; }

        public Vector2 location
        { get; set; }

        public Vector2 size
        { get; set; }

        public Color backcolor
        { get; set; }

        public Color forecolor
        { get; set; }

        public bool enabled
        { get; set; }

        public bool visible
        { get; set; }

        public string text
        { get; set; }

        public string svalue
        { get; set; }

        public string fontname
        { get; set; }

        public bool dragable
        { get; set; }

        public bool canhavefocus
        { get; set; }

        /// <summary>
        /// Constructs a Control
        /// </summary>
        public ControlInit()
        {

        }

    }


}

        gameInit = XmlUtility.DeserializeObject<GameInit>(xmlPath + @"\" + parameter);