views:

223

answers:

2

Hi everybody, please help. I have this code, it's my class to serialize\deserialize application settings.

    public static MyConfigClass myConfigClass = new MyConfigClass(); 
    private static String myConfigFileName = AppDomain.CurrentDomain.BaseDirectory + "\\ApplicationConfig.xml";


    [XmlRoot("EvaStartupData")]
    [Serializable] 
    public class MyConfigClass
    {
        public string ServerName { get; set; }
        public string Database { get; set; }
        public string UserName { get; set; }
        public string UserLogin { get; set; }


        public static void MyConfigLoad()
        {
            FileInfo fi = new FileInfo(myConfigFileName);
            if (fi.Exists)
            {
                XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
                StreamReader myXmlReader = new StreamReader(myConfigFileName);
                try
                {

                    myConfigClass = (MyConfigClass)mySerializer.Deserialize(myXmlReader);
                    myXmlReader.Close();
                }
                catch (Exception e)
                {
                    MessageBox.Show("Ошибка сериализации MyConfigLoad\n" + e.Message);
                }

                finally
                {
                    myXmlReader.Dispose();
                }
            }
        }


        public static void MyConfigSave()
        {
            XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
            StreamWriter myXmlWriter = new StreamWriter(myConfigFileName);
            try
            {
                mySerializer.Serialize(myXmlWriter, myConfigClass);
            }
            catch (Exception e)
            {
                MessageBox.Show("Ошибка сериализации MyConfigSave\n" + e.Message);
            }

            finally
            {
                myXmlWriter.Dispose();
            }
        }

    }

Serialization give's me simple xml-structure:

<ServerName>navuhodonoser</ServerName>
<Database>matrix</Database>
<UserName>Mr.Smith</UserName>
<UserLogin>neo</UserLogin>

How must i modify my class to get this xml structure ?:

<Connection ServerName="navuhodonoser" Database="matrix" ....>
+7  A: 

By default the XmlSerializer will serialize all public properties as elements; to override that you'll need to tag each property with [XmlAttribute] (from System.Xml.Serialization namespace) which will give you your desired output.

For example:

[XmlAttribute]
public string ServerName { get; set; }

[XmlAttribute]
public string Database { get; set; }

[XmlElement]
public string UserName { get; set; }

// Note: no attribute
public string UserLogin { get; set; }

will produce something like:

<xml ServerName="Value" Database="Value">
    <UserName>Value</UserName>  <!-- Note that UserName was tagged with XmlElement, which matches the default behavior -->
    <UserLogin>Value</UserLogin>
</xml>
STW
+2  A: 

I have a couple of suggestions. Try code more like this:

    public static void MyConfigLoad()
    {
        if (!File.Exists(myConfigFileName))
        {
            return;
        }

        XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
        using (StreamReader myXmlReader = new StreamReader(myConfigFileName))
        {
            try
            {
                myConfigClass = (MyConfigClass)mySerializer.Deserialize(myXmlReader);
            }
            catch (Exception e)
            {
                MessageBox.Show("Ошибка сериализации MyConfigLoad\n" + e.ToString());
            }
        }
    }

    public static void MyConfigSave()
    {
        XmlSerializer mySerializer = new XmlSerializer(myConfigClass.GetType());
        using (StreamWriter myXmlWriter = new StreamWriter(myConfigFileName))
        {
            try
            {
                mySerializer.Serialize(myXmlWriter, myConfigClass);
            }
            catch (Exception e)
            {
                MessageBox.Show("Ошибка сериализации MyConfigSave\n" + e.ToString());
            }
        }
    }

You should put the StreamReader and StreamWriter in using blocks so that they will be disposed even if an exception occurs. Also, I suggest you always display e.ToString() instead of just e.Message, as it will display the entire exception, including any inner exceptions.

Also, File.Exists works just like FileInfo.Exists, but doesn't require you to create an instance before using it.

One final note is that you should look into using the Settings feature instead of creating your own configuration classes. That allows you to easily create type-safe settings that can be used throughout your application, and which can be per-user or per-application.

John Saunders
+1 for all solid suggestions
STW
John Thank you for your suggestions !
Alex