Like the machine.config file, Web.config is XML based. This means that each Web.config file is made up of tags and attributes, similar to HTML. (XML is a markup language based on Structured Generalized Markup Language, or SGML, the same language HTML is based on.) Unlike machine.config, however, most Web.config files will not contain elements for every available configuration setting. In fact, an ASP.NET application doesn’t actually require a Web.config file in order to function. If Web.config is omitted from an application, it simply inherits its configuration settings from the master configuration file, machine.config.
A Web.config file has the following basic structure:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <elementName1> <childElementName attributeName1=valu attributeName2=valu attributeNameN=value /> </elementName1> <elementName2  attributeName1=valu attributeName2=valu attributeNameN=value> </elementName2> <elementNameN  attributeName1=valu attributeName2=valu attributeNameN=value /> </system.web> </configuration>
Each Web.config file should begin with the standard XML declaration, though it will work without it. The file also contains opening and closing <configuration> tags. Nested within those tags are the opening and closing <system.web> tags, indicating that the content within is ASP.NET-specific configuration information. This configuration information is supplied in tags referred to as elements. Each element consists of an opening and closing tag. Any attributes are defined within the opening tag and any child elements are defined between the opening and closing tags. If an element doesn’t have child elements, you can omit the closing tag by adding the forward slash (/) character at the end of the opening tag. (This is standard XML syntax.) You’ll see this format in action later in this chapter, as well as in Appendix B.
Many developers found it frustrating when Microsoft Visual InterDev 6 reformatted code according to its preferred style. That feature was difficult, if not impossible, to turn off. In Microsoft Visual Studio .NET, not only can you control how code is validated and formatted, but in most cases you can also turn off autoformatting entirely.
To view or change the formatting settings for a given language, from the Tools menu select Options, and then click the Text Editor folder. Click the folder for the language of your choice. Note that for some languages, the formatting settings appear on more than one option page. For example, HTML/XML formatting options are set on the Format page, the HTML Specific page, and the XML Specific page, all under the HTML/XML folder.
At the time of this writing, the Visual Studio .NET environment’s tools for editing configuration files are limited to syntax coloring, XML validation, and code formatting. Because the ASP.NET configuration files are XML based, you can also use your favorite XML editor (or text editor) to edit them.
Either open the Chapter_05 project from the practice files, or create a new project named Chapter_05, using the steps you learned in Chapter 2.
Locate the Web.config file in the Solution Explorer window and double-click it.
The Web.config file will be opened for editing using the Visual Studio .NET XML editor, as shown in the illustration on the following page. We’ll look at examples of editing this file later in the chapter, so you might want to leave it open.
In addition to syntax coloring and validation, Visual Studio .NET provides a default Web.config file for each new Web application project that you create. This default file contains the most commonly used elements, as well as comments that explain the available options for each element, as shown in the previous illustration. The default Web.config file is useful as a template for any additional Web.config files you want to place in subfolders of your Web application. Keep in mind that when you’re using configuration files in subfolders of your application, it’s a good idea to include only the elements for the configuration settings from the parent file that you want to override. This helps prevent the accidental overriding of a configuration setting, and it might help reduce parsing overhead for the configuration of your application.
Not only does the master configuration file, machine.config, contain the default settings for all ASP.NET applications on the machine, but it also has machine- wide configuration settings. Be cautious when editing this file. It is prudent to create a backup copy of the file before you edit it. Also keep in mind that unless you’re the only one who uses the machine on which you’re developing, any changes that you make to machine.config will also affect other ASP.NET developers using the machine. Unless you enjoy dealing with unhappy colleagues, you should discuss any proposed changes with them first.
At the time of this writing, no GUI tools are available for editing the Web.config files and modifying configuration settings. Fortunately, the default Web.config file created by Visual Studio .NET Web Applications contains comments specific to the most commonly used settings. These comments provide guidance for using the available parameters for a given configuration element (although not all configuration elements appear in the default Web.config file). Complete documentation is provided in the Visual Basic .NET help files installed by default with Visual Studio .NET.
In addition to the comments found in the Web.config file generated by Visual Studio .NET, the machine.config file contains comments with specific settings for certain elements. These comments can guide you when you make configuration changes. Appendix B describes the available ASP.NET configuration elements and their settings.
To illustrate how to configure ASP.NET applications, let’s look at two examples. The first example shows how to use the <customErrors> element to define a custom page to handle 404-Not Found errors when a user requests a page that doesn’t exist in your application. The second example shows how to use the <httpModules> element to remove the SessionStateModule for applications that do not use session state.
Create a new project named Chapter_05 if you didn’t do so in the previous exercise.
Add a new Web Form to the project. Name the file fnf.aspx.
Add a Label control to the page, as shown in the following illustration.
The code-behind module for fnf.aspx will be displayed in the code editor window, with the cursor automatically moved to the Page_Load event handler. Note that a local declaration (highlighted in the following illustration) has been added to the code-behind for the Label control to allow programmatic access to the control by its name, Label1:
protected System.Web.UI.WebControls.Label Label1;
Replace the placeholder comment in the Page_Load event handler with the code in the illustration on the following page. (The ASP.NET runtime adds the aspxerrorpath query string variable automatically and populates it with the path requested by the user when redirecting from an HTTP error.)
Save fnf.aspx and fnf.aspx.vb.
If it is not already open, open Web.config by double-clicking it in Solution Explorer.
Modify the <customErrors> element to look like the code in the illustration on the following page, and then save the file. (The <error> child element maps the HTTP 404 error code to redirect to the Web Form created in a previous step.)
From the Build menu, select Build Chapter_05 to build the project.
Right-click WebForm1.aspx (the default Web Form added to the project when it was created), select Browse With, then select Microsoft Internet Explorer from the Browser List window, and then click Browse, as shown in the following illustration. (This will open the page in a separate browser window, rather than one embedded in the IDE.)
The page will redirect to fnf.aspx, and display a message similar to the following. (The path can vary depending on how you set up your project.)
You can use this technique to provide useful error messages to your users, as in this example, or you can expand on it by using the redirect page to send a notification to an administrator of the error, using the Microsoft .NET Framework’s SmtpMail class. (You’ll learn how to use the SmtpMail class in Chapter 8.)
HttpModules are classes that participate in the processing of every request made to an application. The built-in HttpModules in ASP.NET include SessionStateModule and OutputCacheModule, as well as modules for each of the built-in authentication methods in ASP.NET. These modules are added by default in machine.config using the <httpModules> element. You can use the <httpModules> element in your Web.config file to remove any of these modules that you’re not using, or to add additional httpModules (including your own custom httpModules).
Open Web.config (if it isn’t already open) by double-clicking it in Solution Explorer.
Just under the <system.web> tag, add an <httpModules> element to the file, as shown in the illustration on the following page:
Change the mode attribute of the <customErrors> element to Off. (You’ll see why in a few steps.)
Double-click the file WebForm1.aspx in Solution Explorer, and then double-click the page in the editor.
The code-behind module for WebForm1.aspx will be displayed for editing, as shown in the following illustration.
Session["foo"] = "Bar";
Save all open files and build the project.
In Solution Explorer, right-click WebForm1.aspx, and then select Browse With to browse the page in a separate browser window. (Select Internet Explorer as you did in the previous exercise.)
The request will result in an exception, because you’ve removed the SessionStateModule from the application. Had you not modified the <customErrors> element in Step 3, you would see a generic error message instead of the detailed message shown on the next page.
Once you’ve created the application-level Web.config file (or Visual Studio .NET has created it for you when you created a project) and modified its settings to suit your needs, you might want to modify the configuration settings for a subset of your application. For example, you might want to apply more stringent security requirements to a particular set of files. In ASP.NET, it’s simple to override the application-level configuration settings—it takes only three steps.
Create a subfolder in your application and place in it the content that the new configuration settings will apply to.
Create a new Web.config file in the new folder.
Add the configuration settings you want to override to the new Web.config file.
Include only the configuration elements that you want to override in the new Web.config file. All other settings are inherited from the Web.config file of the parent folder or, if that file doesn’t exist (or doesn’t contain settings for all available configuration elements), from the machine.config file for your Web server.
Clearly, there will be times when Web developers or administrators want to configure settings for an entire server or site and prevent those settings from being overridden. This might be desirable in the case of authentication and authorization settings, or to prevent the overriding of security policy settings. Fortunately, ASP.NET provides the <location> tag for just this purpose.
The <location> tag has two attributes: path and allowOverride. The path attribute allows you to specify a path to which the settings within the <location> tag pair apply. This attribute allows you to use a single configuration file, such as machine.config, to apply configuration settings for multiple applications, virtual directories, or files on the same machine. Some settings can be set only at the machine or application level. If you attempt to apply these settings at the directory or file level using the path attribute, an exception will be thrown.
When you’re using the path attribute to apply configuration settings to multiple locations, use comments to clarify the intended purpose of each set of <location> tags. In shared server environments, use comments to indicate the person responsible for a given set of configuration settings.
The allowOverride attribute determines whether the settings within the <location> tag pair can be overridden by settings applied in a child configuration file. If this attribute is set to False, any attempt to change the specified setting in a child configuration file will result in an exception.
Open the configuration file (Web.config or machine.config) from which you want to lock down a particular setting.
Add the following code within the <configuration> and </configuration> tags:
<location path="path to lock down" allowOverride="false"> <system.web> <!-- Configuration elements to be locked down --> </system.web> </location>
The path attribute should be the name of a subdirectory. The elements that appear inside the system.web tags will be treated as if they were in the Web.config file in that subdirectory.
Starting with ASP.NET 1.1, ASP.NET applications can be configured to run using a specific version of the .NET Framework, as long as that version is installed on the target machine. This is referred to as side-by-side execution. Why is this important? Because as new versions of the .NET Framework are released, there might be times when security or other concerns require that a later version be incompatible with previous versions. Side-by-side execution allows you to install multiple versions of the .NET Framework on a single machine, and then to configure each application to use the desired version, for compatibility or other reasons.
For executable programs written for the .NET Framework, configuring an application to run against a specific version of the framework is accomplished using the <assemblyBinding> configuration element (see the MSDN documentation for Visual Studio .NET for more information on side-by-side execution and the <assemblyBinding> element). For ASP.NET applications, you must modify the application mapping in IIS for the desired application. By default, applications created after installing version 1.1 of the .NET Framework will be mapped to ASP.NET 1.1. The following steps show how to configure an application to run against version 1.0 of ASP.NET.
While logged in as an administrator (or using the Run As feature to run using an administrative account), open a command line window, and navigate to the directory containing the version of the framework you want to run against, in this case, C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705 (change the drive letter and/or the name of the Windows directory to match your setup).
Run the ASP.NET Registration tool (aspnet_regiis.exe) using the following command line, substituting the desired application path for W3SVC/1/ROOT/TestWeb (W3SVC/1/ROOT/ represents the root of the first Web site configured in IIS, while TestWeb represents the application with that name in that Web site):
aspnet_regiis.exe -s W3SVC/1/ROOT/TestWeb
The path to aspnet_regiis.exe may not be registered in the Path environment variable on your machine, in which case you will need to either include the full path to the executable (you can locate it using the Windows search tool) or follow the instructions in Appendix C for adding the path to aspnet_regiis.exe to the Path environment variable.
To verify that the configuration was successful, open the IIS Manager, navigate to the application in question, right-click the application and select Properties, and then click the Configuration button. In the Mappings tab, scroll down to the .aspx extension, and hover the mouse over the Executable Path column for that extension. The version number in the tooltip that displays the path to the executable should look like the one in the following illustration (from the Windows Server 2003 version of the IIS Manager).
In Windows Server 2003 with Internet Information Services 6.0, a new process model is used in which a number of applications are run in one or more processes using an application pool designation. Applications using different application pool designations never share the same process. The reason this is important is that if you try to configure an application to run against a different version of ASP.NET than other applications in the same application pool, you might get an error message similar to the following in the Event Log:
It is not possible to run different versions of ASP.NET in the same IIS process. Please use the IIS Administration Tool to reconfigure your server to run the application in a separate process.
To resolve this issue, you must create a new application pool and assign it to the application that is to be configured differently from the others in the existing pool.