Not able to save changes to config file

2.9k views Asked by At

I've been following this Stackoverflow topic. Everything works on the read side. I get a collection which I transform into a dictionary of the section contents. I publish this to other projects. The problems occur when I try to save a modified section entry. One of the external projects send a key/Value pair and I need to save it to my section. Here is my App.Config

     <?xml version="1.0" encoding="utf-8" ?>
     <configuration>
        <configSections>
           <section name="fileEnvironmentSection" type="MyApp.Infrastructure.Configuration.FileEnvironmentSection, MyApp.Infrastructure"/>
        </configSections>

        <fileEnvironmentSection>
           <fileEnvironment>
             <add key="TestEntry1" value="A nice value"/> 
             <add key="TestEntry2" value="Another value"/> 
            </fileEnvironment>
        </fileEnvironmentSection>
     </configuration>

Here are the three layers of types needed to interact with the config section.

     using System.Configuration;

     namespace SlamDunk.Infrastructure.Configuration {
        public class FileEnvironmentSection : ConfigurationSection {

           [ConfigurationProperty("fileEnvironment", IsDefaultCollection = false)]
           [ConfigurationCollection(typeof(FileEnvironmentCollection), AddItemName = "add", ClearItemsName = "clear", RemoveItemName = "remove")]
           public FileEnvironmentCollection FileEnvironmentList {
              get { return (FileEnvironmentCollection)base["fileEnvironment"]; }
           }
        }
     }


     using System.Configuration;

     namespace SlamDunk.Infrastructure.Configuration {
        public class FileEnvironmentCollection : ConfigurationElementCollection {

           public FileEnvironmentElement this[int index] {
              get { return (FileEnvironmentElement)BaseGet(index); }
              set {
                 if(BaseGet(index) != null) BaseRemoveAt(index);
                 BaseAdd(index, value);
              }
           }

           public void Add(FileEnvironmentElement fileEnvironmentElement) { BaseAdd(fileEnvironmentElement); }

           public void Clear() { BaseClear(); }

           protected override ConfigurationElement CreateNewElement() { return new FileEnvironmentElement(); }

           protected override object GetElementKey(ConfigurationElement element) { return ((FileEnvironmentElement)element).Key; }

           public void Remove(FileEnvironmentElement fileEnvironmentElement) { BaseRemove(fileEnvironmentElement.Key); }

           public void Remove(string key) { BaseRemove(key); }

           public void RemoveAt(int index) { BaseRemoveAt(index); }
        }
     }


     using System.Configuration;

     namespace SlamDunk.Infrastructure.Configuration {
        public class FileEnvironmentElement : ConfigurationElement {

           private const string appConfigDefaultString = "missing";
           private const string _appConfigNameKey = "key";
           private const string _appConfigNameValue = "value";

           public FileEnvironmentElement() { }

           public FileEnvironmentElement(string key, string value) {
              Key = key;
              Value = value;
           }

           [ConfigurationProperty(_appConfigNameKey, DefaultValue = appConfigDefaultString, IsRequired = true, IsKey = true)]
           public string Key {
              get { return (string)this[_appConfigNameKey]; }
              set { this[_appConfigNameKey] = value; }
          }

           [ConfigurationProperty(_appConfigNameValue, DefaultValue = appConfigDefaultString, IsRequired = true, IsKey = false)]
          public string Value {
             get { return (string)this[_appConfigNameValue]; }
             set { this[_appConfigNameValue] = value; }
          }
        }
     }

Here is the code I'm using to save a key/value change.

     var appConfiguration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
     var fileEnvironmentSection = appConfiguration.GetSection("fileEnvironmentSection") as FileEnvironmentSection;
     var fileEnvironmentList = fileEnvironmentSection.FileEnvironmentList;
     fileEnvironmentList.Remove(key);
     var element = new FileEnvironmentElement(key, value);
     fileEnvironmentList.Add(element);

     //appConfiguration.Save(ConfigurationSaveMode.Modified);

     //fileEnvironmentSection.CurrentConfiguration.Save(ConfigurationSaveMode.Modified);

     fileEnvironmentList.CurrentConfiguration.Save(ConfigurationSaveMode.Modified);

I've checked and the changes appear in the list as expected. I've tried the two commented save call plus the last one. I think I'm getting a new instance of FileEnvironmentSection to avoid ConfigurationManager caching issues. After each test run I look in MyApp.exe.config and do not find any changes. I'm missing something and could use some help figuring out what. Thanks.

1

There are 1 answers

0
jcwmoore On BEST ANSWER
appConfiguration.Save(ConfigurationSaveMode.Modified, true);

appConfiguration.Save(ConfigurationSaveMode.Full, true);

the latter should force a full save of the config file, i think the former will as well. i noticed that you are re-adding the same key to you collect, possibly that's why it is not picked up as modified?