Creating Custom Configuration Sections in Web.config
2008-04-23 09:39
561 查看
Ref: http://aspnet.4guysfromrolla.com/demos/printPage.aspx?path=/articles/020707-1.aspx
Introduction
Most ASP.NET applications include a number of configuration settings, such as connection strings, mail server settings, system-wide default settings, and so forth. While these settings could be hard-coded in the source code, it's usually a wiser idea to place them in a configuration file, such as
While
Custom configuration sections can be created in
This model can be used in ASP.NET 2.0 applications, but .NET 2.0 offers new configuration classes that eliminate the need for a handler class as well as for the deserialization code. In short, using .NET 2.0's new configuration classes you can simply create a class whose properties represent the configuration information and specify declaratively, through attributes on the properties, how these properties map to the XML in the configuration markup. In this article we will focus solely on the 1.x technique; Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API for more on .NET 2.0's new configuration classes and capabilities. We'll first look at creating and using a very simple custom configuration section. Following that, we'll add a collection property to the section. Why ASP.NET 1.x Syntax and Style is Used Since this article examines features that date back to the 1.x timeframe (even though they'll work perfectly fine in 2.0 and even though the download at the end of this article is an ASP.NET 2.0 website application), I've used the syntax that works in 1.x rather than take advantage of new 2.0 features. For example, later on in this article we'll use the
As aforementioned, the code for custom configuration sections in ASP.NET 1.x applications is typically broken down into two class files, a handler class and a configuration class. Let's create the configuration class first. Imagine that we want our custom configuration section to record three settings:
The three private member variables specify the default values (i.e., the values used if the property is not provided in the custom configuration section). The three properties are read-only and simply return the corresponding member variable.
The configuration class also needs to provide a method for deserializing the configuration XML. To accomplish this, we need to add a method that accepts an
The
Creating the Handler Class
The handler class is reponsible for taking the XML from the configuration file and passing it to the configuration class for deserialization. The handler class must implement
An instance of the
Defining the Custom Configuration Section in
To use the custom configuration section in
Note that the
With the custom configuration section specified in
Programmatically Accessing the Configuration Information from the ASP.NET Application
To work with the configuration information from an ASP.NET page or one of the classes that make up the application's architecture, we need to use the
What's cool about the
Rather than having to enter this code each time we want to work with configuration data, we can add a
With this method in place, accessing a configuration value is as easy as doing the following:
The following ASP.NET page displays these configuration settings in a Label Web control, as the following code illustrates:
Deserializing More "Interesting" Configuration Markup
The code we've examined thus far has only allowed for scalar properties defined as attributes in the configuration markup. But what if we want to have the custom configuration section specify properties through the XML elements' text nodes (like
Since the configuration class's
To accomplish this, we'd need to add a new property to the configuration class
Conclusion
In this article we explored the technique used in ASP.NET 1.x for specifying custom configuration settings in
This method for providing custom configuration sections can be used by both ASP.NET 1.x and 2.0 applications. However, .NET 2.0 provides configuration classes that require much less code, letting us focus more on defining the properties and declaratively mapping them to the XML markup rather than writing XML deserialization code. .NET 2.0's configuration features are explored in: Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API.
Happy Programming!
Introduction
Most ASP.NET applications include a number of configuration settings, such as connection strings, mail server settings, system-wide default settings, and so forth. While these settings could be hard-coded in the source code, it's usually a wiser idea to place them in a configuration file, such as
Web.config. The reasoning being that if these values need to be modified, editing a configuration file is a lot easier than updating the code, rebuilding, and re-deploying. In fact,
Web.configprovides an
<appSettings>section intended to hold application-wide configuration settings (see Specifying Configuration Settings in
Web.configfor more details).
While
<appSettings>work well for in-house applications, if you are building an application that will be deployed by end users a more professional approach is to use a custom configuration section.
<appSettings>, for example, requires that all values be simple scalars provided through
<add>elements, like:
<appSettings> <add key="message" value="Hello, World!" /> <add key="maxEntriesPerPage" value="10" /> <add key="showMessageInBold" value="true" /> </appSettings>With a custom configuration section, you can provide a more readable syntax. Moreover, custom configuration sections can support collection properties, as the following example illustrates:
<ScottsSettings message="Hello, World!" showMessageInBold="true"> <favoriteColors> <color>Red</color> <color>Yellow</color> <color>Brown</color> </favoriteColors> </ScottsSettings>In this article we'll examine how to use a custom configuration section technique that works in both ASP.NET 1.x and 2.0 applications. See Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API for more on .NET 2.0's new configuration classes and capabilities. Read on to learn more! Custom Configuration Section Basics
Custom configuration sections can be created in
Web.configthrough the
<configSections>element, specifying the name of the configuration section and the class type that is responsible for deserializing the configuration XML into a class instance. We'll explore the
<configSections>element in
Web.configonce we have created a class to handle the deserialization. In ASP.NET 1.x applications, typically two classes are used: A handler class, which implements
System.Configuration.IConfigurationSectionHandler. This class is responsible for loading the configuration markup from
Web.config. A configuration class whose set of properties represent the information captured in the custom configuration section. Along with providing the properties, this class also is responsible for deserializing the configuration XML passed to it from its corresponding handler class.
This model can be used in ASP.NET 2.0 applications, but .NET 2.0 offers new configuration classes that eliminate the need for a handler class as well as for the deserialization code. In short, using .NET 2.0's new configuration classes you can simply create a class whose properties represent the configuration information and specify declaratively, through attributes on the properties, how these properties map to the XML in the configuration markup. In this article we will focus solely on the 1.x technique; Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API for more on .NET 2.0's new configuration classes and capabilities. We'll first look at creating and using a very simple custom configuration section. Following that, we'll add a collection property to the section. Why ASP.NET 1.x Syntax and Style is Used Since this article examines features that date back to the 1.x timeframe (even though they'll work perfectly fine in 2.0 and even though the download at the end of this article is an ASP.NET 2.0 website application), I've used the syntax that works in 1.x rather than take advantage of new 2.0 features. For example, later on in this article we'll use the
ConfigurationSettingsclass's
GetConfigmethod, which has been deprecated in 2.0 in favor of the
ConfigurationManagerclass's
GetSectionmethod. Regardless, I stick with the using the
ConfigurationSettingsclass's
GetConfigmethod. Similarly, when we look at specifying collections in the custom configuration section, I use a
StringCollectionobject to hold this collection of strings. If I were creating this for .NET 2.0, I'd use a Generic
Listinstance of type
stringinstead. Creating the Configuration Class
As aforementioned, the code for custom configuration sections in ASP.NET 1.x applications is typically broken down into two class files, a handler class and a configuration class. Let's create the configuration class first. Imagine that we want our custom configuration section to record three settings:
message,
favoriteNumber, and
showMessageInBold. We would start by creating three public properties in this class like so:
public class ASPNET1Configuration { private string _message = "Hello, World!"; private int _favoriteNumber = 2; private bool _showMessageInBold = true; public string Message { get { return _message; } } public int FavoriteNumber { get { return _favoriteNumber; } } public bool ShowMessageInBold { get { return _showMessageInBold; } } ... }
The three private member variables specify the default values (i.e., the values used if the property is not provided in the custom configuration section). The three properties are read-only and simply return the corresponding member variable.
The configuration class also needs to provide a method for deserializing the configuration XML. To accomplish this, we need to add a method that accepts an
XmlNodeinstance as input and steps through the XML data to populate the property values.
public class ASPNET1Configuration { ... Property and member variable statements omitted for bevity ... internal void LoadValuesFromXml(XmlNode section) { XmlAttributeCollection attrs = section.Attributes; if (attrs["message"] != null) { _message = attrs["message"].Value; attrs.RemoveNamedItem("message"); } if (attrs["favoriteNumber"] != null) { _favoriteNumber = Convert.ToInt32(attrs["favoriteNumber"].Value); attrs.RemoveNamedItem("favoriteNumber"); } if (attrs["showMessageInBold"] != null) { _showMessageInBold = XmlConvert.ToBoolean(attrs["showMessageInBold"].Value); attrs.RemoveNamedItem("showMessageInBold"); } // If there are any further attributes, there's an error! if (attrs.Count > 0) throw new ConfigurationException("There are illegal attributes provided in the section"); } }
The
LoadValuesFromXmlmethod inspects the
Attributescollection of the passed-in
XmlNodeinstance. If it exists, it reads in the value into the corresponding member variable and removes the attribute from the
XmlNode. If, after the three properties have been deserialized, there are any additional attributes in the
XmlNode, a
ConfigurationExceptionis raised since an invalid attribute is included in the custom configuration section.
Creating the Handler Class
The handler class is reponsible for taking the XML from the configuration file and passing it to the configuration class for deserialization. The handler class must implement
IConfigurationSectionHandler, which defines a single method,
Create.
Createaccepts as one of its input parameters the
XmlNodefrom the configuration section and is tasked with returning an instance of the configuration data. This can all be accomplished with just a few lines of code, as shown below:
public class ASPNET1ConfigurationHandler : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) { ASPNET1Configuration config = new ASPNET1Configuration(); config.LoadValuesFromXml(section); return config; } }
An instance of the
ASPNET1Configurationclass is created and its
LoadValuesFromXmlmethod is passed the
XmlNodeinstance received by the
Createmethod. The
Createmethod completes by returning the deserialized
ASPNET1Configurationinstance.
Defining the Custom Configuration Section in
Web.config
To use the custom configuration section in
Web.config, we need to first define it in the
<configSections>element like so:
<configuration> <!-- Define the custom configuration sections... --> <configSections> <section name="aspnet1Configuration" type="ASPNET1ConfigurationHandler"/> </configSections> <system.web> ... </system.web> </configuration>
Note that the
typevalue is the fully-typed name of the handler class. Since the handler class appears in my
App_Codefolder, the value for the
typeattribute is simply the class's name. If this class resided in a separate assembly, the
typevalue would be: "Namespace.ClassName, AssemblyName".
With the custom configuration section specified in
<configSections>, we can add the custom section to
Web.config. Note that the custom section, like
<configSections>, appears outside of the
<system.web>section:
<configuration> <!-- Define the custom configuration sections... --> <configSections> <section name="aspnet1Configuration" type="ASPNET1ConfigurationHandler"/> </configSections> <aspnet1Configuration message="This is a test!" showMessageInBold="true" /> <system.web> ... </system.web> </configuration>
Programmatically Accessing the Configuration Information from the ASP.NET Application
To work with the configuration information from an ASP.NET page or one of the classes that make up the application's architecture, we need to use the
ConfigurationSettingsclass's
GetConfigmethod, passing in the path to the markup we are interested in ("aspnet1Configuration", for this example). This can be accomplished using the following code snippet:
ASPNET1Configuration configInfo = (ASPNET1Configuration) ConfigurationSettings.GetConfig("aspnet1Configuration"); // Work with the properties from the ASPNET1Configuration class... string msg = configInfo.Message; ...
What's cool about the
GetConfig()method is that is automatically caches the configuration information returned by the associated handler class. This data remains cached until the application is restarted (such as through restarting the webserver, modifying
Web.config, uploading an assembly to the
/binfolder, and so on). To convince yourself that this caching occurs, download the sample code at the end of this article and set a breakpoint in the above line of code and in the
Createmethod of the handler class and then start debugging. What you'll find is that the first time the configuration data is read in after an application restart, the handler class's
Createmethod is invoked when the
GetConfig()method is called. On subsequent calls, however, the
Createmethod is not executed, as its results have been cached.
Rather than having to enter this code each time we want to work with configuration data, we can add a
staticmethod to the
ASPNET1Configurationthat encapsulates this logic.
public static ASPNET1Configuration GetConfig() { return ConfigurationSettings.GetConfig("customConfigDemo/aspnet1Configuration") as ASPNET1Configuration; }
With this method in place, accessing a configuration value is as easy as doing the following:
string msg = ASPNET1Configuration.GetConfig().Message;
The following ASP.NET page displays these configuration settings in a Label Web control, as the following code illustrates:
string messageHtml = ASPNET1Configuration.GetConfig().Message; if (ASPNET1Configuration.GetConfig().ShowMessageInBold) messageHtml = "<b>" + messageHtml + "</b>"; int favNumber = ASPNET1Configuration.GetConfig().FavoriteNumber; // Display the configuration settings aspnet1Values.Text = string.Format("The message is {0} and your favorite number is {1}.", messageHtml, favNumber);
Deserializing More "Interesting" Configuration Markup
The code we've examined thus far has only allowed for scalar properties defined as attributes in the configuration markup. But what if we want to have the custom configuration section specify properties through the XML elements' text nodes (like
<someProperty<value</someProperty>) or what if we want to allow the configuration data to include an arbitrary collection of information?
Since the configuration class's
LoadValuesFromXmlmethod is passed an
XmlNode, we simply need to update that method to perform any of the more rigorous deserialization. For example, imagine that in addition to the
message,
favoriteNumber, and
showMessageInBoldproperties we also wanted to allow the developer to specify a list of "favorite colors" through the following pattern:
<aspnet1Configuration message="This is a test!" showMessageInBold="true"> <favoriteColors> <color>Red</color> <color>Olive</color> <color>Purple</color> ... </favoriteColors> </aspnet1Configuration>
To accomplish this, we'd need to add a new property to the configuration class
ASPNET1Configurationto hold the list of favorite colors. Moreover, we'd need to update the
LoadValuesFromXmlmethod to find the
<favoriteColors>element and add its
<color>elements' text node values to the corresponding property. The following code accomplishes these two tasks:
public class ASPNET1Configuration { ... Prior property and member variable statements omitted for bevity ... private StringCollection _favColors = new StringCollection(); public StringCollection FavoriteColors { get { return _favColors; } } internal void LoadValuesFromXml(XmlNode section) { ... Prior deserialization logic removed for brevity ... // Now, get the child node bool processedFavColors = false; foreach (XmlNode childNode in section.ChildNodes) { if (!processedFavColors && childNode.Name == "favoriteColors") { processedFavColors = true; foreach (XmlNode favColorNode in childNode.ChildNodes) { if (favColorNode.Name == "color") { // Get the text node value XmlNode textNode = favColorNode.ChildNodes[0]; if (textNode == null) throw new ConfigurationException("You must provide a text value for each element, like Red"); else _favColors.Add(textNode.Value); } else throw new ConfigurationException(" can only contain child elements named "); } } else throw new ConfigurationException(" may only contain one child element and it must be named "); } } }
Conclusion
In this article we explored the technique used in ASP.NET 1.x for specifying custom configuration settings in
Web.config. This is accomplished by creating two classes: a handler class and a configuration class. The handler class is used to pump the XML data from the configuration file to the configuration class, where it is deserialized. In addition to its deserialization logic, the configuration class also contains the properties that model the configuration information. This class can be accessed programmatically via the
ConfigurationSettingsclass's
GetConfigmethod.
This method for providing custom configuration sections can be used by both ASP.NET 1.x and 2.0 applications. However, .NET 2.0 provides configuration classes that require much less code, letting us focus more on defining the properties and declaratively mapping them to the XML markup rather than writing XML deserialization code. .NET 2.0's configuration features are explored in: Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API.
Happy Programming!
相关文章推荐
- Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API
- Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API
- Creating Custom Configuration Sections in Web.config Using .NET 2.0's Configuration API
- Customize web.config sections and register your own configuration then get values in asp.net
- WCF hosted in IIS reading configuration section in *.config other than web.config
- Another way to retrieve a custom key's value from web.config in web form application
- 管理后台-第一部分:Creating custom sections in Umbraco 7 - Part 1(翻译文档)
- custom errors in webconfig
- asp.net c# web.config 读取web.config中自定义的参数信息,configuration section configSections
- Creating Custom Web Controls in C# Stats(转)
- Creating and writing ASP.NET 2.0 custom Configuration Sections
- [转]Creating Custom Web Controls in C# Stats(演示了如何创建一个导航条)
- Specifying Configuration Settings in Web.config
- WCF Server Configuration in Web.config or App.config
- (对Web.config文件加密)encrypting sensitive information stored in the web.config file
- 关于web.config中<customErrors>节点说明
- Accessing web.config at Design Time in .NET 2.0 (转)
- vs, vsto,custom settings file in app.config 部署后会在哪里
- Edit and encrypt Web.Config sections using C# 2.0
- 虚拟主机运行ASP错误解决:HTTP/1.1 New Application Failed when allowSessionState is set to false in web.config