【问题标题】:C# XML Error: System.InvalidOperationExceptionC# XML 错误:System.InvalidOperationException
【发布时间】:2015-08-10 12:55:57
【问题描述】:

序列化此 XML 时出现奇怪的错误:

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

错误:

“'System.InvalidOperationException' 类型的第一次机会异常 发生在 System.Xml.dll 附加信息: 反思 EasyRPG.SplashScreen 发生的错误类型。如果有一个处理程序 这个异常,程序可以安全地继续。”

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 新手,我不知道什么是重要的,什么不是

【问题讨论】:

  • 您两次发布了SplashScreen 课程。可以发GameScreenImage 吗?
  • 哦,谢谢,没注意到
  • 我怀疑您会通过调查您的异常的InnerException 找到更多信息。我猜Image 中的一个或多个公共字段不受支持。

标签: c# xml serialization xna monogame


【解决方案1】:

此代码将起作用。

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;}
    }

}
​

【讨论】:

  • 很难说清楚。我相信这是 XML 序列化类的嵌套。我很困惑你说错误发生在序列化期间(类到 XML),而这样的错误通常发生在反序列化(XML 到类)中并且你发布了 XML。如果序列化失败,如何获取 XML?
  • 问题在于反映类型,很可能是因为Image 类中的一种或多种字段类型。这只是通过删除除 Path 之外的所有内容来作弊。
  • 我没有猜到错误的位置。代码中有很多地方可能会发生异常。我不是想作弊。让 Op 找出问题所在。我只是提供了一段我知道可以工作的代码。
【解决方案2】:

这是一个不会对您的代码进行太多更改的答案,因为我从 youtube 教程中认出了它,并且更改太多可能会使您难以按照教程进行操作。如果 Xml 文件中不包含公共变量,则需要使用 [XmlIgnore]。因此,您可以更改您的 XMl 文件或将 [XmlIgnore] 添加到 image.cs 因为这是来自我推荐的教程,如果/当您想将变量添加到 xml 时,请记住删除添加的 [XmlIgnore]文件。

最佳选择:编辑 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 文件中的所有公共值。 (注意我遗漏了一些变量,但你明白了)

<?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;”和“公共 SpriteBatch SpriteBatch;”在 Image.cs 中,它们应该在 ScreenManager.cs 中

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2022-02-27
    • 1970-01-01
    相关资源
    最近更新 更多