我以为我昨天舔了这个问题,我通过改变我的操作顺序让它工作。
但今天我在调用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();
}
}
}
答案 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();
}