Can ConfigurationManager retain XML comments on Save()? Can ConfigurationManager retain XML comments on Save()? xml xml

Can ConfigurationManager retain XML comments on Save()?


I jumped into Reflector.Net and looked at the decompiled source for this class. The short answer is no, it will not retain the comments. The way Microsoft wrote the class is to generate an XML document from the properties on the configuration class. Since the comments don't show up in the configuration class, they don't make it back into the XML.

And what makes this worse is that Microsoft sealed all of these classes so you can't derive a new class and insert your own implementation. Your only option is to move the comments outside of the AppSettings section or use XmlDocument or XDocument classes to parse the config files instead.

Sorry. This is an edge case that Microsoft just didn't plan for.


Here is a sample function that you could use to save the comments. It allows you to edit one key/value pair at a time. I've also added some stuff to format the file nicely based on the way I commonly use the files (You could easily remove that if you want). I hope this might help someone else in the future.

public static bool setConfigValue(Configuration config, string key, string val, out string errorMsg) {    try {        errorMsg = null;        string filename = config.FilePath;        //Load the config file as an XDocument        XDocument document = XDocument.Load(filename, LoadOptions.PreserveWhitespace);        if(document.Root == null) {            errorMsg = "Document was null for XDocument load.";            return false;        }        XElement appSettings = document.Root.Element("appSettings");        if(appSettings == null) {            appSettings = new XElement("appSettings");            document.Root.Add(appSettings);        }        XElement appSetting = appSettings.Elements("add").FirstOrDefault(x => x.Attribute("key").Value == key);        if (appSetting == null) {            //Create the new appSetting            appSettings.Add(new XElement("add", new XAttribute("key", key), new XAttribute("value", val)));        }        else {            //Update the current appSetting            appSetting.Attribute("value").Value = val;        }        //Format the appSetting section        XNode lastElement = null;        foreach(var elm in appSettings.DescendantNodes()) {            if(elm.NodeType == System.Xml.XmlNodeType.Text) {                if(lastElement?.NodeType == System.Xml.XmlNodeType.Element && elm.NextNode?.NodeType == System.Xml.XmlNodeType.Comment) {                    //Any time the last node was an element and the next is a comment add two new lines.                    ((XText)elm).Value = "\n\n\t\t";                }                else {                    ((XText)elm).Value = "\n\t\t";                }            }            lastElement = elm;        }        //Make sure the end tag for appSettings is on a new line.        var lastNode = appSettings.DescendantNodes().Last();        if (lastNode.NodeType == System.Xml.XmlNodeType.Text) {            ((XText)lastNode).Value = "\n\t";        }        else {            appSettings.Add(new XText("\n\t"));        }        //Save the changes to the config file.        document.Save(filename, SaveOptions.DisableFormatting);        return true;    }    catch (Exception ex) {        errorMsg = "There was an exception while trying to update the config value for '" + key + "' with value '" + val + "' : " + ex.ToString();        return false;    }}


If comments are critical, it might just be that your only option is to read & save the file manually (via XmlDocument or the new Linq-related API). If however those comments are not critical, I would either let them go or maybe consider embedding them as (albeit redundant) data elements.