【问题标题】:Reading and writing values in.NET .config files在 .NET .config 文件中读取和写入值
【发布时间】:2012-05-06 21:34:28
【问题描述】:

我想为 user.config 文件使用自定义路径,而不是让 .NET 从默认位置读取它。

我是这样打开文件的:

ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
configMap.ExeConfigFilename = String.Format("{0}\\user.config",AppDataPath);
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.PerUserRoamingAndLocal);

但我不知道如何实际从中读取设置,我收到一个编译错误,提示当我尝试通过 AppData 或 ConfigurationSection 获取值时无法访问这些值。

我是否需要创建某种包装类来正确使用数据?

【问题讨论】:

  • 您有自定义配置部分吗?配置文件是什么样的,你的消费代码是什么样的?
  • @yamen 没有,基本都是现货。

标签: c# .net configuration configuration-files configurationmanager


【解决方案1】:

我最近接到了一个类似问题的任务,我不得不将读取设置文件的位置从 AppData 中的默认位置更改为应用程序目录。我的解决方案是创建我自己的设置文件,这些文件源自ApplicationSettingsBase,它指定了一个自定义SettingsProvider。虽然这个解决方案一开始感觉有点矫枉过正,但我​​发现它比我预期的更灵活和可维护。

更新:

示例设置文件:

public class BaseSettings : ApplicationSettingsBase
{
    protected BaseSettings(string settingsKey)
       { SettingsKey = settingsKey.ToLower(); }


    public override void Upgrade()
    {
         if (!UpgradeRequired)
             return;
         base.Upgrade();
         UpgradeRequired = false;
         Save();
    }


    [SettingsProvider(typeof(MySettingsProvider)), UserScopedSetting]
    [DefaultSettingValue("True")]
    public bool UpgradeRequired
    {
         get { return (bool)this["UpgradeRequired"]; }
         set { this["UpgradeRequired"] = value; }
    }
}

示例设置提供者:

public sealed class MySettingsProvider : SettingsProvider
{
    public override string ApplicationName { get { return Application.ProductName; } set { } }
    public override string Name { get { return "MySettingsProvider"; } }


    public override void Initialize(string name, NameValueCollection col)
         { base.Initialize(ApplicationName, col); }


    public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propertyValues)
    {
       // Use an XmlWriter to write settings to file. Iterate PropertyValueCollection and use the SerializedValue member
    }


    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
    {
       // Read values from settings file into a PropertyValuesCollection and return it
    }


    static MySettingsProvider()
    {
        appSettingsPath_ = Path.Combine(new FileInfo(Application.ExecutablePath).DirectoryName, settingsFileName_);

        settingsXml_ = new XmlDocument();
        try { settingsXml_.Load(appSettingsPath_); }
        catch (XmlException) { CreateXmlFile_(settingsXml_); } //Invalid settings file
        catch (FileNotFoundException) { CreateXmlFile_(settingsXml_); } // Missing settings file
    }
}

【讨论】:

  • 最后,我做了非常相似的事情。似乎让配置工作更容易,但我对此的需求是如此简单,以至于没有理由花更多时间在这个问题上。
【解决方案2】:

一些改进:

1) 加载起来简单一点,不需要其他行:

var config = ConfigurationManager.OpenExeConfiguration(...);

2) 正确访问AppSettings:

config.AppSettings.Settings[...]; // and other things under AppSettings

3) 如果您想要自定义配置部分,请使用此工具:http://csd.codeplex.com/

【讨论】:

    【解决方案3】:

    我从来没有让配置管理器方法工作。在摸索了半天毫无进展后,我决定推出自己的解决方案,因为我的需求是基本的。

    这是我最后想出的解决方案:

    public class Settings
    {
        private XmlDocument _xmlDoc;
        private XmlNode _settingsNode;
        private string _path;
    
        public Settings(string path)
        {
            _path = path;
            LoadConfig(path);
        }
    
        private void LoadConfig(string path)
        {
           //TODO: add error handling
            _xmlDoc = null;
            _xmlDoc = new XmlDocument();
            _xmlDoc.Load(path);
            _settingsNode = _xmlDoc.SelectSingleNode("//appSettings");
        }
    
        //
        //use the same structure as in .config appSettings sections
        //
        public string this[string s]
        {
            get
            {
                XmlNode n = _settingsNode.SelectSingleNode(String.Format("//add[@key='{0}']", s));
                return n != null ? n.Attributes["value"].Value : null;
            }
            set
            {
                XmlNode n = _settingsNode.SelectSingleNode(String.Format("//add[@key='{0}']", s));
    
                //create the node if it doesn't exist
                if (n == null)
                {
                    n=_xmlDoc.CreateElement("add");
                    _settingsNode.AppendChild(n);
                    XmlAttribute attr =_xmlDoc.CreateAttribute("key");
                    attr.Value = s;
                    n.Attributes.Append(attr);
                    attr = _xmlDoc.CreateAttribute("value");
                    n.Attributes.Append(attr);
                }
    
                n.Attributes["value"].Value = value;
                _xmlDoc.Save(_path);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-16
      • 2015-09-29
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      相关资源
      最近更新 更多