2016-07-22 1 views
1

Je pensais que j'avais ce problème léché hier, je l'ai eu en travaillant en changeant l'ordre de mes opérations.Les propriétés de ConfigurationSection ne peuvent pas être éditées lorsqu'elles sont verrouillées

  1. section Créer de nouvelles
  2. Ajouter des éléments à la section
  3. section Ajouter config
  4. config.Save()

Mais aujourd'hui, je reçois la même erreur sur l'appel à config.Save()

Je pensais que le problème était peut-être dû au fait que j'avais ajouté une propriété à l'élément de section lui-même propriété d'index) mais j'ai soutenu cela.

Ma question est pourquoi la section est-elle verrouillée? Quelles opérations provoquent le verrouillage d'une section. Que dois-je faire pour vider le verrou? Quel est le bon ordre pour mettre à jour une section?

Dois-je seulement enregistrer la configuration entière une fois? J'essaie de faire une sauvegarde après avoir modifié chaque section individuelle.

OK, voici une coupe de mon code. À l'exception de FolderSection et FolderElement qui sont dérivés de ConfigurationSection et ConfigurationElement. Le premier appel à UpdateFolders() fonctionne comme prévu. Le deuxième appel échoue dans l'appel à config.Save() avec l'exception interne "Les propriétés de ConfigurationSection ne peuvent pas être modifiées lors du verrouillage" Que faire entre les appels?

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

Quelle est l'erreur que vous obtenez? Où trouve-t-on l'erreur dans votre code? – cdkMoose

+0

@cdkMoose Mise à jour avec test complet. Obtenir l'erreur montrée dans le titre jeté à partir de config.Save() au second appel. –

Répondre

0

Je peux résoudre le problème au moins dans le cas de test, si je hisse la retirerai de la classe de mise à jour de sorte qu'il est exécutée une seule fois.

[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(); 
    } 

Rouvrir la configuration semble également fonctionner dans le cas de test, mais je pourrais jurer que ce que je faisais dans le code d'origine.

[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(); 
    }