XMLSerializer writes invalid XML when class is serialized (sometimes)

My goal is to exchange configuration settings between applications. For example, I want to be able to use the WinForm application to install and save settings and have a console application to read these parameters and run it as a scheduled task. The approach I tried is to create the SharedSettings class, which is referenced by both the Winform application and the console application. There is nothing in this class except public string properties.

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

I use the following to serialize an 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 is for deserializing and filling in the form fields

 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; 

From time to time, perhaps every time every five times I run an XML file created in an invalid XML format. 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> 

Pay attention to the last line. rata> What am I doing wrong in serializing my class?

+4
source share
3 answers

It looks like the previous run wrote out a longer file. Using FileMode.OpenOrCreate in serialization code does not truncate the previous file, so it is partially overwritten.

Use FileMode.Create instead.

See the documentation here .

+15
source

In your code, to serialize your settings, do you call fs.Flush () or fs.Close ()?

It looks like the file is not closing properly.

For example, it looks like the file you open and write contains more data that you wrote this time. (Not sure if this makes sense ...) And since you did not close the file properly, the file does not end in the right place.

Let's see if I can explain which is better ...

The first time you write a file, let's say you write:

 "Hello World!" 

And the second time you write fewer bytes and do not close the file properly. Therefore, if you write "Hello Bob." You'll get:

 "Hi Bob.orld!" 

If fs.Close () does not fix your problem, you can try deleting the configuration file every time before writing.

-one
source

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 this does not mean that you did not clean the output stream correctly.

-one
source

All Articles