锁定时无法编辑ConfigurationSection属性

时间:2016-07-22 09:53:54

标签: .net app-config

我以为我昨天舔了这个问题,我通过改变我的操作顺序让它工作。

  1. 创建新栏目
  2. 部分添加元素
  3. 添加部分到配置
  4. config.Save()
  5. 但今天我在调用config.Save()

    时再次遇到同样的错误

    我原来认为问题可能是因为我添加了一个属性toe section section元素本身(添加了一个索引属性),但我支持了。

    我的问题是该部分为何被锁定?什么操作导致部分被锁定。我需要做些什么来清除锁?更新部分的正确顺序是什么?

    我应该只保存整个配置一次吗?我在修改每个部分后尝试进行保存。

    好的,这是我的代码。除了从ConfigurationSection和ConfigurationElement派生的FolderSection和FolderElement之外。该 第一次调用UpdateFolders()按预期工作。第二次调用在调用config.Save()时失败,内部异常"当锁定"时,无法编辑ConfigurationSection属性。电话之间我该怎么做?

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    using System.IO;
    using System.Configuration;
    
    // using Common.Core;
    // using Common.Config;
    
    namespace Common.Test
    {
        public class FolderElement : ConfigurationElement
        {
            protected const string NameKey = "name";
            protected const string VolumeKey = "volume";
            protected const string PathKey = "path";
            protected const string selectedKey = "selected";
            protected const string activeKey = "active";
    
        [ConfigurationProperty(NameKey, DefaultValue = "", IsKey = true, IsRequired = true)]
        public string Name
        {
            get { return (string)base[NameKey]; }
            set { base[NameKey] = value; }
        }
    
        [ConfigurationProperty(VolumeKey, DefaultValue = "", IsKey = false, IsRequired = false)]
        public string VolumeLabel
        {
            get { return (string)base[VolumeKey]; }
            set { base[VolumeKey] = value; }
        }
    
        [ConfigurationProperty(PathKey, DefaultValue = "", IsKey = false, IsRequired = true)]
        public string Path
        {
            get { return (string)base[PathKey]; }
            set { base[PathKey] = value; }
        }
    
        [ConfigurationProperty(selectedKey, DefaultValue = "false", IsKey = false, IsRequired = false)]
        public bool Selected
        {
            get { return (bool)base[selectedKey]; }
            set { base[selectedKey] = value; }
        }
    
        [ConfigurationProperty(activeKey, DefaultValue = "true", IsKey = false, IsRequired = false)]
        public bool Active
        {
            get { return (bool)base[activeKey]; }
            set { base[activeKey] = value; }
        }
    }
    
    [ConfigurationCollection(typeof(FolderElement))]
    public class FolderCollection : ConfigurationElementCollection
    {
        internal const string _elementName = "elements";
    
        protected override string ElementName
        {
            get { return _elementName; }
        }
    
        public override ConfigurationElementCollectionType CollectionType
        {
            get { return ConfigurationElementCollectionType.AddRemoveClearMap; }
        }
    
        protected override bool IsElementName(string elementName)
        {
            return elementName.Equals(_elementName, StringComparison.InvariantCultureIgnoreCase);
        }
    
        public override bool IsReadOnly()
        {
            return false;
        }
    
        protected override ConfigurationElement CreateNewElement()
        {
            return new FolderElement();
        }
    
        /// <summary>
        /// Return key value for element.
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((FolderElement)element).Name;
        }
    
        /// <summary>
        /// Default index property.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public FolderElement this[int index]
        {
            get { return (FolderElement)BaseGet(index); }
        }
    
    
        /// <summary>
        /// Returns content element by name.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public FolderElement GetElementByName(string name)
        {
            return (FolderElement)BaseGet(name);
        }
    
    
        public IEnumerable<FolderElement> Elements
        {
            get
            {
                for (int index = 0; index < this.Count; index++) yield return (FolderElement)BaseGet(index);
            }
        }
    
        /// <summary>
        /// Add an element to the collection
        /// </summary>
        /// <param name="element"></param>
        public void AddElement(FolderElement element)
        {
            BaseAdd(element);
        }
    
    
    }
    
    public class FolderSection : ConfigurationSection
    {
    
        // Attribute argument must be a constant expression.
        protected const string _elementsTag = "elements";
    
        [ConfigurationProperty(_elementsTag, Options = ConfigurationPropertyOptions.IsDefaultCollection)]
        public FolderCollection Elements
        {
            get { return ((FolderCollection)(base[_elementsTag])); }
            set { base[_elementsTag] = value; }
        }
    
    }
    
    
    [TestClass]
    public class TestConfig
    {
        private string _appName = "Test";
        private string _appFolder = null;
    
        private static string _exec = Path.GetFileName(Environment.GetCommandLineArgs()[0]);
    
    
        public string AppFolder
        {
            get
            {
                return (_appFolder == null)
                    ? _appFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "myProjects", _appName)
                    : _appFolder;
            }
        }
    
    
        public ExeConfigurationFileMap GetFileMap()
        {
    
            var fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = Path.Combine(AppContext.BaseDirectory, _exec + ".config");
            fileMap.RoamingUserConfigFilename = Path.Combine(AppFolder, "App.config");
            fileMap.LocalUserConfigFilename = Path.Combine(AppFolder, "App.config");
    
            return fileMap;
    
        }
    
    
        [TestMethod]
        public void SaveConfigTest()
        {
            var fileMap = GetFileMap();
            var userConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.PerUserRoamingAndLocal);
    
            UpdateFolders(userConfig, "dstFolders", 0, @"C:\Temp", @"C:\Users\Darrel", @"C:\Users\Darrel\MyDocuments");
            UpdateFolders(userConfig, "srcFolders", 0, @"C:\Temp", @"C:\Users\Angela", @"C:\Users\Angela\MyDocuments");
    
        }
    
        public void UpdateFolders(Configuration config, string sectionName, int selectedIndex, params string[] folders)
        {
            bool addSection = false;
    
            var section = config.GetSection(sectionName) as FolderSection;
            if (section == null)
            {
                section = new FolderSection();
                section.SectionInformation.AllowDefinition = ConfigurationAllowDefinition.Everywhere;
                section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
                section.SectionInformation.ForceSave = true;
                section.SectionInformation.ForceDeclaration(true);
                addSection = true;
            }
    
            int index = 0;
            section.Elements.EmitClear = true;
            foreach (var folder in folders)
            {
                string Name = "folder" + (index + 1).ToString();
                // string label = FileHelper.GetVolumeLabel(folder);
                string label = "OS";
                var element = section.Elements.GetElementByName(Name) as FolderElement;
                if (element != null)
                {
                    element.Path = folder;
                    element.VolumeLabel = label;
                }
                else
                {
                    element = new FolderElement() { Name = Name, Path = folder, VolumeLabel = label };
                    section.Elements.AddElement(element);
                }
                element.Selected = (selectedIndex == index);
                index++;
            }
    
            // Add elements to section before adding section to config.Sections.
            if (addSection) config.Sections.Add(sectionName, section);
    
            config.Save();
    
        }
    }
    

    }

1 个答案:

答案 0 :(得分:0)

我可以至少在测试用例中修复问题,如果我将保存提升出更新类,那么它只执行一次。

 [TestMethod]
    public void SaveConfigTest()
    {
        var fileMap = GetFileMap();
        var userConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.PerUserRoamingAndLocal);

        UpdateFolders(userConfig, "dstFolders", 0, @"C:\Temp", @"C:\Users\Darrel", @"C:\Users\Darrel\MyDocuments");
        UpdateFolders(userConfig, "srcFolders", 0, @"C:\Temp", @"C:\Users\Angela", @"C:\Users\Angela\MyDocuments");

        userconfig.Save();
    }

重新打开配置似乎也适用于测试用例,但我发誓这就是我在原始代码中所做的事情。

[TestMethod]
    public void SaveConfigTest()
    {
        var fileMap = GetFileMap();
        var userConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.PerUserRoamingAndLocal);

        UpdateFolders(userConfig, "dstFolders", 0, @"C:\Temp", @"C:\Users\Darrel", @"C:\Users\Darrel\MyDocuments");
        userconfig.Save();

        userConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.PerUserRoamingAndLocal);
        UpdateFolders(userConfig, "srcFolders", 0, @"C:\Temp", @"C:\Users\Angela", @"C:\Users\Angela\MyDocuments"); 
        userconfig.Save();
    }