views:

162

answers:

3

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 approach 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"&gt;
<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?

+5  A: 

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.

Andrew Rollings
Thanks Andrew. That did the trick.
TooFat
A: 

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.

TJMonk15
A: 

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.

John Saunders