Creating Custom Configuration Sections

The defined handlers are available for you to use for your own custom sections. You need to define a section only once—section definitions are inherited.

For example, suppose you wanted to define a set of product groups containing individual products. You could add a <productGroups> section and define a <product> section, perhaps using a

System.Configuration.NameValueFileSectionHandler to handle returning individual product values. To see how this works, add a new section definition to the top of the web.config file in the root directory of your CSharpASPTest project, just after the <configuration> element:



<section name="product"

type="System.Configuration.NameValueSectionHandler, System" /> </configSections>

<!-- rest of the web.config file —> </configuration>

Next, add a <product> element at the end of the file, just before the </configuration> element.

Note The tags below are commented out in the web.config file for the CSharpASPTest project on Enable the tags between the comments <!— start Listing 16.3—> and <!—end Listing 16.3 —> to see the code in Listing 16.3 work.

<!-- existing web.config file content--> <product>

<add key="Flashlights" value="Flashlights description" /> <add key="Key Rings" value="Key Rings description" /> </product>

The NameValueSectionHandler type implements a getConfig method that returns a NameValue-Collection of product element values. The Web Form getProducts.aspx retrieves the products and loops through them, displaying the keys and values (see Listing 16.3).

Unfortunately, when you run this code, you get an error stating that "File or assembly name System, or one of its dependencies, was not found". Although the documentation states that you can create custom configuration sections that use the NameValueSectionHandler type, you can use it only if you take one of the following steps:

■ Create a custom configuration handler class.

■ Add the <section> tag to your machine.config file rather than to your web.config file.

■ Copy the system.dll file from your Winnt.Microsoft.NET\Framework\<version> folder to the bin folder of your project--in this case, the CSharpASPTest\bin folder. While I don't recommend this option, it may be the only way to get your section to work if you don't have access to the machine.config file.

The first option is the most flexible because by writing your own class, you can handle anything you like; however, it's also the most trouble. See the section "Creating a Custom Configuration Handler" later in this chapter for more information. However, if you can use one of the existing system handlers, it's much easier to use the first option. For simple key/value pairs such as the <product> example, use one of the first two options. Avoid the last option—copying the system.dll—unless you have no other choice.

Add the <section> tag to your machine.config file, and run the Web Form getProducts.aspx in the CSharpASPTest root folder, which retrieves and displays the information in the <product> tag in your web.config file. Listing 16.3 shows the code.

Listing 16.3: Retrieving Custom Configuration Settings (getProducts.aspx.cs)

using System.Collections.Specialized // autogenerated code omitted private void Page Load(object sender, System.EventArgs e) { NameValueCollection nvc = null;

nvc = (NameValueCollection) Context.GetConfig("product"); if (nvc == null) {

Response.Write("No products defined<br>");

foreach (String aKey in nvc.Keys) {

Response.Write(aKey + "=" + nvc.Get(aKey) + "<br>");

The output from the code in Listing 16.3 looks like Figure 16.13.

Figure 16.13: Output from the Web Form


Figure 16.13: Output from the Web Form


Using the built-in configuration handlers, settings are read-only, so you can't use them to add new settings at runtime. It's not clear why Microsoft chose to make the handlers act in read-only mode, because there's a simple workaround. You can add new settings programmatically if you open the file and use the methods in System.XML to add nodes. The procedure is as follows:

1. Create an XmlDocument.

2. Load the web.config file.

3. Retrieve the section node that contains the values you want.

4. Create a new node and add attributes as needed.

5. Append the new node to the section node.

6. Save your changes.

The ASP.NET engine watches the .config file hierarchy and reloads the files if they change, so any changes you make in this manner take effect immediately. For example, the Web Form addProduct.aspx still in the CSharpASPTest application adds a new key and value to the <product> section and displays it immediately (see Listing 16.4).

Listing 16.4: Adding a Custom Configuration Setting Dynamically (addProduct.aspx.cs)

using System.Coiiections.Speciaiized; using System.Xmi;

// autogenerated code omitted private void Page Load(object sender, System.EventArgs e) { NameVaiueCoiiection nvc = nuii; XmiDocument xmi = new XmiDocument();

XmlNode node = null, product = null, keys = null; xml.Load(Server.MapPath(".") + "\\web.config"); keys =

xml.SelectSingleNode("configuration/product/add[@key='Keys']"); if (keys == null) {

Response.Write("Adding key<br>");

product = xml.SelectSingleNode("configuration/product"); node = xml.CreateNode(XmlNodeType.Element, "add", ""); node.Attributes.Append(xml.CreateAttribute("key")); node.Attributes[0].Value = "Keys";

node.Attributes.Append(xml.CreateAttribute("value")); node.Attributes[1].Value = "Keys description"; product.AppendChild(node);

xml.Save(Server.MapPath(".") + "\\web.config");

nvc = (NameValueCollection) Context.GetConfig("product"); if (nvc == null) {

Response.Write("No products defined<br>");

foreach(String aKey in nvc.Keys) {

Response.Write(aKey + "=" + nvc.Get(aKey) + "<br>");

When you run the Web Form, the output looks like Figure 16.14.

Figure 16.14: Output from the Web Form CSharpASPTest.addProduct.aspx after adding a custom setting

Was this article helpful?

0 0

Post a comment