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. The a开发者_C百科pproach I tried is to create a SharedSettings class that is referenced by both the Winform app and the Console app. 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 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. 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?
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.
Use FileMode.Create
instead.
See the documentation here.
In your code to Serialize your settings, are you calling fs.Flush() or 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.
Learn to use using
blocks:
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.
精彩评论