写入 app.config .Net 中的自定义部分

Posted

技术标签:

【中文标题】写入 app.config .Net 中的自定义部分【英文标题】:Write to custom section in app.config .Net 【发布时间】:2012-04-05 17:29:08 【问题描述】:

我在带有 MVVM 的 WPF 应用程序上使用 .Net 4.0 我已将自定义部分 MyAppCustom.ReportServer.Settings 添加到部分组 userSettings 中,如下所示:

<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b87a6a562548e011" >
  <section name="MyApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b87a6a562548e011" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
  <section name="MyAppCustom.ReportServer.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b87a6a562548e011" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>

<userSettings>
<MyApp.Properties.Settings>
  <setting name="Timezone" serializeAs="String">
    <value>Asia/Calcutta</value>
  </setting>
  <setting name="Language" serializeAs="String">
    <value>en_US</value>
  </setting>
  <setting name="SSO" serializeAs="String">
    <value>True</value>
  </setting>
  <setting name="LoginPeriod" serializeAs="String">
    <value>480</value>
  </setting>
  <setting name="FirstLaunch" serializeAs="String">
    <value>True</value>
  </setting>
  <setting name="IP" serializeAs="String">
    <value />
  </setting>
  <setting name="Port" serializeAs="String">
    <value />
  </setting>
  <setting name="ReportServer" serializeAs="String">
    <value>http://10.2.130.121/ReportServer</value>
  </setting>
  <setting name="Reports" serializeAs="String">
    <value>/MyReports/UserReport</value>
  </setting>
</BallyTech.UserMatrix.Properties.Settings>
<MyAppCustom.ReportServer.Settings>
  <setting name="UserName" serializeAs="String">
    <value>Administrator</value>
  </setting>
  <setting name="Password" serializeAs="String">
    <value>admin</value>
  </setting>
  <setting name="Domain" serializeAs="String">
    <value></value>
  </setting>
</BallyTech.UserMatrix.ReportServer.Settings>

我正在通过以下方式阅读这些设置:

System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
System.Configuration.ClientSettingsSection configClient = ((System.Configuration.ClientSettingsSection)(config.GetSection("userSettings/MyAppCustom.ReportServer.Settings")));

string userName = configClient.Settings.Get("UserName").Value.ValueXml.InnerText;
string password = configClient.Settings.Get("Password").Value.ValueXml.InnerText;

userNamepassword 指的是安装了 s-s-rS 报告服务器 的服务器的登录信息,我从中获取报告和在我的客户端应用程序中通过 ReportViewer 显示。

考虑到我不应该将我的 app.config 中的凭据保存为纯文本,我有 2 种方法来加密和解密 app.config 部分:

public static void EncryptConfigSection(string sectionName)
    
        System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        ConfigurationSection configSection = config.GetSection(sectionName);
        if (configSection != null)
        
            if (!configSection.SectionInformation.IsProtected)
            
                if (!configSection.ElementInformation.IsLocked)
                
                    configSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
                    configSection.SectionInformation.ForceSave = true;
                    config.Save(ConfigurationSaveMode.Full);
                
            
        
    

    public static void DecryptConfigSection(string sectionName)
    
        System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        ConfigurationSection configSection = config.GetSection(sectionName);
        if (configSection != null)
        
            if (!(configSection.SectionInformation.IsLocked))
            
                configSection.SectionInformation.UnprotectSection(); config.Save();
            
         
    

我想让用户可以配置此用户名和密码,以防报表服务器发生更改。因此,我将为用户提供一个界面,以提供报表服务器名称、报表路径和该服务器的凭据。我无法弄清楚如何将用户提供的凭据写入此部分并能够保存它并在运行时刷新设置。

我不想使用 MyApp.Properties.Settings 部分来保存凭据信息,因为我通过 Properties.Settings.Default 在我的应用程序中多次使用它。[ PropertyName] 并且不需要对所有信息进行加密和解密。

另外,我愿意接受任何可以保存凭据并能够对其进行加密并在我的应用程序中读取的替代想法。

【问题讨论】:

【参考方案1】:

您永远不应该写入位于您的应用目录中的 web.config 或 app.config。

    很可能在生产中,该文件夹将是只读的。 特别是 ASP.Net,使用应用程序监视文件夹内的任何更改,并且每次您向 web.config 写入任何内容时都会回收 AppPool。此外,每次您将任何文件写入应用程序文件夹时都会发生这种情况。

因此,要使所有这些工作,您应该创建一个单独的文件夹(不在您的网络应用程序文件夹下),并在那里存储一个单独的配置。

为了在自定义位置打开配置,您应该使用如下代码:

var configMap = new ExeConfigurationFileMap();
configMap.ExeConfigFilename = "your full path to the config";
var customConfig = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);

另外,这是一个网络应用程序的示例文件夹结构:

C:\YourApp - 应用的根目录。 C:\YourApp\Config - 自定义配置文件夹 C:\YourApp\Data - 一些用户生成数据的文件夹,例如上传文件。 C:\YourApp\Web - 在 IIS 中映射的实际 Web 应用程序文件夹。您不应该在此处从您的应用程序代码中写入或更改任何文件,否则 IIS 将回收您的应用程序池。

【讨论】:

以上是关于写入 app.config .Net 中的自定义部分的主要内容,如果未能解决你的问题,请参考以下文章

在Web.config或App.config中的添加自定义配置

在Web.config或App.config中的添加自定义配置

在Web.config或App.config中的添加自定义配置

带有“添加”元素的简单列表的自定义 app.config 部分

为 app.config 内置 .NET 键/值对 configSection 处理程序

使用 FileSystemMonitoring 读取 app.config 中的更改并实时写入 app.config