本文的发布号曾为 CHS309045
有关本文的 Microsoft Visual Basic .NET 版本,请参见
318457。
本文引用下面的 Microsoft .NET 框架类库名称空间:
本文引用下面的 Microsoft .NET 框架类库名称空间:
- System.Configuration
- System.Xml
本任务的内容
概要
本文介绍如何使用 Visual C# .NET 创建 ASP.NET 自定义配置节处理程序。返回页首
创建配置节处理程序及其组件
以下步骤演示如何创建配置节处理程序及其组件。为了使您可以更好地维护并重用这些代码,以下步骤演示了如何创建一个包含静态方法的名为 ConfigHelper 的类。这些静态方法帮助您分析并检索配置文件中的 XML 属性。由于构建 ConfigHelper 的代码在配置节中使用枚举和一个字符串,所以 ConfigHelper 包含两种方法: GetEnumValue 和 GetStringValue。GetEnumValue 方法用预定义的值分析配置节中的属性,确认属性值有效,然后返回该属性及属性值。 GetStringValue 方法分析配置节中的属性,然后返回属性及属性值。
- 启动 Microsoft Visual Studio .NET。
- 在文件菜单上,指向新建,然后单击项目。
- 在新建项目对话框中,单击项目类型下的 Visual C# Projects,然后单击模板下的类库。在名称文本框中,键入 MyConfig,然后单击确定。
- 添加一个对 System.Web.dll 程序集的引用。
- 将 Class1.cs 重命名为 MyConfig.cs。
- 从"解决方案资源管理器"中,打开 MyConfig.cs。
- 将以下名称空间声明添加到文件的顶部:
using System.Configuration; using System.Web; using System.Xml;
- 删除默认类定义。
- 添加枚举以保存自定义配置节的属性:
public enum LevelSetting { High, Medium, Low, None }
- 创建名为 MyConfigSection 的类来保存配置信息。该类是 Create 方法实现返回的对象。
public class MyConfigSection { private LevelSetting level = LevelSetting.None; private string name = ""; public MyConfigSection(LevelSetting _level, string _name) { level = _level; name = _name; } public LevelSetting Level { get {return level;} } public string Name { get {return name;} } }
- 按如下所示创建名为 ConfigHelper 的类:
internal class ConfigHelper { //Helper method for retrieving enum values from XmlNode. public static XmlNode GetEnumValue (XmlNode _node, string _attribute,Type _enumType, ref int _val) { XmlNode a = _node.Attributes.RemoveNamedItem(_attribute); if(a==null) throw new ConfigurationException("Attribute required:" + _attribute); if(Enum.IsDefined(_enumType, a.Value)) _val = (int)Enum.Parse(_enumType,a.Value); else throw new ConfigurationException("Invalid Level:'" + a.Value + "'",a); return a; } //Helper method for retrieving string values from xmlnode. public static XmlNode GetStringValue(XmlNode _node, string _attribute, ref string _val) { XmlNode a = _node.Attributes.RemoveNamedItem(_attribute); if(a==null) throw new ConfigurationException("Attribute required:" + _attribute); else _val = a.Value; return a; } }
备注:您也可以为每一种数据类型创建一个 helper 方法用于您的配置节(例如,GetIntValue 和 GetBooleanValue)。 - 创建一个名为 MyConfigSectionHandler 的类。该类继承 IConfigurationSectionHandler 接口并实现该接口的 Create 方法。在 Create 方法中,此代码使用 ConfigHelper 类从配置文件检索数值。然后,该示例创建并返回 MyConfigSection 对象。
MyConfigSectionHandler 类应如以下所示:public class MyConfigSectionHandler :IConfigurationSectionHandler { public virtual object Create(object parent,object configContext,XmlNode section) { int iLevel = 0; string sName = ""; ConfigHelper.GetEnumValue(section, "level", typeof(LevelSetting), ref iLevel); ConfigHelper.GetStringValue(section, "name", ref sName); return new MyConfigSection((LevelSetting)iLevel,sName); } }
- 保存并编译项目。
完整代码列表
在最后一个窗体中,您的类文件应如以下所示:using System; using System.Web; using System.Xml; using System.Configuration; namespace MyConfig { public enum LevelSetting { High, Medium, Low, None } public class MyConfigSectionHandler :IConfigurationSectionHandler { public virtual object Create(object parent,object configContext,XmlNode section) { int iLevel = 0; string sName = ""; ConfigHelper.GetEnumValue(section, "level", typeof(LevelSetting), ref iLevel); ConfigHelper.GetStringValue(section,"name",ref sName); return new MyConfigSection((LevelSetting)iLevel,sName); } } public class MyConfigSection { private LevelSetting level = LevelSetting.None; private string name = null; public MyConfigSection(LevelSetting _level,string _name) { level = _level; name = _name; } public LevelSetting Level { get {return level;} } public string Name { get {return name;} } } internal class ConfigHelper { public static XmlNode GetEnumValue (XmlNode _node, string _attribute,Type _enumType, ref int _val) { XmlNode a = _node.Attributes.RemoveNamedItem(_attribute); if(a==null) throw new ConfigurationException("Attribute required:" + _attribute); if(Enum.IsDefined(_enumType, a.Value)) _val = (int)Enum.Parse(_enumType,a.Value); else throw new ConfigurationException("Invalid Level",a); return a; } public static XmlNode GetStringValue(XmlNode _node, string _attribute, ref string _val) { XmlNode a = _node.Attributes.RemoveNamedItem(_attribute); if(a==null) throw new ConfigurationException("Attribute required:" + _attribute); else _val = a.Value; return a; } } }返回页首
测试配置处理程序
- 打开 Visual Studio .NET。
- 在新建项目对话框中,单击项目类型下面的 Visual C# 项目,然后单击模板下面的 ASP.NET Web 应用程序。为您的新项目指定名称和位置。
- 添加对 MyConfig.dll 的引用。
- 打开 Web.config 文件。在 <configuration> 部分添加以下代码:
<configSections> <sectionGroup name="system.web"> <section name="myConfig" type="MyConfig.MyConfigSectionHandler,MyConfig" /> </sectionGroup> </configSections>
- 在 <system.web> 部分添加以下代码:
<myConfig level="High" name="hello world" />
- 打开 WebForm1.aspx 的代码隐藏 (code-behind) 文件,默认名为 WebForm1.aspx.cs。在 WebForm1.aspx.cs 顶部添加以下名称空间声明:
using MyConfig;
- 将下面的代码添加到 Page_Load 事件:该代码调用 GetConfig 方法来检索 MyConfigSection 对象的实例,然后填写该对象的两个属性值。
MyConfigSection s = (MyConfigSection)Context.GetConfig("system.web/myConfig"); Response.Write("Level:" + s.Level + "<br>"); Response.Write("Name:" + s.Name);
- 保存并编译该应用程序。
- 在浏览器中查看该页面。输出如下:
Level:High
Name:hello world
疑难解答
创建自定义的 ASP.NET 配置节处理程序时,实现 IConfigurationSectionHandler 接口时遵从以下原则:- 您实现 IConfigurationSectionHandler 接口的类实例必须是线程安全且无状态的。您必须能够从多个线程同时调用 IConfigurationSectionHandler.Create 方法。
- IConfigurationSectionHandler.Create 返回的配置对象必须是线程安全且不可变。
- 不要修改 IConfigurationSectionHandler.Create 的父参数。因为配置系统缓存配置对象,不修改 IConfigurationSectionHandler.Create 的父参数是很重要的。例如,如果 IConfigurationSectionHandler.Create 的返回值只对父参数进行小的修改,则必须修改父参数的副本,而不是原值。
参考
有关 ASP.NET 配置的其他信息,请单击下列文章编号,查看相应的 Microsoft 知识库文章:307626 INFO: ASP.NET Configuration Overview(INFO:ASP.NET 配置概述)
307513 PRB: Access Violation Occurs When You Use a Custom Configuration Section Handler in an ASP.NET Application That Is Under Stress(PRB:在负荷较重的 ASP.NET 应用程序中使用自定义配置节处理程序时发生访问冲突)
返回页首这篇文章中的信息适用于:
- Microsoft ASP .NET(随 .NET 框架一起提供)
- Microsoft Visual C# .NET (2002)
最近更新: | 2002-7-15 (1.0) |
关键字 | kbConfig kbDSupport kbGrpDSASP kbhowto kbHOWTOmaster kbweb KB309045 |