The Web.config File

One of the goals of the Microsoft .NET Framework from the outset was to support XCOPY installs鈥攖hat is, the ability to install applications by copying them to a directory on your hard disk and uninstall them by deleting files and directories. Having this ability means, among other things, that managed applications don鈥檛 store configuration settings in the registry as traditional Windows applications do. Instead, they store them in text-based XML files. Web.config is the XML file in which ASP.NET applications store configuration data.

Here鈥檚 the general structure of a typical Web.config file:

<configuration>
聽聽<appSettings>
聽聽聽聽<!--聽appSettings聽values聽go聽here聽-->
聽聽</appSettings>
聽聽<system.web>
聽聽聽聽<!--聽ASP.NET聽configuration聽settings聽go聽here聽-->
聽聽</system.web>
</configuration>

This file is partitioned into two sections: an appSettings section that holds application-specific data items such as database connection strings, and a system.web section that holds ASP.NET configuration settings. These sections aren鈥檛 the only ones that can appear in a Web.config file, but they are the most common. Web.config鈥檚 architecture is extensible, enabling developers to define custom sections when circumstances warrant.

<appSettings>

The appSettings section of Web.config holds application-specific values (strings) that are keyed by other strings. Its purpose is to parameterize an application鈥檚 behavior, and to allow that behavior to be modified without changing any source code.

Suppose, for example, that you coded the following statements into a Page_Load handler:

SqlDataAdapter聽adapter聽=聽new聽SqlDataAdapter
聽聽聽聽("select聽*聽from聽titles聽where聽price聽!=聽0",
聽聽聽聽 "server=hawkeye;database=pubs;uid=sa;pwd=");
DataSet聽ds聽=聽new聽DataSet聽();
adapter.Fill聽(ds);

The only problem with this code is that if the database connection string changes鈥攊f the database moves to another machine, for example, or if the user name or password changes鈥攜ou have to modify the code to update the database connection string. If you work in a big company, code modifications probably trigger a mountain of paperwork and require all or part of the application to be retested and reapproved.

A better solution to encoding connection strings and other data that鈥檚 subject to change over the lifetime of an application is to put it in the appSettings section of Web.config. The following Web.config file declares a connection string and assigns it the name 鈥淢yConnectionString鈥?

<configuration>
聽聽<appSettings>
聽聽聽聽<add聽key="MyConnectionString"
聽聽聽聽聽聽value="server=hawkeye;database=pubs;uid=sa;pwd=" />
聽聽</appSettings>
</configuration>

Page_Load can be rewritten to extract the connection string from Web.config:

string聽conn聽=聽ConfigurationSettings.AppSettings["MyConnectionString"];
SqlDataAdapter聽adapter聽=聽new聽SqlDataAdapter
聽聽聽聽("select聽*聽from聽titles聽where聽price聽!=聽0",聽conn);
DataSet聽ds聽=聽new聽DataSet聽();
adapter.Fill聽(ds);

AppSettings is a static method belonging to the ConfigurationSettings class in the FCL鈥檚 System.Configuration namespace. It retrieves values by name from the appSettings section of Web.config. The benefit to doing it this way? Storing the database connection string in Web.config enables you to change it without touching any actual program code. It鈥檚 analogous to storing program settings in the registry in a Windows application, and it comes with all the perks but none of the drawbacks.

<system.web>

The system.web section of Web.config holds configuration settings used by ASP.NET. Its content is categorized by subsections. Although the type and number of subsections that can appear is technically unlimited鈥攁s developers are free to define custom subsections鈥攖he ones listed in the following table are supported by default and can be used without writing custom configuration handlers.

<system.web> Subsections聽

Section Name

Description

authentication

Sets the authentication mode and specifies settings for the mode selected

authorization

Specifies who is allowed to access resources in this directory and its subdirectories

browserCaps

Maps user-agent data to browser capabilities

clientTarget

Maps user-agent data to browser types

compilation

Specifies run-time compilation settings such as whether executables should be compiled with debug symbols, maps file name extensions and Language attributes to compilers, and identifies the assemblies that ASP.NET links to

customErrors

Enables the use of custom error pages and specifies how errors should be reported on clients and servers

httpRuntime

Specifies request time-outs and other settings used by the ASP.NET runtime

globalization

Specifies character encodings for requests and responses

httpHandlers

Maps URLs to HTTP handlers (for example, maps requests for ASPX files to System.Web.UI.PageHandlerFactory)

httpModules

Identifies HTTP modules called in response to HTTP requests

identity

Controls the identity that ASP.NET assigns to individual requests

machineKey

Specifies encryption and validation settings (for example, the key and algorithm used to encrypt authentication cookies)

pages

Specifies page-level configuration settings such as whether output buffering, session state, and view state are enabled

processModel

Specifies configuration settings for ASP.NET worker processes

securityPolicy

Maps trust levels to CONFIG files containing security policies

sessionState

Specifies session state settings (for example, where session state is stored)

trace

Enables and disables tracing and specifies trace settings

trust

Specifies the code access security trust level

webControls

Identifies the location on the server of client scripts used by ASP.NET Web controls

webServices

Contains Web service settings

Here鈥檚 a sample Web.config file that enables tracing. Drop it in the application root, and ASP.NET appends useful trace information (including strings written to trace output with Trace.Write and Trace.Warn) to the application鈥檚 pages:

<configuration>
聽聽<system.web>
聽聽聽聽<trace聽enabled="true" />
聽聽</system.web>
</configuration>

Here鈥檚 another Web.config file that enables tracing, instructs ASP.NET to compile debug executables, moves session state to a back-end SQL Server database (a topic you鈥檒l learn about later in this chapter), tells ASP.NET to assume code found in the application鈥檚 files is written in C# unless otherwise noted, and enables view state validation by appending hashes to view state values round-tripped to the client:

<configuration>
聽聽<system.web>
聽聽聽聽<trace聽enabled="true" />
聽聽聽聽<sessionState
聽聽聽聽聽聽mode="SQLServer"
聽聽聽聽聽聽sqlConnectionString="server=localhost;uid=sa;pwd="
聽聽聽聽/>
聽聽聽聽<compilation聽debug="true" defaultLanguage="c#" />
聽聽聽聽<pages聽enableViewStateMac="true" />
聽聽</system.web>
</configuration>

Because element and attribute names in XML are case-sensitive, statements in Web.config are case-sensitive, too. For example, the statement

<Pages聽enableviewstatemac="true" />

isn鈥檛 valid and will generate an error message. Even attribute values are case-sensitive. The statement

<pages聽enableViewStateMac="True" />

is invalid because the T in 鈥渢rue鈥?must be lowercase.

If you鈥檙e going to use Web.config files to affect configuration changes, knowing what the default settings are so that you know what needs changing and what doesn鈥檛 is helpful. Default configuration settings are defined in Machine.config, which is located in the Windows (or Winnt) directory鈥檚 Microsoft.NET\Framework\vn.n.nnnn\Config directory. For example, tracing is disabled by default as the result of the following statement in Machine.config:

<trace聽enabled="false" ...聽/>

Because Machine.config holds configuration settings for all managed applications on the host machine, modifying Machine.config changes the defaults machine-wide. If you want tracing to be enabled by default, simply edit the statement above to read

<trace聽enabled="true" ...聽/>

Settings in Web.config, by contrast, apply only to local applications.

The Microsoft .NET SDK documents most of the elements and attributes that Web.config supports out of the box. But the ultimate source of reference is Machine.config. It鈥檚 sprinkled with comments placed there by Microsoft developers documenting the options available and the syntax of individual elements. If you have a question about Web.config and can鈥檛 find an answer in the documentation, turn to Machine.config; chances are it鈥檒l have the answer you鈥檙e looking for.

Configuration Inheritance

One of the hallmarks of Web.config files is configuration inheritance. Simply put, configuration inheritance means that settings specified in a Web.config file pertain to all files in the host directory (the one that holds Web.config) and its subdirectories. In other words, if you put the following Web.config file in wwwroot:

<configuration>
聽聽<system.web>
聽聽聽聽<compilation聽defaultLanguage="c#" />
聽聽</system.web>
</configuration>

the default language for subdirectories stemming from wwwroot is also C#. Why? Because subdirectories inherit configuration settings from parent directories.

Subdirectories inherit their parents鈥?configuration settings, but they can override those settings with Web.config files of their own. As an example, consider the directory structure in Figure 9-3. The top-level directory contains a Web.config file that sets the default language to C#. One of its subdirectories holds a Web.config file that sets the default language to Visual Basic .NET; the other subdirectory has no Web.config file. In this case, C# is the default language in wwwroot and wwwroot\CSharpFiles, but Visual Basic .NET is the default language in wwwroot\VBFiles. If the subdirectories contained subdirectories of their own, those subdirectories too would inherit settings from their parents. Specifically, subdirectories underneath wwwroot\CSharpFiles would default to C# and subdirectories beneath wwwroot\VBFiles would default to Visual Basic .NET. Those settings, of course, could be overridden by placing Web.config files in the subdirectory鈥檚 subdirectories.

Figure 9-3
Configuration inheritance.

Machine.config sits at the top of the inheritance hierarchy. Default settings for the .NET Framework, ASP.NET included, are defined in Machine.config and are inherited by all framework applications. That鈥檚 why settings in Machine.config apply to every managed application on the machine, and why you can look to Machine.config to determine what a server鈥檚 default settings are. When you drop a Web.config file into a local directory, all you鈥檙e really doing is overriding settings inherited from Machine.config.