Although you learned about the structure of ASP.NET Web applications earlier in the book, it is worthwhile to review this information. Understanding the structure of an ASP.NET application will make the deployment process smoother, and can help prevent unexpected errors and problems in your deployed applications.
Each ASP.NET application needs to have a corresponding IIS application root to function properly. During development using Visual Studio .NET, this process is handled for you automatically. Each time you create a new ASP.NET project in Visual Studio .NET, part of the project-creation process undertaken by the IDE is creating the folder and making it an IIS application root. The application root provides the boundary for the application. The physical file system directory that maps to the application root is the location where the root Web.config file for the application, as well as the application’s bin directory (which contains all managed assemblies related to the application) and the Global.asax file (if you choose to use one), are deployed. If the IIS directory that is the root of the application is not configured as an application root, certain configuration settings can fail, and the assemblies located in the bin directory (if present) will not be loaded.
Microsoft Windows XP offers multiple views of the Control Panel. The default view is called category view and the optional view is called the classic view. For this chapter, all instructions will be for the classic view. To switch from category view to classic view, click on Switch To Classic View on the left side of the Control Panel.
To determine if a directory in IIS has been configured as an application, complete the following steps.
Open the Internet Information Services MMC snap-in (called Internet Services Manager in Microsoft Windows 2000) by clicking Start, Control Panel, Administrative tools, and then selecting Internet Information Services. (In Windows 2000, click Start, Programs, Administrative Tools, and then Internet Services Manager.) Note that you must be logged in as an administrator (or use the Run As feature to run the snap-in) to access the full functionality of this tool.
Navigate to the directory whose configuration you want to check by expanding the Web site containing it and expanding other nodes as necessary. If the directory is configured as an application root, it will show an icon of a black globe in a gray box. If the directory is not configured as an application, it will either show a folder icon (for content that resides directly within the path of the parent application root) or a folder icon with a small globe (for content that resides elsewhere in the file system). The following illustration shows examples of these icons:
If the directory is not configured as an application, you can create an application root at this level. Right-click the directory, select Properties, and then click the Create button in the Directory tab (or Virtual Directory tab) of the Properties dialog box. The Properties dialog box for the Chapter_13 directory is shown in the illustration on the next page. (Note that the dialog for IIS 6.0 is slightly different in the options it presents.)
Click OK to update the directory with the new setting.
The directory should now show the icon for an application root, as shown in the following illustration. This step should not be necessary for directories that are the root of a Visual Studio .NET Web Application project, since Visual Studio .NET configures the root directory of this project type as an Application in IIS automatically.
As you can see in these figures, IIS application roots can be nested one beneath the other. However, each application root defines its own application boundary. One advantage of this is that it allows you to partition your application as necessary. For example, you can provide customized configuration settings or use different versions of a private assembly with different parts of your application. The most important thing to remember, however, is that the application root is where the bin directory and Global.asax and Web.config files should be located.
An important distinction to make when discussing deployment is between the physical path of an application (that is, the application’s location within the file system of its server) and the URL of the application. This distinction becomes important when discussing the array of different tools available for deployment, some of which (such as the DOS XCOPY command) use file or network paths, and some of which (such as FTP and WebDAV) use URLs.
There is only a single file path for a given application root in IIS. However, more than one directory in IIS can map to a single physical directory in the file system. This allows you to set up URLs for both public and private access to a given application, with different IIS settings for each. If more than one IIS application root points to the same physical directory in the file system, each IIS application root will have its own IIS-specific settings. It is important to note, however, that if the physical directory contains ASP.NET-specific configuration and start-up files (Web.config and Global.asax), both IIS applications will share the settings in these files.
One important caveat regarding this sharing is that when a subfolder containing a Web.config file or a Global.asax file is defined as an application root in one of the IIS applications, it’s not configured as an application root in the second IIS application. In the first case, shown in the illustration on the next page, requests to the Chapter_13 subfolder of the aspnetsbs folder will use the Global.asax file contained in the Chapter_13 folder for start-up code.
In the second case, shown in the following illustration, the Global.asax file contained within this subfolder will be ignored, since the folder is not configured as an application in IIS.
You should also note that certain settings in the Web.config file are applicable only at the application root level. For example, if the Web.config file contained in the Chapter_13 folder shown in the preceding illustration contains an <authentication> section, a configuration error will result because this section can be defined only at the machine (machine.config) or application root level.
The URL for a specific application root in IIS is a product of the domain name (if any) associated with the IP address that is assigned to the IIS Web site, plus the folder hierarchy between the IIS Web site and the application root. Thus, in the previous illustration, where the aspnetsbs application root resides under the default Web site, the URL to reach the Chapter_13 directory would be either http://localhost/aspnetsbs/Chapter_13/ or http://servername/aspnetsbs/Chapter_13/.
This works if you request the URL from the server containing the application, because requests for localhost or servername (where servername represents the name of the Web server containing the application) are automatically directed to the default Web site. If you wanted to make the content of the Chapter_13 application root available on the Internet, you’d need to create a new IIS Web site, assign a publicly available IP address on the machine to the Web site, and then create (or have a DNS provider create) a DNS entry that maps your chosen domain name (for example, http://www.aspnetsbs.com/) to that IP address. Then you would create a new application root under the new Web site that maps to the Chapter_13 directory in the file system. You could access this application from the Internet using the URL http://www.aspnetsbs.com/Chapter_13/.
Note that if you have directory browsing disabled (the default), you will need to set a default document in the Documents tab of the Properties dialog box for the directory, in case the user does not enter a document name. The name of the default document should match the name of a page that exists in the directory. This will allow access to content using a URL that does not contain a document name, such as the preceding URLs. Otherwise, the name of the desired file must be appended, or an error will occur.
One of the challenges of deploying most non-trivial Web applications in classic ASP is figuring out where to store application-specific configuration information. Classic ASP allowed for a number of approaches, including using custom keys in the system registry, storing configuration information in a back-end database, reading configuration settings from a custom configuration file, and building settings into components. Each approach has its own set of drawbacks that makes it less than ideal.
For example, storing configuration information in the system registry makes that information relatively secure (particularly if proper registry security procedures are followed).
However, adding that information to the registry or modifying it from a remote machine can be difficult, if not impossible, because of permission settings designed to protect the registry from remote tampering. Additionally, accessing settings within the registry can be expensive from a performance standpoint.
Neither storing configuration information in a back-end database nor storing that information in custom configuration files provides easily repeatable procedures for multiple applications. The database solution requires that changes to the Web application and the configuration database be synchronized so that users always get the correct information. The custom configuration file solution requires building logic into pages or components to parse and cache the application settings, while periodically checking to see if settings have been modified, and loading the new settings if they have been.
To simplify this situation, ASP.NET provides a special section of the Web.config and machine.config files called appSettings, which allows you to store application-specific configuration settings as a set of key/value pairs.
<appSettings> <add key="myConfigKey" value="myConfigValue" /> </appSettings>
When your application starts up, ASP.NET caches the values of the appSettings section in a string collection called ConfigurationSettings.AppSettings. You can access these settings by passing the desired key to this collection, as shown here:
Label1.Text = ConfigurationSettings.AppSettings["myConfigKey"];
In addition to automatically loading and caching these values for you at application start-up, ASP.NET monitors the Web.config file(s) for changes and dynamically reloads the contents of the appSettings configuration section if changes are detected.
The practice files for this chapter include an example of using the appSettings configuration section to store and display a simple text value. See the Web.config file for an example of storing the value; see the AppSettings.aspx file for an example of retrieving and displaying the value.
While appSettings provides a storage location for application-specific configuration settings that is almost ideal in its ease of use and performance, note that since the values are stored as plain text in a file in the Web space, some security risk is associated with this approach.
If a vulnerability in the Web server allowed access to the Web.config file, any sensitive information stored in appSettings could be compromised. For this reason, never store sensitive information, such as usernames, passwords, or credit card or account numbers, in the appSettings section of Web.config. For items of medium sensitivity, one solution is to add the items to the appSettings of the machine.config file, which is not located within the Web space and thus harder to compromise. Keep in mind, however, that the appSettings stored in Machine.config are available to every application on the server, unless they are locked down using the <location> tag. (See Chapter 5 for more information on locking down configuration settings.)
For more information on storing sensitive information in Web applications, see the “Storing Secrets” section of the following security article on the MSDN Web site: