ASP.NET配置数据存储在名为Machine.config/Web.config的XML文本文件中,Web.config文件可以出现在ASP.NET应用程序的多个目录中。由于这些文件将应用程序配置设置与应用程序代码分开,可以方便地设置与应用程序关联。正是因为配置文件中存储着关于整个应用程序的设置,当我读一个陌生项目的源码时,经常把它作为入口。
我将从以下几点分析ASP.NET配置文件:
ASP.NET配置文件完全是基于XML的,它们可以出现在ASP.NET应用程序的多个目录中。ASP.NET配置层次结构具有以下特征:
所有的ASP.NET应用程序都从一个名为systemroot\Microsoft .NET\Framework\versionNumber\CONFIG\Machine.conf的文件继承基本设置和默认值。Machine.config文件用于服务器级的配置设置。其中某些设置不能再位于层级结构中较低的配置中被重写。ASP.NET配置层次结构的根是一个称为Web.config文件的文件,它与Machine.config文件位于同一个目录中。根Web.config文件继承Machine.config文件中的所有配置,它包括应用于所有运行某一个具体版本的.NET Framework的ASP.NET应用程序的设置。由于每个ASP.NET应用程序都从根Web.config文件那里继承默认配置,因此只需为重写默认配置的设置创建Web.config文件。配置文件层次结构的层次关系如图1所示:
Machine.config 文件包含服务器上所有Web 应用程序的ASP.NET 架构,如appSettings、connectionStrings、system.data、xmlSerializer等等配置节都是在machine.config文件中声明的。有兴趣的可以打开machine.config文件研究研究。
processModel 元素(ASP.NET 设置架构)元素配置用于服务器(包括服务器上的所有 ASP.NET 应用程序)的处理模型。因此,processModel 设置只能放在 Machine.config 文件中,而且不能被任何 Web.config 文件中的设置重写。
对 processModel 元素的更改将只有在辅助进程重新启动之后才生效,而不是像其他配置元素那样在设置更改之后立即生效。
当ASP.NET 以辅助进程隔离模式运行在Internet 信息服务 (IIS) 6.0 中时,将使用IIS 6.0 进程模型,并将忽略 Machine.config 文件的processModel 节中的设置。若要配置进程标识、循环或其他进程模型值,要使用IIS 管理器来配置应用程序的IIS 辅助进程。将IIS 6.0 配置为在IIS 5.0隔离模式中运行 ASP.NET 后,就不会运行ASP.NET 2.0。
根Web.config 文件与Machine.config 文件存储在同一个目录中,它包含大部分system.web 配置节的默认值。在这也不一一列举了,请自行查看根web.config文件和msdn。
所有的ASP.NET配置信息都驻留在.config(Machine.config、Web.config等等,本文以后都用Web.config代指所有配置文件)文件中的configuration元素中。此元素中的配置信息分为两个主区域:配置节处理程序声明区域和配置节设置区域。
注:配置文件中的标记格式是区分大小的,因为这些标记必须是格式良好的 XML,所以标记、子标记和属性是区分大小写的。标记名和属性名是Camel 大小写形式的,这意味着标记名的第一个字符是小写的,后面的任何连接单词的第一个字母是大写的。大多数情况下,字符串属性值是Pascal大小写形式的,这意味着第一个字符是大写的,后面的任何连接单词的第一个字母也是大写的。true和false例外,它们总是小写的。
配置节处理程序声明区域驻留在Web.config文件中的configSections元素内。它包含在其中声明节处理程序的ASP.NET配置section元素。可以将这些配置节处理程序声明嵌套在sectionGroup元素中,以帮助组织配置信息。通常,sectionGroup元素表示要应用配置设置的命名空间。例如,DotText中的配置节声明区域configSections的设置如下面的代码所示。
- <configSections>
- <section name="webfx.config" type="CchenSoft.Framework.Config.ConfigurationHandler, CchenSoft.Framework"/>
- <section name="BlogConfigurationSettings" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework"/>
- <section name="HandlerConfiguration" type="Dottext.Framework.Util.XmlSerializerSectionHandler, Dottext.Framework"/>
- </configSections>
从上述代码可以看出,DotText在web.config配置文件的配置节处理程序声明区域中声明了三个自定义配置节,分别为:
只需要声明配置节处理程序一次。默认ASP.NET配置节的节处理程序已在默认的Machine.config文件中进行声明。根Web.config文件和ASP.NET应用程序中的其他配置文件都自动继承在Machine.config文件中声明的配置处理程序。只有当创建用来处理自定义设置节的自定义节处理程序类时,才需要声明新的节处理程序。DotText中就定义了自定义的节处理程序,上例中的Dottext.Framework.Util.XmlSerializerSectionHandler就是。关于如何创建自定义配置节及配置节处理程序本文后面将详细介绍。
配置节设置区域位于配置节处理程序声明区域之后,它包含实际的配置设置。默认情况下,在内部或者在某个根配置文件中,对于configSections区域中的每一个section和sectionGroup元素,都会有一个指定的配置节元素。配置节元素还可以包含子元素,这些子元素与其父元素由同一个节处理程序处理。如上面DotText例子中的BlogConfigurationSettings配置节在配置节设置区域中的设置如下所示:
- <BlogConfigurationSettings type="Dottext.Framework.Configuration.BlogConfigurationSettings, Dottext.Framework">
- <Tracking enableAggBugs="true" enableWebStats="true" queueStats="false" queueStatsCount="3" enableTrackBacks="false" enablePingBacks="false" pingWeblogs="false"/>
- <EntryHandlers>
- <EntryHandler type="Dottext.Framework.EntryHandling.CommentFormatHandler, Dottext.Framework" postType="Comment" processAction="Insert" processState="PreCommit" isAsync="false"/>
- <EntryHandler type="Dottext.Framework.EntryHandling.CommentDeliveryHandler, Dottext.Framework" postType="Comment" processAction="Insert" processState="PostCommit" isAsync="true"/>
- <EntryHandler type="Dottext.Framework.EntryHandling.EntryValidationHandler, Dottext.Framework" postType="BlogPost Article" processAction="Insert Update" processState="PreCommit" isAsync="false"/>
- <!--<EntryHandler type="Dottext.Framework.EntryHandling.WeblogsPingHandler, Dottext.Framework" postType = "BlogPost" processAction ="Insert Update" processState="PostCommit" isAsync="true" />-->
- <EntryHandler type="Dottext.Framework.EntryHandling.TrackBackHandler, Dottext.Framework" postType="BlogPost Article" processAction="Insert Update" processState="PostCommit" isAsync="false"/>
- <EntryHandler type="Dottext.Framework.EntryHandling.KeyWordHandler, Dottext.Framework" postType="BlogPost Article" processAction="Insert Update" processState="PreCommit" isAsync="false"/>
- <!--<EntryHandler type="Dottext.Framework.EntryHandling.WebServicePostHandler, Dottext.Framework" postType = "BlogPost Article" processAction ="Insert" processState="PreCommit" isAsync="false" />-->
- </EntryHandlers>
- <!--
- An event is a configuration for a Dottext.Framework.ScheduledEvents.IEvent. The type property must specify a class which implements
- IEvent. You must also specify a unqiue key for each event and either a mintues interval value or timeOfDay value (both int). Interval is how often
- the event should occur. timeOfDay is the absolute time in minutes. 0 = 12:00 am, 720 = noon, 785 = 1:06 pm.
- The first "walk through" will happen 1 minute after an application restart, and then every five minutes.
- -->
- <Events>
- <!-- <Event type="Dottext.Search.SearchEngineSchedule, Dottext.Search" minutes="1" key="SearchEngine"/> -->
- <Event type="Dottext.Framework.Tracking.StatsQueueSchedule, Dottext.Framework" minutes="5" key="StatsQueue"/>
- </Events>
- <EnableMultiHost>false</EnableMultiHost>
- <!-- Checkout DottextHelper for hashing passwords -->
- <UseHashedPasswords>true</UseHashedPasswords>
- <!-- Globally control access to web services -->
- <AllowServiceAccess>true</AllowServiceAccess>
- <AllowImages>true</AllowImages>
- <!-- Globally control use of XHTML -->
- <UseXHTML>false</UseXHTML>
- <ItemCount>25</ItemCount>
- <!-- Server Time Zone -->
- <ServerTimeZone>+8</ServerTimeZone>
- <!-- 网站分类选择方式:true-单选 false-多选 -->
- <GlobalCategorySingleSelect>true</GlobalCategorySingleSelect>
- <!-- 分类级别(1或2) -->
- <CategoryDepth>1</CategoryDepth>
- <!-- Url的扩展名 -->
- <UrlFormat>aspx</UrlFormat>
- <!-- 是否允许所有用户上传文件 -->
- <EnableAllUserUpload>true</EnableAllUserUpload>
- <!-- 站点Logo图片 -->
- <Logo></Logo>
- <!-- 登录是否使用验证码 -->
- <EnableLoginAuhenCode>false</EnableLoginAuhenCode>
- <!-- 匿句用户发表评论是否使用验证码 -->
- <EnableFeedBackAuhenCode>false</EnableFeedBackAuhenCode>
- </BlogConfigurationSettings>
从上述代码可以看出,在配置节设置区域配置了一个BlogConfigurationSettings元素,他的相应类为:Dottext.Framework.Configuration.BlogConfigurationSettings。BlogConfigurationSettings元素中又包含许多子元素,如Tracking、EntryHandlers、Events、EnableMultiHost等等,而且他们其中有的还嵌有子元素。这些子元素是Dottext.Framework.Configuration.BlogConfigurationSettings中的一些属性,我们在配置文件中设置这些元素即是设置类中相应属性的值,web.config就相当于一个存储介质。这里一些配置细节看不懂也没关系,只要明白怎么设置配置节,BlogConfigurationSettings以后将会更详细的介绍。
要自定义配置节必须要创建相应的配置节处理程序,该处理程序是实现了System.Configuration.ConfigurationSection类的.NET Framework类(.NET2.0的方式,.NET1.x是System.Configuration.IConfigurationSectionHandler)。节处理程序解释并处理Web.config文件特定部分中XML配置元素中定义的设置,并根据配置设置返回适当的配置对象。处理程序类返回的配置对象可以是任何数据结构;它不限于任何基配置类或配置格式。ASP.NET使用该配置对象,以对自定义配置元素进行读取和写入。
下面代码显示了DotText中BlogConfigurationSettings节的处理程序:
- using System;
- using System.Configuration;
- using System.Xml;
- using System.Xml.Serialization;
- using System.Xml.XPath;
- namespace Dottext.Framework.Util
- {
- public class XmlSerializerSectionHandler : IConfigurationSectionHandler
- {
- public object Create(object parent, object configContext, System.Xml.XmlNode section)
- {
- XPathNavigator nav = section.CreateNavigator();
- string typename = (string) nav.Evaluate("string(@type)");
- Type t = Type.GetType(typename);
- XmlSerializer ser = new XmlSerializer(t);
- return ser.Deserialize(new XmlNodeReader(section));
- }
- }
- }
DotText中是以.NET1.X的方式,我们完全可以把它用.NET2.0的方式改写。跟.NET1.X相比从 System.Configuration.ConfigurationSection 类继承允许对节处理程序进行更精细的控制。
创建完配置节处理程序后,就可以向Web.config文件中配置节声明区域和配置节设置区域添加了,3.1、3.2就是以BlogConfigurationSettings为例讲了配置节声明区域和配置节设置区域这里就不在重复了。
方法一:获取自定义配置对象的一个实例,并使用System.Configuration.ConfigurationManager.GetSection(System.String) 方法。
对于客户端应用程序,此方法检索通过合并应用程序配置文件、本地用户配置文件和漫游配置文件而获得的最终配置文件。GetSection 方法只能访问运行时的配置信息,不能更改这些配置信息。要更改配置,可通过使用下列Open方法中的一种来对所获得的配置文件使用System.Configuration.GetSection 方法:
OpenExeConfiguration
OpenMachineConfiguration
OpenMappedExeConfiguration
方法二也是这种情况。
方法二:获取自定义配置对象的一个实例,并使用System.Web.Configuration.WebConfigurationManager.GetSection(System.String) 方法。
方法三:访问<appSettings>中的数据还可以用System.Configuration.ConfigurationManager.AppSettings属性 or System.Web.Configuration.WebConfigurationManager.AppSettings 属性
方法四:访问<connectionStrings>中的数据还可以用System.Configuration.ConfigurationManager.ConnectionStrings属性 or System.Web.Configuration.WebConfigurationManager.ConnectionStrings属性。
当然你可以用DOM来操作web.config文件读取相应的配置数据,不过此方法不推荐。
注意:1、上述方法都是在在.NET Framework 2.0 版中是新增的。
2、其实在DotText中用的是.net 1.x中System.Configuration中的上述方法、属性,如System.Configuration.ConfigurationSettings.GetConfig(sectionName)方法。这些API 现在已过时。
【1】微软公司著,《Web应用开发——ASP.NET2.0》38~39页,高等教出版社
【2】MSDN,ASP.NET 配置概述
【3】MSDN,ASP.NET 配置文件
以下三篇文章是来自codeproject:
【1】Jon Rista,Unraveling the Mysteries of .NET 2.0 Configuration
【2】Jon Rista,Decoding the Mysteries of .NET 2.0 Configuration
【3】Jon Rista,Cracking the Mysteries of .NET 2.0 Configuration
百度,Google之后发现没有人翻译,我将翻译了上述三篇文章,翻译工作已经开始,相信不久就会发布,先列出如下:
【4】揭开.NET 2.0配置之谜
【5】解码.NET 2.0配置之谜
【6】破解.NET 2.0配置之谜