【问题标题】:How to load a separate Application Settings file dynamically and merge with current settings?如何动态加载单独的应用程序设置文件并与当前设置合并?
【发布时间】:2011-01-24 06:16:27
【问题描述】:

存在与reading settings from a separate config file 和其他类似问题有关的问题,但我的问题是特定于应用程序属性设置(即<MyApplication.Properties.Settings> - 请参阅下面的 XML 文件)以及如何动态加载它们。我尝试了this post 中的方法,该方法涉及刷新主配置文件的整个 appSettings 部分,但我的改编引发了异常,因为我没有替换 appSettings 部分:

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
// Have tried the other ConfigurationUserLevels to no avail
config.AppSettings.File = myRuntimeConfigFilePath;
config.Save(ConfigurationSaveMode.Modified); // throws ConfigurationErrorsException
ConfigurationManager.RefreshSection("userSettings");

ConfigurationErrorsException.Message 是“根元素必须与引用文件的部分的名称相匹配,‘appSettings’(C:\myFile.xml 第 2 行)。”文件是:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <MyApplication.Properties.Settings>
            <setting name="SineWaveFrequency" serializeAs="String">
                <value>6</value>
            </setting>
            <setting name="SineWaveAmplitude" serializeAs="String">
                <value>6</value>
            </setting>
        </MyApplication.Properties.Settings>
    </userSettings>
</configuration>

有没有办法将此文件中的值导入MyApplication.Properties.Settings.Default 类,让框架像在应用程序启动时加载配置文件时那样处理所有 XML 反序列化?

【问题讨论】:

标签: .net persistence configuration-files settings


【解决方案1】:

好吧,这行得通:

using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Xml.XPath;

public static class SettingsIO
{
    internal static void Import(string settingsFilePath)
    {
        if (!File.Exists(settingsFilePath))
        {
            throw new FileNotFoundException();
        }

        var appSettings = Properties.Settings.Default;
        try
        {
            var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);

            string appSettingsXmlName = 
Properties.Settings.Default.Context["GroupName"].ToString(); 
// returns "MyApplication.Properties.Settings";

            // Open settings file as XML
            var import = XDocument.Load(settingsFilePath);
            // Get the whole XML inside the settings node
            var settings = import.XPathSelectElements("//" + appSettingsXmlName);

            config.GetSectionGroup("userSettings")
                .Sections[appSettingsXmlName]
                .SectionInformation
                .SetRawXml(settings.Single().ToString());
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("userSettings");

            appSettings.Reload();
        }
        catch (Exception) // Should make this more specific
        {
            // Could not import settings.
            appSettings.Reload(); // from last set saved, not defaults
        }
    }

    internal static void Export(string settingsFilePath)
    {
        Properties.Settings.Default.Save();
        var config = 
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
        config.SaveAs(settingsFilePath);
    }
}

导出方法创建如下文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <MyApplication.Properties.Settings>
            <setting name="SineWaveFrequency" serializeAs="String">
                <value>1</value>
            </setting>
            <setting name="SineWaveAmplitude" serializeAs="String">
                <value>100</value>
            </setting>
            <setting name="AdcShift" serializeAs="String">
                <value>8</value>
            </setting>
            <setting name="ControlBitsCheckedIndices" serializeAs="String">
                <value>0,1,2,3,5,6,7,8</value>
            </setting>
            <setting name="UpgradeSettings" serializeAs="String">
                <value>False</value>
            </setting>
        </MyApplication.Properties.Settings>
    </userSettings>
</configuration>

导入方法解析该文件,获取节点内的所有内容,将该 XML 放入 user.config 文件的适当部分,然后重新加载 Properties.Settings.Default 以便从新用户那里获取这些值。配置文件。

【讨论】:

  • 注意,您必须添加对 System.Configuration 程序集的引用。
  • 什么是属性?我复制并粘贴了代码,但收到此错误“实际上下文中不存在名称“属性””
【解决方案2】:

Pat 建议的解决方案:

// Get the whole XML inside the settings node
var settings = import.XPathSelectElements("//" + appSettingsXmlName);

返回null。我把它改成

var settings = import.Element("configuration").Element("userSettings").Element(appSettingsXmlName);

config.GetSectionGroup("userSettings")
      .Sections[appSettingsXmlName]
      .SectionInformation
      .SetRawXml(settings.ToString());

而且效果很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    相关资源
    最近更新 更多