NameValueSectionHandler - can i use this section type for writing back to the application config file?

你说的曾经没有我的故事 提交于 2019-12-20 04:51:09

问题


back to the topic of why didn't .net provide a simple (i don't want to implement "ConfigurationSection" "ConfigurationElement" "ConfigurationProperty" for 2 values) way to write values back into application config files... (and i don't want to use 'user' app config)

i want to write to the app.config values, i tired the above method of key,value - for reading its fine but i can't write back into it (it says the collection is read only). even though the following method is supplied -

NameValueCollection.Set(string,string)

am i missing something here ?

this is the way i am trying to do it:

 NameValueCollection nvc = (NameValueCollection)ConfigurationManager.GetSection("options");
 nvc.Set("SelectTimeOut", sqlTimeoutSpinBox.Value.ToString());

回答1:


  • No - NameValueSectionHandler does not assist the user in 'creating' the Xml that will be written to the app.config file.

Fire up reflector and take a look at the following method on System.Configuration.NameValueSectionHandler : internal static object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName).

Linda Liu from Microsoft Online Community Support gives some great information about NameValueSectionHandler, IConfigurationSectionHandler, and why a DefaultSection instance will be returned from Configuration.GetSection(string) in a discussion at the EggHeadCafe forums: Backwards compatibility of System.Configuration.Configuration.

It is technically possible to read, and create this information, but I recommend you not cause yourself more pain than you must by interacting at this extremely low level of the Configuration API. Please use the below code for Educational purposes only. I highly encourage you to use one of the methods like what Richard mentioned using the declarative style for creating a custom ConfigurationSection

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="SingleTag" type="System.Configuration.SingleTagSectionHandler"/>
    </configSections>
    <SingleTag scheme="https" server="webmail.contoso.com" domain="CONTOSO" username="jdoe" password="iTz@s3Cr3t!"/>
</configuration>`

You could read this configuration section, but it's not good for your mental health.

Sample C# Code - Stick this inside your void Main(string[] args) and smoke it.

// Read configuration
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSection readableSection = config.GetSection("SingleTag");
string readableSectionRawXml = readableSection.SectionInformation.GetRawXml();
XmlDocument readableSectionRawXmlDocument = new XmlDocument();
readableSectionRawXmlDocument.Load(new StringReader(readableSectionRawXml));
SingleTagSectionHandler readableSectionHandler = new SingleTagSectionHandler();
Hashtable result = (Hashtable)readableSectionHandler.Create(null, null, readableSectionRawXmlDocument.DocumentElement);
foreach (string item in result.Keys)
{
    Console.WriteLine("{0}\t=\t{1}", item, result[item]);
}

// Create similar configuration section
Hashtable mySettings = new Hashtable();
mySettings.Add("key1", "value1:" + DateTime.Now);
mySettings.Add("key2", "value2:" + DateTime.Now);
mySettings.Add("key3", "value3:" + DateTime.Now);
mySettings.Add("keynull", null);
mySettings.Add("key4", "value4:" + DateTime.Now);
string rawData = string.Empty;
XmlDocument writableSectionXmlDocument = new XmlDocument();
XmlElement rootElement = writableSectionXmlDocument.CreateElement("CreateSingleTag");
foreach (var item in mySettings.Keys)
{
    if (mySettings[item] != null)
    {
        rootElement.SetAttribute(item.ToString(), mySettings[item].ToString());
    }
}
writableSectionXmlDocument.AppendChild(rootElement);

if (config.Sections.Get("CreateSingleTag") == null)
{
    ConfigurationSection writableSection = new DefaultSection();
    writableSection.SectionInformation.SetRawXml(writableSectionXmlDocument.OuterXml);
    config.Sections.Add("CreateSingleTag", writableSection);
}
else
{
config.Sections["CreateSingleTag"].SectionInformation.SetRawXml(writableSectionXmlDocument.OuterXml);
}

config.Save();

For completeness sake - you need the following usings

using System;
using System.Collections;
using System.Configuration;
using System.IO;
using System.Xml;

and a reference to at least the following assemblies

System
System.Configuration
System.Xml



回答2:


You need to load the config file in the right way. Rather than using the static properties of ConfigurationManager use the methods to load.

Also you need to ensure you are managing the difference between global, application, user roaming and user local configuration. Normally only the last two should be writeable.

Some test code for writing changes to the use config file:

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
TestConfigData data = (TestConfigData)config.GetSection("testConfigData");
++data.Data;
config.Save(ConfigurationSaveMode.Minimal);

Where TestConfigDate is a custom configuration type:

using System;
using System.Configuration;
using System.Text;

namespace CustomConfiguration {
  public class TestConfigData : ConfigurationSection {

    [ConfigurationProperty("Name", IsRequired=true)]
    public string Name {
      get {
        return (string)this["Name"];
      }
      set {
        this["Name"] = value;
      }
    }

    [ConfigurationProperty("Data", IsRequired=false),
     IntegerValidator(MinValue=0)]
    public int Data {
      get {
        return (int)this["Data"];
      }
      set {
        this["Data"] = value;
      }
    }
  }
}

And the configuration file contains, noting the allowExeDefinition attribute on the section element to define that a user configuration file and override the app.exe.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="testConfigData"
             type="CustomConfiguration.TestConfigData, CustomConfiguration"
             allowExeDefinition="MachineToLocalUser"/>
  </configSections>

  <testConfigData Name="Fubar" Data="0"/>
</configuration>


来源:https://stackoverflow.com/questions/1149443/namevaluesectionhandler-can-i-use-this-section-type-for-writing-back-to-the-ap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!