Практическое руководство. Создание пользовательских разделов конфигураций с помощью IConfigurationSectionHandler
Обновлен: Ноябрь 2007
При необходимости можно дополнить стандартный набор параметров конфигурации ASP.NET собственными элементами конфигурации XML. Для этого необходимо создать собственный обработчик разделов конфигурации.
Обработчик должен быть классом .NET Framework, реализующим либо интерфейс System.Configuration.IConfigurationSectionHandler, либо класс System.Configuration.ConfigurationSection.
Примечание. |
---|
В этом разделе используется интерфейс System.Configuration.IConfigurationSectionHandler, который стал устаревшим в .NET Framework версии 2.0. Пример, который использует класс System.Configuration.ConfigurationSection, см. в разделе Практическое руководство. Создание пользовательских разделов конфигурации с помощью класса ConfigurationSection. Чтобы воспользоваться следующими примерами кода, следует построить их с помощью .NET Framework версии 1.0 или 1.1. |
Обработчик разделов интерпретирует и обрабатывает параметры, определенные в элементах конфигурации XML указанной части файла Web.config, и возвращает соответствующие объекты конфигурации, полученные на основе этих параметров. Объект конфигурации, возвращаемый классом обработчика, может быть любой структурой данных и не ограничен каким-либо базовым классом или форматом конфигурации. В ASP.NET объекты конфигурации используются для чтения и записи пользовательских элементов конфигурации.
Создание обработчика пользовательского раздела конфигурации
Создайте открытый класс, реализующий интерфейс System.Configuration.IConfigurationSectionHandler, как показано в следующем коде.
Imports System Imports System.Collections Imports System.Text Imports System.Configuration Imports System.Xml Namespace MyConfigSectionHandler Public Class MyHandler Implements IConfigurationSectionHandler Public Function Create( _ ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) _ As Object Implements System.Configuration.IConfigurationSectionHandler.Create Throw New System.Exception("The method is not implemented.") End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Text; using System.Configuration; using System.Xml; namespace MyConfigSectionHandler { public class MyHandler : IConfigurationSectionHandler { #region IConfigurationSectionHandler Members object IConfigurationSectionHandler.Create( object parent, object configContext, XmlNode section) { throw new Exception("The method is not implemented."); } #endregion } }
Добавьте собственный код настройки параметров конфигурации.
Например, можно заменить строку throw new Exception("The method is not implemented."); кодом, который получает имена и значения атрибутов из свойства Attributes параметра section и возвращает объект пользовательской конфигурации. В следующем примере в качестве объекта конфигурации используется Hashtable.
Imports System Imports System.Collections Imports System.Text Imports System.Configuration Imports System.Xml Namespace MyConfigSectionHandler Public Class MyHandler Implements IConfigurationSectionHandler Public Function Create( _ ByVal parent As Object, ByVal configContext As Object, ByVal section As System.Xml.XmlNode) _ As Object Implements System.Configuration.IConfigurationSectionHandler.Create ' Creates the configuration object that this method will return. ' This can be a custom configuration class. ' In this example, we use a System.Collections.Hashtable. Dim myConfigObject As New Hashtable ' Gets any attributes for this section element. Dim myAttribs As New Hashtable For Each attrib As XmlAttribute In section.Attributes If XmlNodeType.Attribute = attrib.NodeType Then myAttribs.Add(attrib.Name, attrib.Value) End If Next ' Puts the section name and attributes as the first config object item. myConfigObject.Add(section.Name, myAttribs) ' Gets the child element names and attributes. For Each child As XmlNode In section.ChildNodes If XmlNodeType.Element = child.NodeType Then Dim myChildAttribs As New Hashtable For Each childAttrib As XmlAttribute In child.Attributes If XmlNodeType.Attribute = childAttrib.NodeType Then myChildAttribs.Add(childAttrib.Name, childAttrib.Value) End If Next myConfigObject.Add(child.Name, myChildAttribs) End If Next Return (myConfigObject) End Function End Class End Namespace
using System; using System.Collections; using System.Text; using System.Configuration; using System.Xml; namespace MyConfigSectionHandler { public class MyHandler : IConfigurationSectionHandler { #region IConfigurationSectionHandler Members object IConfigurationSectionHandler.Create( object parent, object configContext, XmlNode section) { // Creates the configuration object that this method will return. // This can be a custom configuration class. // In this example, we use a System.Collections.Hashtable. Hashtable myConfigObject = new Hashtable(); // Gets any attributes for this section element. Hashtable myAttribs = new Hashtable(); foreach (XmlAttribute attrib in section.Attributes) { if (XmlNodeType.Attribute == attrib.NodeType) myAttribs.Add(attrib.Name, attrib.Value); } // Puts the section name and attributes as the first config object item. myConfigObject.Add(section.Name, myAttribs); // Gets the child element names and attributes. foreach (XmlNode child in section.ChildNodes) { if (XmlNodeType.Element == child.NodeType) { Hashtable myChildAttribs = new Hashtable(); foreach (XmlAttribute childAttrib in child.Attributes) { if (XmlNodeType.Attribute == childAttrib.NodeType) myChildAttribs.Add(childAttrib.Name, childAttrib.Value); } myConfigObject.Add(child.Name, myChildAttribs); } } return (myConfigObject); } #endregion } }
Добавление обработчика пользовательского раздела в файл конфигурации ASP.NET
Добавьте элементы sectionGroup и section в элемент configSections файла Web.config, как показано в следующем коде.
Примечание. Вложение элемента section в элемент sectionGroup не обязательно, но рекомендуется для упрощения организации данных конфигурации.
Можно добавлять объявление обработчика раздела в файл конфигурации, отличный от того, в который были добавлены пользовательские элементы конфигурации, при условии, что файл, в котором объявляется обработчик, располагается на более высоком уровне иерархии файлов конфигурации. Дополнительные сведения см. в разделе Иерархия и наследование файла конфигурации ASP.NET.
Атрибут type элемента section должен соответствовать манифесту сборки, иначе возникнет ошибка конфигурации. Файл сборки должен находиться в одном каталоге приложения ASP.NET с файлом Web.config, в котором он определяется.
<configuration> <!-- Configuration section-handler declaration area. --> <configSections> <sectionGroup name="myCustomGroup"> <section name="myCustomSection" type="MyConfigSectionHandler.MyHandler, MyCustomConfigurationHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" allowLocation="true" allowDefinition="Everywhere" /> </sectionGroup> <!-- Other <section> and <sectionGroup> elements. --> </configSections> <!-- Configuration section settings area. --> </configuration>
Добавьте пользовательские элементы конфигурации в область параметров раздела конфигурации файла Web.config.
<configuration> <!-- Configuration section-handler declaration area. --> <!-- Configuration section settings area. --> <myCustomGroup> <myCustomSection myAttrib1="Clowns"> <myChildSection myChildAttrib1="Zippy" myChildAttrib2="Michael Zawondy "/> </myCustomSection> </myCustomGroup> <!-- Other configuration settings, like <system.web> --> </configuration>
Программный доступ к данным пользовательской конфигурации
Получите экземпляр объекта пользовательской конфигурации и заполните его с помощью метода ConfigurationManager.GetSection или WebConfigurationManager.GetSection.
Страница ASPX из следующего примера работает с предыдущими примерами кода для перечисления атрибутов и дочерних элементов раздела особой конфигурации при нажатии кнопки.
Поскольку обработчик пользовательского раздела использует Hashtable как объект конфигурации, метод GetSection возвращает Hashtable.
Следующий код находится на ASPX-странице. В следующем примере приведен код для события нажатия кнопки, который находится в файле кода программной части.
Для этого примера кода требуется .NET Framework версии 1.0 или 1.1.
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="BugTest.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <html> <head> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 2003"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name=vs_defaultClientScript content="JavaScript"> <meta name=vs_targetSchema content="https://schemas.microsoft.com/intellisense/ie5"> </head> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <h1>Enumerate MyCustomSection</h1> <asp:Label ID="Label1" runat="server" Text="" /> <br /> <asp:Button ID="Button1" runat="server" Text="Get Custom Config Info" OnClick="Button1_Click" /> </form> </body> </html>
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 2003"> <meta name="CODE_LANGUAGE" Content="VB"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="https://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <h1>Enumerate MyCustomSection</h1> <asp:Label ID="Label1" runat="server" Text="" /> <br> <asp:Button ID="Button1" runat="server" Text="Get Custom Config Info" OnClick="Button1_Click" /> </form> </body> </HTML>
Следующий код для события нажатия кнопки находится в файле кода программной части, принадлежащем предыдущей ASPX-странице. Файл кода программной части использует расширение имени файла ASPX.CS или ASPX.VB, в зависимости от атрибута language объявления @Page.
[C#]
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Configuration; using System.Text; namespace BugTest { /// <summary> /// Summary description for WebForm1. /// </summary> public class WebForm1 : System.Web.UI.Page { protected System.Web.UI.WebControls.Label Label1; protected System.Web.UI.WebControls.Button Button1; private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion protected void Button1_Click(object sender, System.EventArgs e) { Hashtable config = (Hashtable)System.Configuration.ConfigurationSettings.GetConfig("myCustomGroup/myCustomSection"); StringBuilder sb = new StringBuilder(); sb.AppendFormat("Config object item count = {0}<br/><br/>", config.Count); foreach (DictionaryEntry deKey in config) { sb.AppendFormat("<h2>Attributes in the {0} Element:</h2>", deKey.Key.ToString()); Hashtable attribs = (Hashtable)deKey.Value; foreach (DictionaryEntry deAttrib in attribs) { sb.AppendFormat("{0} = {1}<br/>", deAttrib.Key.ToString(), deAttrib.Value.ToString()); } } Label1.Text = sb.ToString(); Label1.Visible = true; } } }
Imports System.Text Public Class WebForm1 Inherits System.Web.UI.Page #Region " Web Form Designer Generated Code " 'This call is required by the Web Form Designer. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() End Sub Protected WithEvents Label1 As System.Web.UI.WebControls.Label Protected WithEvents Button1 As System.Web.UI.WebControls.Button 'NOTE: The following placeholder declaration is required by ' the Web Form Designer. 'Do not delete or move it. Private designerPlaceholderDeclaration As System.Object Private Sub Page_Init(ByVal sender As System.Object, ByVal _ e As System.EventArgs) Handles MyBase.Init 'CODEGEN: This method call is required by the Web Form Designer 'Do not modify it using the code editor. InitializeComponent() End Sub #End Region Private Sub Page_Load(ByVal sender As System.Object, ByVal _ e As System.EventArgs) Handles MyBase.Load 'Put user code to initialize the page here End Sub Protected Sub Button1_Click(ByVal sender As System.Object, ByVal _ e As System.EventArgs) Handles Button1.Click Dim config As Hashtable = _ System.Configuration.ConfigurationSettings.GetConfig( _ "myCustomGroup/myCustomSection") Dim sb As New StringBuilder sb.AppendFormat("Config object item count = {0}<br/><br/>", _ config.Count) For Each deKey As DictionaryEntry In config sb.AppendFormat("<h2>Attributes in the {0} Element:</h2>", _ deKey.Key.ToString()) Dim attribs As Hashtable = deKey.Value For Each deAttrib As DictionaryEntry In attribs sb.AppendFormat("{0} = {1}<br/>", deAttrib.Key.ToString(), _ deAttrib.Value.ToString()) Next Label1.Text = sb.ToString() Label1.Visible = True Next End Sub End Class
См. также
Задачи
Основные понятия
Структура файла конфигурации ASP.NET (разделы и обработчики разделов)
Другие ресурсы
Администрирование веб-узлов ASP.NET