简体   繁体   English

XMLSerializer在序列化类时写入无效的XML(有时候)

[英]XMLSerializer writes invalid XML when serializing a class (Sometimes)

My goal is to be able to share configration settings amongst apps. 我的目标是能够在应用程序之间共享配置设置。 For example I want to be able to use a WinForm app to set and save the settings and have a console app be able to read those settings and run as a scheduled task. 例如,我希望能够使用WinForm应用程序来设置和保存设置,并让控制台应用程序能够读取这些设置并作为计划任务运行。 The approach I tried is to create a SharedSettings class that is referenced by both the Winform app and the Console app. 我尝试的方法是创建一个由Winform应用程序和控制台应用程序引用的SharedSettings类。 In this class there is nothing but public string properties like so. 在这个类中,只有像这样的公共字符串属性。

public class SharedSettings
{
    public string URL { get; set; }
    public string DestUser { get; set; }
    public string RelScript { get; set; }
}

I am using the following to serialize the instance of the SharedSettings class 我使用以下序列来序列化SharedSettings类的实例

SharedSettings settings = new SharedSettings();

settings.RelScript = this.txtRelScript.Text;
settings.URL = this.txtURL.Text;
settings.DestUser = this.txtDestUser.Text;

XmlSerializer dehydrator = new XmlSerializer(settings.GetType());
System.IO.FileStream fs = new FileStream(this.configFilePath, FileMode.OpenOrCreate);
dehydrator.Serialize(fs, settings); 

and this to Deserialize it and populate the fields in the Form 并将其反序列化并填充表单中的字段

SharedSettings settings = new SharedSettings();
XmlSerializer dehydrator = new XmlSerializer(settings.GetType());
System.IO.FileStream fs = new FileStream(this.configFile, FileMode.Open);
settings = (SharedSettings)dehydrator.Deserialize(fs);

this.txtRelScript.Text = settings.RelScript;
this.txtURL.Text = settings.URL;
this.DestUser.Text = settings.DestUser;

Every once in a while maybe one out of every five times I run it the XML file that is created in not valid XML. 每隔一段时间,每五次一次,我就会运行在无效XML中创建的XML文件。 Here is an example 这是一个例子

<?xml version="1.0"?>
<SharedSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ProjectName>test2</ProjectName>
<URL />
<DestUser>test3</DestUser>
<RelScript>D:\Events.dll</ReleaseScript>
</SharedSettings>ttings>

Notice the last line. 注意最后一行。 ttings> What am I doing wrong in Serializing my class? ttings>在序列化我的课程时我做错了什么?

It looks like the previous run through wrote out a longer file. 看起来像以前的运行写了一个更长的文件。 The use of FileMode.OpenOrCreate in your serialization code doesn't truncate the previous file, so it is partly overwritten. 在序列化代码中使用FileMode.OpenOrCreate不会截断以前的文件,因此会被部分覆盖。

Use FileMode.Create instead. 请改用FileMode.Create

See the documentation here . 请参阅此处的文档。

In your code to Serialize your settings, are you calling fs.Flush() or fs.Close()? 在序列化设置的代码中,您是在调用fs.Flush()还是fs.Close()?

It looks like the file isnt being "closed" properly. 看起来文件没有正确“关闭”。

For instance, it looks like the file you are opening and writing to had more data in it the you wrote this time. 例如,看起来你正在打开和写入的文件中包含了你这次写的更多数据。 (Not sure if that makes sense...) And because you didn't close the file properly, the file doesn't end at the right spot. (不确定这是否有意义......)并且因为您没有正确关闭文件,文件不会在正确的位置结束。

Lets see if I can explain that better... 让我们看看我是否可以更好地解释......

First time you write a file, let say you write: 第一次写文件时,请写下:

"Hello World!"

And the second time you write less bytes, and don't close the File properly. 第二次写入较少的字节,并且不要正确关闭文件。 So if you write "Hi Bob." 所以,如果你写“嗨鲍勃”。 you would get: 你会得到:

"Hi Bob.orld!"

If fs.Close() doesn't fix your problem, you can try deleteing the config file each time before you write it. 如果fs.Close()无法解决您的问题,您可以尝试在每次编写之前删除配置文件。

Learn to use using blocks: 学习using块:

    SharedSettings settings = new SharedSettings();

    settings.RelScript = this.txtRelScript.Text;
    settings.URL = this.txtURL.Text;
    settings.DestUser = this.txtDestUser.Text;

    XmlSerializer dehydrator = new XmlSerializer(settings.GetType());
    using (System.IO.FileStream fs = new FileStream(this.configFilePath, FileMode.OpenOrCreate))
    {
        dehydrator.Serialize(fs, settings);
    }

The result of not doing so is that you were not properly flushing the output stream. 不这样做的结果是您没有正确刷新输出流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM