自定义配置节

自定义配置节(2008-12-20 11:23:41)

Custom Configuration Sections

除了预先定义好的配置节之外,还可以添加自定义配置节。可添加两种不同类型的自定义配置节:

          提供对Name/Value对集合访问的配置节,类似于appSettings

          返回任何对象类型的配置节

本节将对以上两者进行讲解。

Name/Value对

返回示例18-10,添加一个<appSettings>配置节,将包含ISBN号和标题的字符串存储其中。假设需要为多个数据库存储连接字符串,一个名为Test(用于测试目的),一个名为Content(存储产品信息)。在这种情况下,使用自定义配置节是返回name/value对的处理方法。

示例18-13显示了插入到web.config中的最终版本的代码行。添加一个返回name/value对的自定义配置节有三个步骤:

1. 确定把自定义配置节添加到哪个具体的配置文件中。正如在层次化配置一节中所描述的那样,需要确定自定义节的范围或者可见性。

向machine.config或者机器级别的web.config添加配置节,可以将它应用到机器上所有应用程序。向默认网站(c:\inetpub\wwwroot)的web.config文件添加配置节,可以将它应用到默认网站下的每个站点。向应用程序根目录下的web.config文件添加配置节,可以将它应用到整个应用程序,但不包括其他应用程序。向应用程序子目录下的web.config文件添加配置节,可以将它应用到这个子目录及其下的子目录。

2. 通过向指定配置文件的<configSections>配置节添加一行,可以声明此配置节的处理程序。它告诉ASP.NET以指定的名字和类接受此配置节,并且使用程序集文件处理此配置节。

向指定配置文件的<configSections>内添加示例18-13中的高亮显示行。如果所编辑的文件没有<configSections>标记,那么就把它们一起添加上。<configSections>必须是<configuration>配置节的第一个子配置节。

3. 向配置文件添加自定义配置节。这由示例18-13中<altDB>标记之间的高亮部分组成。这个自定义配置节包括两个项,一个命名为Test,另一个命名为Content,它们都具有自己的属性值。

示例18-13:web.config中的自定义配置节

<configSections>

   <section name="altDB"

            type="System.Configuration.DictionarySectionHandler,

                  System, Version=2.0.0.0, Culture=neutral,

                  PublicKeyToken=b77a5c561934e089" />

</configSections>

<altDB>

   <add key="Test"

        value=" SERVER=Zeus;DATABASE=Test;UID=sa;PWD=secret;" />

   <add key="Content"

        value=" SERVER=Zeus;DATABASE=Content;UID=sa;PWD=secret;" />

</altDB>

<section>配置节中的type属性用于指定System.dll程序集文件中的Dictionary- SectionHandler类。更多有关的文档,参见SDK文件,检索“Custom Elements”,并选择“Custom Element for NameValueSectionHandler”。

为了读取自定义配置节的内容,可使用ConfigurationManager类的GetSection方法。完成此功能的代码如示例18-14高亮部分所示。此处假定内容页中有两个Label控件:lblTest和lblContent。在代码隐藏文件顶部声明引入System.Collections名字空间。这样就不必在使用Hashtable对象时,必须写一个完全限定的名字。

示例18-14:读取自定义配置值

using System.Collections;    //对Hashtable必要

    protected void Page_Load(object sender, EventArgs e)

    {

       if (!IsPostBack)

       {

          string strTest;

          strTest = ((Hashtable)ConfigurationManager.

                            GetSection("altDB"))["Test"].ToString(  );

          lblTest.Text = strTest;

          lblContent.Text = ((Hashtable)ConfigurationManager.

                            GetSection("altDB"))["Content"].ToString(  );

       }

    }

示例18-14说明了两个等效的显示键值的内容的方法。一种方法是先把值赋给一个字符串,然后再把字符串赋给Label控件的Text属性。另一种方法是直接赋值给Text属性。尽管后一种更简练,但前者更多的时候有利于调试。

GetSection方法将需要获取的配置节名字作为一个参数,然后返回一个Hashtable类型的对象。使用get属性语法,在Collection中利用一个偏移量检索期望值。在C#中,此属性使用方括号来检索。

C#代码首先计算或者转换由GetSection方法返回的值,因为C#不支持后期绑定。另外,由于返回值是对象类型,所以必须使用静态ToString方法将它转换为字符串。

对象

appSettings和自定义配置节都非常有用。然而,它们都受限于只能返回Name/Value对。有时候,返回一个对象会更加有用。

例如,假设需要在数据库中执行一个标准查询。可以将查询字符串存储在appSetti- ngs标记中,然后返回该字符串并打开数据库连接。然而,更方便的方法是,将查询字符串存储在web.config文件,然后使配置系统直接返回一个DataSet。

为了实现以上内容,必须在指定配置文件中添加一个<section>标记和一个配置节,这个过程与上节所介绍的自定义配置节返回Name/Value对一样。

编辑前一个示例18-14中使用的web.config文件,添加示例18-15中高亮显示的代码。

示例18-15:在web.config中自定义返回对象的配置节

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

   <configSections>

      <section name="altDB"

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

      <sectionGroup name="system.web">

         <section name="DataSetSectionHandler"

                  type="DataSetSectionHandler,SectionHandlers" />

         </section>

      </sectionGroup>

   </configSections>

   <altDB>

      <add key="Test"

           value=" SERVER=Zeus;DATABASE=Test;UID=sa;PWD=secret;" />

      <add key="Content"

           value=" SERVER=Zeus;DATABASE=Content;UID=sa;PWD=secret;" />

   </altDB>

  <system.web>

.

.

.

    <!—自定义返回对象的配置节-->

    <DataSetSectionHandler 

         str="Select CompanyName,ContactName,City from Customers"  />

.

.

.

  </system.web>

</configuration>

在<configSections>配置节的子配置节<sectionGroup>中,为system.web组的DataSetSectionHandler创建了一个处理程序声明。这样就指定了在这个文件的system.web配置节中将有一个名为DataSetSectionHandler的自定义配置节。此外,

它还指定了处理这个配置节的类DataSetSectionHandler,而这个类包含在bin目录中的程序集文件SectionHandlers.dll中。

另外,在这个文件的<system.web>配置节中有一个名为DataSetSectionHandler配置节。该配置节仅包括一个str属性。其中的字符串是传递给数据库的SQL语句。

接下来必须创建DataSetSectionHandler类,它位于SectionHandler.cs文件中。为此,在VS2005的解决方案资源管理器中,右击应用程序根目录。选择添加新项,接着选择一个新类并命名为SectionHandlers.cs。添加示例18-16中高亮显示的代码。

示例18-16:SectionHandler.cs

using System;

using System.Data;

using System.Data.SqlClient;     //  对数据访问必要

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

public class DataSetSectionHandler : IConfigurationSectionHandler

{

   public Object Create(Object parent,

                        Object configContext,

                        System.Xml.XmlNode section)

   {

      string strSql;

      strSql = section.Attributes.Item(0).Value;

      string connectionString = "server=MyServer; uid=MyID; " +

                     "pwd=secret; database=Northwind";

      // 创建数据集命令对象和DataSet

      SqlDataAdapter da = new SqlDataAdapter(strSql,

                        connectionString);

      DataSet dsData = new DataSet(  );

      // 填充数据,设置对象

      da.Fill(dsData, "Customers");

      return dsData;

   }

}

为了与示例18-15列举的web.config中的类名匹配,类名已经更改为DataSetSec- tionHandler。该类继承自IconfigurationSectionHandler。

提示:设置连接字符串以匹配指定的数据库。服务器名和密码当然与示例18-16中显示的不同。

第9章和第10章中完整介绍了示例中数据库方面的代码。

对于一个作为配置节处理程序的类,必须实现IConfigurationSectionHandler接口。在C#中,使用类或方法和被继承的类或接口之间的冒号表示。

提示:有关完整的讨论面向对象的基本概念,例如继承、基类和接口,超出了本书范围。当前,仅需要了解接口相当于实现类必须遵守的合同。例如,接口指示实现类必须实现的方法的特征,或者指示该类必须提供哪些属性。

IConfigurationSectionHandler接口只有一个Creat方法。因此,实现类必须实现具有指定特征的Create方法。接口指定了方法的三个参数。前两个参数很少用,在这里也不做深入讨论。第三个参数是来自配置文件的XML数据。

解析XML节点,在Attributes集合中的第一项将被赋予一个字符串变量,如下所示:

strSql = section.Attributes.Item(0).Value

一旦获取了SQL字符串和硬编码的连接字符串,那么将初始化一个SqlDataAdapter对象并执行,接着填充并返回DataSet。

类在使用前必须经过编译,并将其存储在应用程序根目录下的bin目录的应用程序集缓存中。

警告:引用<section>中type属性指定的程序集,必须进行预编译,应用程序才可使用。不能仅仅把类源代码放在App_Code目录中让它在运行时自动编译。和普通的操作一样,编译要求有集合的名字,而不仅仅是它的内容。

单击开始 > Microsoft Visual Studio 2005 > Visual Studio Tools > Visual Studio 2005命令提示,打开一个DOS命令窗口。使用cd命令把当前目录设置为应用程序根目录。假定应用程序根目录已经有一个名为bin的子目录。如果没有,则新建一个。然后输入以下命令行(不要换行):

csc /t:library /out:bin\SectionHandlers.dll

   /r:system.dll,System.data.dll,System.xml.dll SectionHandlers.cs

输出目标类型被设置为类库,也就是dll。输出文件存储在bin目录中,名称为Section- Handlers.dll。同时,还引用了3个dll文件。输入源文件是SectionHandler.cs。当编译源文件时,将dll输出到bin目录中,此处的类将自动为应用程序使用。

利用自定义配置节的典型方法是,先在页面上放置一个GridView控件,然后从配置节返回数据集,并与其绑定。假设GridView控件被命名为gv,示例18-17中列出的代码将从数据库中返回数据,并将其绑定到控件。

示例18-17:返回自定义配置对象的代码隐藏文件

protected void Page_Load(object sender, EventArgs e)

{

   if (!IsPostBack)

   {

      CreateGrid(  );

   }

}

private void CreateGrid(  )

{

   DataSet dsGrid = new DataSet(  );

   dsGrid = (DataSet)ConfigurationManager.

                        GetSection("system.web/DataSetSectionHandler");

   gv.DataSource = dsGrid.Tables[0];

   gv.DataBind(  );

}

示例18-17中有趣的工作是使用CreateGrid方法来完成。该方法没有提供连接字符串和SQL查询字符串,而是调用ConfigurationManage类的GetSection方法,直接返回一个DataSet对象。GridView控件的数据源设置为DataSet对象,然后控件执行数据绑定。GetSection方法的参数是包含配置设置的配置节名称的字符串。节(system.web)与子节(DataSetSectionHandler)的名字从语法上用一个斜线隔开。

posted on 2009-05-20 18:32  冉元胜  阅读(253)  评论(0编辑  收藏  举报

导航