C#XML错误:System.InvalidOperationException

时间:2015-08-10 12:55:57

标签: c# xml serialization xna monogame

我在序列化这个XML时遇到了奇怪的错误:

<?xml version="1.0" encoding="utf-8" ?>
<SplashScreen>
  <Image>
    <Path>Content/splash</Path>
  </Image>
</SplashScreen>

错误:

  

&#34;类型&#39; System.InvalidOperationException&#39;的第一次机会异常   发生在System.Xml.dll中的附加信息:反映在   EasyRPG.SplashScreen发生错误的类型。如果有一个处理程序   这个例外,程序可以安全地继续。&#34;

XMLManager类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace EasyRPG.Managers {
public class XmlManager<T> {

    public Type Type;

    public T Load (String path) {
        T instance;
        using (TextReader reader = new StreamReader(path)){
            XmlSerializer xml = new XmlSerializer(Type);
            instance = (T)xml.Deserialize(reader);
        }
        return instance;
    }

    public void Save (string path, object obj) {
        using (TextWriter writer = new StreamWriter(path)) {
            XmlSerializer xml = new XmlSerializer(Type);
            xml.Serialize(writer, obj);
        }
    }
}
}

我迷失了,我尝试了所有我知道的事情(尽管不是很多)但仍然没有。

图像类,如果需要:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using EasyRPG;

namespace TEAM_TheCity.Source {
public class Image {

    public float Alpha;
    public string Path;
    public string Text, FontName;
    public Vector2 Position;

    public Vector2 Scale;
    public Rectangle SourceRect;

    public SpriteFont font;
    public GraphicsDevice GraphcsDevice;
    public Texture2D Texture;
    Vector2 origin;

    ContentManager content;
    RenderTarget2D renderTarget;
    public SpriteBatch SpriteBatch;

    public Image () {
        Path = Text = String.Empty;
        FontName = "Orbitron";
        Position = Vector2.Zero;
        Scale = Vector2.One;
        Alpha = 1.0F;
        SourceRect = Rectangle.Empty;
    }

    public void LoadContent(){
        content = new ContentManager(ScreenManager.Manager.Content.ServiceProvider, "Content");

        if(Path != String.Empty) Texture = content.Load<Texture2D>(Path);

        font = content.Load<SpriteFont>(FontName);

        Vector2 dimensions = Vector2.Zero;

        if(Texture != null)
            dimensions.X += Texture.Width;
        dimensions.X += font.MeasureString(Text).X;

        if(Texture != null)
            dimensions.Y = Math.Max(Texture.Height, font.MeasureString(Text).Y);
        else
            dimensions.Y = font.MeasureString(Text).Y;

        if(SourceRect == Rectangle.Empty)
            SourceRect = new Rectangle(0,0, (int)dimensions.X, (int)dimensions.Y);

        renderTarget = new RenderTarget2D(ScreenManager.Manager.GraphicsDevice,(int) dimensions.X, (int)dimensions.Y);
        ScreenManager.Manager.GraphicsDevice.SetRenderTarget(renderTarget);
        ScreenManager.Manager.GraphicsDevice.Clear(Color.Transparent);
        ScreenManager.Manager.SpriteBatch.Begin();
        if (Texture != null)
            ScreenManager.Manager.SpriteBatch.Draw(Texture, Vector2.Zero, Color.White);
        ScreenManager.Manager.SpriteBatch.DrawString(font, Text, Vector2.Zero, Color.White);
        ScreenManager.Manager.SpriteBatch.End();

        Texture = renderTarget;

        ScreenManager.Manager.GraphicsDevice.SetRenderTarget(null);
    }

    public void UnloadContent(){

    }

    public void Update(GameTime gameTime){

    }

    public void Draw(SpriteBatch SpriteBatch) {
        origin = new Vector2(SourceRect.Width / 2, SourceRect.Height /     2);
        SpriteBatch.Draw(Texture, Position + origin, SourceRect,     Color.White, 0.0f, origin, Scale, SpriteEffects.None, 0.0f);
    }

}
}

和SplashScreen类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using TEAM_TheCity.Source;

namespace EasyRPG {
public class SplashScreen : GameScreen{

    public Image Image;

    public SplashScreen () {

    }

    public override void LoadContent () {
        base.LoadContent();
        Image.LoadContent();
    }

    public override void UnloadContent () {
        base.LoadContent();
        Image.UnloadContent();
    }

    public override void Update (GameTime gameTime) {
        base.Update(gameTime);
        Image.Update(gameTime);
    }

    public override void Draw (SpriteBatch spriteBatch) {
        base.Draw(spriteBatch);
        Image.Draw(spriteBatch);
    }
}
}

GameScreen类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace EasyRPG {
public class GameScreen {

    protected ContentManager content;
    [XmlIgnore]
    public Type Type;

    public GameScreen () {
        Type = this.GetType();
    }

    public virtual void LoadContent () {
        content = new ContentManager(ScreenManager.Manager.Content.ServiceProvider, "Content");
    }

    public virtual void UnloadContent () {
        content.Unload();
    }

    public virtual void Update (GameTime gameTime) {}

    public virtual void Draw (SpriteBatch spriteBatch) {}
}
}

P.S。:对于那么多代码感到抱歉,但我是XML的新手,我不知道什么是重要的,什么不是

2 个答案:

答案 0 :(得分:0)

此代码可以使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            SplashScreen splashScreen = new SplashScreen()
            {
                image = new Image()
                {
                    Path = "Content/splash"
                }
            };
            XmlSerializer serializer = new XmlSerializer(typeof(SplashScreen));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, splashScreen);
            writer.Flush();
            writer.Close();
            writer.Dispose();


            XmlSerializer xs = new XmlSerializer(typeof(SplashScreen));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            SplashScreen  newSplashScreen = (SplashScreen)xs.Deserialize(reader);

        }
    }
    [XmlRoot("SplashScreen")]
    public class SplashScreen
    {
        [XmlElement("Image")]
        public Image image {get; set; }

    }
    [XmlRoot("Image")]
    public class Image
    {
        [XmlElement("Path")]
        public string Path {get; set;}
    }

}
​

答案 1 :(得分:0)

这是一个不会过多改变你的代码的答案,因为我从youtube教程中认识到它并且过多地改变它可能会让你难以理解教程。如果不在Xml文件中包含公共变量,则需要使用[XmlIgnore]。所以你可以改变你的XMl文件或者将[XmlIgnore]添加到image.cs因为这是我推荐的后期教程,只要记住删除添加的[XmlIgnore] if / when你想把变量添加到xml文件。

最佳选项:编辑Image.cs

[XmlIgnore] public float Alpha;
public string Path;
[XmlIgnore] public string Text, FontName;
[XmlIgnore] public Vector2 Position;

[XmlIgnore] public Vector2 Scale;
[XmlIgnore] public Rectangle SourceRect;

[XmlIgnore] public SpriteFont font;
[XmlIgnore] public GraphicsDevice GraphcsDevice;
[XmlIgnore] public Texture2D Texture;
Vector2 origin;

ContentManager content;
RenderTarget2D renderTarget;
[XmlIgnore] public SpriteBatch SpriteBatch;

其他选项:编辑XML

基本上初始化XML文件中的所有公共值。 (注意我留下了一些vars,你知道了)

<?xml version="1.0" encoding="utf-8" ?>
<SplashScreen>
  <Image>
    <Alpha>0.5</Alpha>
    <Path>Content/splash</Path>
    <Text>Put Text Here</Text>
    <FontName>Fonts/Orbitron</FontName>
    <Scale>
      <X>1.0</X>
      <Y>1.0</Y>
    </Scale>
    <Position>
      <X>0</X>
      <Y>0</Y>
    </Position>
    <SourceRect>Rectangle.Empty</SourceRect>
  </Image>
</SplashScreen>

旁注

我相信你不需要“public GraphicsDevice GraphicsDevice;”和“public SpriteBatch SpriteBatch;”在Image.cs中,它们应该在ScreenManager.cs

另外我认为“公共SpriteFont字体”;不应该公开。