20.3 Configuring the Application

ASP.NET provides a very powerful and flexible means of configuring applications. This configuration is accomplished using text-based XML configuration files. The server-wide configuration file is called machine.config, described in Section 20-3.1. This is supplemented by a number of application-specific configuration files, all called web.config, located in the application virtual root directory and subdirectories.

This configuration scheme offers the following features:

  • The XML files that control the configuration can be edited with any standard text editor or XML parser. It is not necessary to use the IIS control panel, as was the case with classic ASP.

  • Since the configuration is accomplished with text files, it is easy to administer remotely. Files can be created or edited remotely, then copied into place via FTP or remote network access by anyone with suitable security clearance. There is no need for a person to be physically present at the server machine hosting the application in order to perform configuration chores, as is the case with classic ASP.

  • The system is hierarchical. Each application inherits a baseline configuration from machine.config, located on the server. The web.config files then apply successive configuration attributes and parameters as the application directory tree structure is traversed. This will be explained in detail in Section 20-3.1.

  • A corollary of the hierarchical nature of the system is that each application can have its own independent configuration. It is not necessary for all applications to share a server-wide configuration, as with classic ASP.

  • The system is extensible. The baseline system provides configurability to a large number of standard program areas. In addition, you can add custom parameters, attributes, and section handlers, as required by your application. This too will be explained in detail later.

  • It is possible to modify the configuration of a running application without stopping and restarting either the application or the server. The changes automatically and immediately apply themselves to any new client requests. Any clients online at the time the changes are made will not be aware that changes are being made, other than perhaps a slight delay for the first request made after the change is put in place.

  • The configuration settings for each unique URL are computed at application runtime, using all the hierarchical web.config files. These configuration settings are then cached so that requests to each URL can retrieve the configuration settings in a performant manner. ASP.NET automatically detects if any configuration files anywhere in the hierarchy are modified, and recomputes and recaches the configuration settings accordingly.

  • Configuration files are hidden from browser access. If a browser directly requests a configuration file in a URL, an HTTP access error 403 (forbidden) will be returned. This is the same behavior seen if the global.asax file is requested directly by a browser.

20.3.1 Hierarchical Configuration

The configuration system is hierarchical, just as a directory tree structure is hierarchical. The file at the very top of the hierarchy is a file called machine.config. This file is contained in the subdirectory:

c:\winnt\Microsoft.NET\Framework\version number\CONFIG

where version number will be replaced with the version of the .NET runtime installed on your machine, such as v1.1.4322.

All the other configuration files are called web.config. These files are optional: if there are none anywhere in an application virtual directory or its subdirectories, then the configuration settings contained in machine.config will apply to your application without any modifications.

Each directory and subdirectory contained in the application can have at most a single web.config file. The configuration settings contained in a specific instance of web.config apply to the directory in which it is contained and to all its child directories. If a specific instance of web.config contains a setting that is in conflict with a setting higher up in the configuration hierarchy (i.e., in a parent directory or machine.config), then the lower-level setting will override and apply to its own directory and all child subdirectories below it (unless, of course, any of those child subdirectories have their own copies of web.config, which will further override the settings).

So, for example, consider the directory structure shown in Figure 20-5. The virtual root of the web site is called MyWebSite, corresponding to the physical directory c:\inetpub\wwwroot\MyWebSite. Underneath the virtual root are two child subdirectories, each of which has additional child subdirectories. The URL for this web site would be www.MyWebSite.com (assuming that the domain name MyWebSite.com was registered to the IP address assigned to the server).

Figure 20-5. Hierarchical configuration
figs/pan2_2005.gif

If there were no web.config files in any of these directories, then all the configuration would come directly from machine.config. If there is a version of web.config in the directory MyWebSite, then any settings it contains would apply to the entire application (but only to that application), including all the subdirectories beneath it. If there were another version of web.config in the MembersOnly directory, then its configuration settings would apply to the MembersOnly directory and its subdirectories, but not to PublicStuff. If any of the settings in web.config in MembersOnly conflicted with those in MyWebSite, then the settings in MembersOnly would override those in MyWebSite.

It is important to note that the hierarchical nature of the configuration files is based on application virtual directories. Refer again to Figure 20-5. The only virtual directory defined so far for that application is MyWebSite. However, suppose another virtual directory, MyPublicWebSite, were defined, corresponding to c:\inetpub\wwwroot\MyWebSite\PublicStuff. The URL for this application would be www.MyPublicWebSite.com. This application would inherit the configuration settings from machine.config, but not from c:\inetpub\wwwroot\MyWebSite\web.config. Although c:\inetpub\wwwroot\MyWebSite is the physical parent directory of c:\inetpub\wwwroot\MyWebSite\PublicStuff, it is not the virtual parent. In fact, c:\inetpub\wwwroot\MyWebSite\PublicStuff is a virtual root and does not have a parent. Configuration settings inherit from virtual parents, not physical parents.

20.3.2 Format

The configuration files, machine.config and web.config, are XML files. As such they must be well-formed. (For a description of well-formed XML, see the sidebar "Well-Formed HTML" in Chapter 4.) Specifically, these files consist of a nested hierarchy of XML tags. All opening tags must have the corresponding closing tag or be self-closing (with a trailing / character just inside the closing angle bracket). The tag pairs must not be interleaved with other tag pairs. Subtags may be nested inside tag pairs. Both tags and subtags may have attributes and attribute values. All of these elements are case-sensitive.

Typically, tag and attribute names consist of one or more words run together. Tag and attribute names are camel-cased. Attribute values are usually Pascal-cased.

Camel-casing means that all the characters are lowercase, including the first character, except the first character of each run-on word after the first. Examples of camel-casing are appSettings, configSections, section, and sessionState.

Pascal-casing is the same as camel-casing except that the first character of the name is also upper case. Examples of Pascal-casing are SortByTime, InProc, and StateServer.

The word usually is used because there are exceptions:

  • true and false are always lowercase.

  • Literal strings do not adhere to either camel- or Pascal-casing. A database connection string may be specified as: SERVER=Zeus;DATABASE=Pubs;UID=sa;PWD=secret;

  • If the value is the name of another tag in a configuration file, then it will be camel-cased.

The first line in the configuration file declares the file to be an XML file, with attributes specifying the version of the XML specification to which the file adheres and the character encoding used. Here is a typical XML declaration line:

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

The character encoding specified here is UTF-8, which is a superset of ASCII. The character encoding parameter may be omitted if, and only if, the XML document is written in either UTF-8 or UTF-32. Therefore, if the XML file is written in pure ASCII, the encoding parameter may be omitted, although including the attribute contributes to self-documentation.

The next line in the configuration files is the opening <configuration> tag:

<configuration>

The entire contents of the configuration file, except the initial XML declaration, is contained between the opening <configuration> tag and the closing </configuration> tag.

Comments can be contained within the file using the standard XML (and HTML) format:

<!-- Your comments here -->

Within the <configuration> tags are two broad categories of entries. They are, in the order in which they appear in the configuration files:

  • Configuration section handler declarations

  • Configuration sections

20.3.3 Configuration Section Handler Declarations

The handler declarations are contained between an opening <configSections> tag and a closing </configSections> tag. Each handler declaration specifies the name of a configuration section, contained elsewhere in the file that provides specific configuration data. Each declaration also contains the name of the .NET class that will process the configuration data in that section.

This terminology is very confusing. The first part of the file is enclosed in <configSections> tags, but contains only a list of the configuration sections and their handlers, not the configuration sections themselves. And, as you will see shortly, the configuration sections are each contained within tags, but there is no grouping tag to contain all the separate configuration sections, analogous to <configSections>.

The machine.config file contains, in the default installation, many configuration section handler declarations that cover the areas subject to configuration by default. (Since this is an extensible system, you can also create your own. A typical entry containing a handler declaration is shown in Example 20-12.

In the original machine.config file, the contents of Example 20-12 were all contained in a single line.

Example 20-12. Typical configuration section handler declaration
<section name="compilation"           type="System.Web.UI.CompilationConfigurationHandler,                 System.Web,                Version=1.0.2411.0,                 Culture=neutral,                PublicKeyToken=b03f5f7f11d50a3a" />

Despite appearances to the contrary, the <section> tag has only two attributes: name and type. The name is compilation. This implies that somewhere else in the configuration file is a configuration section called compilation. This configuration section will contain the configuration settings, which are name/value pairs, to be used by the application(s). It will be described in detail shortly.

The type attribute has a lengthy parameter enclosed in quotation marks. This parameter contains:

  • The class that will handle the named configuration section

  • The assembly file (dll) that contains that class

  • Version and culture information to coordinate with the assembly file

  • A public key token used to verify that the dll being called is secure

Each handler need only be declared once, either in the base level machine.config file or in a web.config file further down the configuration hierarchy. The configuration section it refers to can then be specified as often as desired in other configuration files.

Example 20-13 shows a truncated version of the default machine.config.

Only a small subset of the actual entries in machine.config are included in Example 20-13. Also, the type attribute of each entry has been edited to remove all but the class, and lines have been broken to enhance the readability.

Example 20-13. Truncated machine.config file
<?xml version="1.0" encoding="UTF-8" ?> <configuration>   <configSections>     <section name="runtime"                type="System.Configuration.IgnoreSectionHandler" />      <section name="mscorlib"               type="System.Configuration.IgnoreSectionHandler" />      <section name="startup"               type="System.Configuration.IgnoreSectionHandler" />      <section name="appSettings"                type="System.Configuration.NameValueFileSectionHandler " />     <sectionGroup name="system.net">       <section name="defaultProxy"                type="System.Net.Configuration.DefaultProxyHandler " />     </sectionGroup>     <sectionGroup name="system.web">       <section name="compilation"                type="System.Web.UI.CompilationConfigurationHandler " />       <section name="pages"                 type="System.Web.UI.PagesConfigurationHandler " />     </sectionGroup>   </configSections>   <appSettings>     <!-- use this section to add application specific configuration        example: <add key="XML File Name" value="myXmlFileName.xml" /> -->   </appSettings>   <system.net>     <defaultProxy>         <proxy              usesystemdefault="true"          />     </defaultProxy>     <webRequestModules>       <add prefix="http"                   type="System.Net.HttpRequestCreator"       />       <add prefix="https"                   type="System.Net.HttpRequestCreator"       />       <add prefix="file"                   type="System.Net.FileWebRequestCreator"       />     </webRequestModules>   </system.net>   <system.web>     <compilation debug="false" explicit="true" defaultLanguage="vb">       <compilers>         <compiler language="c#;cs;csharp" extension=".cs"                    type="Microsoft.CSharp.CSharpCodeProvider " />         <compiler language="vb;visualbasic;vbscript" extension=".vb"                   type="Microsoft.VisualBasic.VBCodeProvider " />         <compiler language="js;jscript;javascript" extension=".js"                   type="Microsoft.JScript.JScriptCodeProvider " />         <compiler language="VJ#;VJS;VJSharp" extension=".jsl"                    type="Microsoft.VJSharp.VJSharpCodeProvider "/>       </compilers>       <assemblies>         <add assembly="mscorlib"/>         <add assembly="System "/>         <add assembly="System.Web "/>         <add assembly="System.Data "/>         <add assembly="System.Web.Services "/>         <add assembly="System.Xml "/>         <add assembly="System.Drawing "/>         <add assembly="*"/>       </assemblies>     </compilation>     <pages buffer="true" enableSessionState="true" enableViewState="true"             enableViewStateMac="false" autoEventWireup="true"             validateRequest="true" />   </system.web> </configuration>

The first three declarations in machine.config are runtime, mscorlib, and startup. They are special because they are the only declarations that do not have corresponding configuration sections in the file.

In Example 20-13, you can also see that many of the handler declarations are contained within <sectionGroup> tags. The name attribute of these tags corresponds to the namespace that contains the handlers. This groups together all the configuration sections that are handled out of the same namespace.

20.3.4 Configuration Sections

The configuration sections contain the actual configuration data. They each are contained within a pair of tags corresponding to the name of the section specified in the configuration section handler declaration. Alternatively, a single self-closing tag can be used. For example, the following two configuration sections are equivalent:

<globalization requestEncoding="utf-8" responseEncoding="utf-8" />

and:

<globalization>     requestEncoding="utf-8"     responseEncoding="utf-8" </globalization>

Configuration sections contain name/value pairs that hold the configuration data. They may also contain subsections.

machine.config contains one configuration section for each handler declaration. If the handler declaration was contained within a <sectionGroup> tag, then its corresponding configuration section will be contained within a tag containing the name of the <sectionGroup>. This can be seen in Example 20-13 for both system.net and system.web.

The sections that follow provide a description of each of the configuration sections contained in the default machine.config. There are other configuration sections that are beyond the scope of this book, including system. diagnostics, system.runtime.remoting, and system. windows.forms.

20.3.4.1 appSettings

appSettings allows you to easily store application-wide name/value pairs for read-only access. It is similar in function to application objects in the global.asax file.

Consider the handler declaration for appSettings, shown in Example 20-13 and reproduced here:

<section name="appSettings"            type="System.Configuration.NameValueSectionHandler " />

This indicates that the NameValueSectionHandler class is used to handle appSettings. This class provides name/value pair configuration handling for a specific configuration section.

As seen in Example 20-13, the appSettings section in the default machine.config file contains only a comment. More typically, you would add an appSettings section to one or more web.config files.

Example 20-14 shows a web.config file with an appSettings section added to provide two application-wide values. Note that the appSettings section is not contained within any higher-level tag other than <configuration>.

Example 20-14. appSettings configuration section
<?xml version="1.0" encoding="utf-8" ?> <configuration>    <appSettings>       <add key="appDSN"             value=" SERVER=Zeus;DATABASE=Pubs;UID=sa;PWD=secret;" />       <add key="appTitle" value="Programming ASP.NET" />    </appSettings> </configuration>

These values can be accessed anywhere in the application to which this configuration is applicable (i.e., its current directory and any child directories in which the value is not overridden by another web.config file). Example 20-15 and Example 20-16 show a script block from an .aspx file to illustrate how this is done in both VB.NET and C#, respectively. The C# version of the code in Example 20-16 shows only the script block, since the HTML is identical to the VB.NET version in Example 20-15.

Example 20-15. Reading appSettings values in VB.NET
<%@ Page Language="vb" %> <script runat="server">    sub Page_Load(ByVal Sender as Object, _                ByVal e as EventArgs)       if not IsPostBack then          dim strDSN as string          strDSN = ConfigurationSettings.AppSettings("appDSN")          '  use the DSN to connect to the database here          lblDSN.Text = strDSN           lblTitle.Text = ConfigurationSettings.AppSettings("appTitle")       end if    end sub </script> <html>    <body>    <form runat="server">       <h1>Configuration</h1>       Application DSN:         <asp:Label                    runat="server"/>       <br/>       Application Title:         <asp:Label                    runat="server"/>     </form>    </body> </html>
Example 20-16. Reading appSettings values in C#
<%@ Page Language="cs" %> <script runat="server">    void Page_Load(Object Source, EventArgs E)    {       if (!IsPostBack)       {          string strDSN;          strDSN = ConfigurationSettings.AppSettings["appDSN"];          //  use the DSN to connect to the database here                    lblDSN.Text = strDSN ;          lblTitle.Text = ConfigurationSettings.AppSettings["appTitle"];       }    } </script>

Configuration settings are read by an application using the AppSettings property of the ConfigurationSettings class. This class provides methods and properties for reading configuration settings in an application's configuration files. It is part of the System.Configuration namespace, which is automatically imported into every ASP.NET application.

The AppSettings property of the ConfigurationSettings class is of type NameValueCollection. It takes a key as a parameter and returns the value associated with that key.

20.3.4.2 system.net

The system.net configuration section contains subsections that deal with networking. These subsections include authenticationModules, defaultProxy, connectionManagement, and webRequestModules. These subsections are not used by ASP.NET developers and are outside the scope of this book.

20.3.4.3 system.web

The system.web configuration section contains subsections that configure ASP.NET. Each of these subsections will be described briefly in the following sections.

browserCaps

This subsection contains information about the capabilities of all the web browsers and operating systems your clients are likely to use. This information includes such items as the name of the browser; its major and minor version numbers; whether it supports frames, tables, cookies, cascading style sheets, VBScript, JavaScript, Java applets; and so on.

The version of <browserCaps> contained in the default machine.config file performs fairly extensive testing of the client browser to determine both the browser capabilities and the client platform.

As new browser versions come on the market, you can update the information contained in this section by visiting http://www.cyscape.com/browsercaps/.

clientTarget

Closely related to <browserCaps>, the <clientTarget> subsection provides ASP.NET with aliases for the browsers. For example, it provides the aliases shown in Table 20-2.

Table 20-2. Browser aliases

Alias

Browser characteristics

ie5

Internet Explorer 5.5

ie4

Internet Explorer 4.0

uplevel

Internet Explorer 4.0 and higher

downlevel

All others

compilation

This subsection allows you to configure the compilation behavior in ASP.NET. For example, you can change the default language and enable or disable debugging. If the default language is VB.NET, you can also set the explicit attribute to true, which is the equivalent of including the Option Explicit On statement in your page or web service.

The default <compilation> tag in machine.config looks like this:

<compilation debug="false" explicit="true" defaultLanguage="vb">

In a VB.NET project created in Visual Studio .NET, the default <compilation> tag in the web.config file for the application looks like this:

<compilation defaultLanguage="vb" debug="true" />

For a C# project in Visual Studio .NET, it looks like this:

<compilation defaultLanguage="c#" debug="true" />

Notice that the debug attribute in either web.config file overrides the value set in machine. config.

In addition to setting the language and debug mode, this subsection includes two other subsections: <compilers> and <assemblies>. The former subsection specifies what language names map with what file extensions. It also specifies the class containing the code provider and version information. The latter subsection specifies which assembly files are to be included when the project is compiled.

pages

This subsection specifies whether page options (such as buffering, session state, and view state) are enabled for the pages under the control of the configuration file. The default <pages> tag in the default machine.config file looks like this:

<pages buffer="true"         enableSessionState="true"         enableViewState="true"        enableViewStateMac="false"         autoEventWireup="true" />

The autoEventWireup attribute is specific to Visual Studio .NET. When AutoEventWireup is true (the default value outside of VS.NET), then the .NET Framework calls page events (Page_Init & Page_Load) automatically, with no code necessary to explicitly add an event handler to an event delegate. If AutoEventWireup is false (the default when using VS.NET), you must explicitly add event handler methods to the event delegates. VS.NET does this for you.

customErrors

This subsection allows you to control what the user sees when there is an error. Example 20-17 shows a typical <customErrors> configuration section that demonstrates the available features.

Example 20-17. <customErrors> configuration section
<customErrors defaultRedirect="StdError.htm" mode="RemoteOnly" >    <error statusCode="404" redirect="err404.htm" />    <error statusCode="407" redirect="err407.htm" /> </customErrors >

When custom errors are enabled, if an error occurs, the web page specified in defaultRedirect is presented to the client rather than the standard ASP.NET error page.

The mode attribute specifies how custom errors are enabled. There are three possible values for this mode, which are shown in Table 20-3.

Table 20-3. Values for the mode attribute of the <customErrors> tag

Value

Description

On

Custom errors are enabled for all users.

Off

Custom errors are disabled for all users.

RemoteOn ly

Custom errors are shown only to remote clients, not to local clients. This setting allows developers to see the full error message provided by ASP.NET while showing end users the error page you wish them to see.

You can add multiple <error> tags to present specific error pages for specific errors.

In Example 20-17, error 404 will result in err404.htm being presented to the client, error 407 will result in err407.htm, and all other errors will result in StdError.htm being presented. In any case, the developer working on the local machine will see none of these custom error pages, but rather will see the standard error page put up by ASP.NET.

httpRuntime

This subsection configures the ASP.NET HTTP runtime settings. There are several attributes available in this section, as shown in Table 20-4.

Table 20-4. Attributes of the httpRuntime subsection

Attribute

Description

useFullyQualifie dRedirectUrl

Specifies if client-side redirects are fully qualified, which is necessary for some mobile controls. Legal values are true, for fully qualified URLs, and false, for relative URLs.

executionTimeout

Maximum number of seconds a request is allowed to execute before being shut down by ASP. NET.

maxRequestLength

Maximum file size for upload, in bytes. This can help prevent denial of service attacks by preventing clients from posting large files.

minFreeThreads

Minimum number of free threads for execution of new requests. These threads are available for requests that require additional threads.

minLocalRequestF reeThreads

Minimum number of free threads available for requests to localhost.

appRequestQueueL imit

Maximum number of requests queued waiting for a free thread. If incoming request rejected, then "503 Server too busy" error will be returned.

The <httpRuntime> tag in the default machine.config file looks like this:

<httpRuntime      executionTimeout="90"      maxRequestLength="4096"      useFullyQualifiedRedirectUrl="false"      minFreeThreads="8"      minLocalRequestFreeThreads="4"      appRequestQueueLimit="10" />
globalization

This subsection is used to configure the globalization settings for an application. The attributes shown in Table 20-5 are supported.

Table 20-5. Attributes of the globalization subsection

Attribute

Description

requestEncoding

Specifies the encoding assumed for incoming requests. If not specified in any configuration file, defaults to computer's Regional Options locale setting.

responseEncoding

Specifies the encoding of responses. If not specified in any configuration file, defaults to computer's Regional Options locale setting.

fileEncoding

Specifies the default encoding for parsing .aspx, .asmx, and .asax files.

culture

Specifies the default culture for incoming requests.

uiCulture

Specifies the default culture for locale-dependent resource searches.

The <globalization> tag in the default machine.config file looks like this:

<globalization         requestEncoding="utf-8"         responseEncoding="utf-8" />
httpHandlers

This subsection maps incoming requests to a class that implements either the IHttpHandler or IHttpHandlerFactory interfaces. There is a fairly extensive mapping in the default machine.config file, which maps standard file types to a specific class (e.g., all .aspx requests are mapped to the PageHandlerFactory class).

The <httpHandlers> tag has several subtags:

<add>

Specifies the mapping. A typical <add> subtag looks like:

<add verb="*"       path="*.vb"       type="System.Web.HttpForbiddenHandler"/>

The verb attribute can either contain a comma separated list of HTTP verbs, such as GET, PUT, or POST, or the wildcard character (*). The path attribute can contain either a single URL path or a wildcard string. The type attribute is a class name. ASP.NET first searches for the specified class in the \bin directory, then in the global assembly cache. (See Section 20-4 later in this chapter for a description of the global assembly cache.)

<remove>

Removes a previously added mapping. It has the same syntax as the <add> subtag, except that there is no type attribute.

<clear>

Clears all currently configured or inherited mappings. It has no attributes.

httpModules

This subsection configures the HTTP modules within an application. Each <add> subtag within the subsection assigns a class to a module. The default machine.config file includes the modules and their classes shown in Table 20-6.

Table 20-6. Modules and classes defined in the httpModules subsection

Module

Class

OutputCache

System.Web.Caching.OutputCacheModule

Session

System.Web.SessionState.SessionStateModule

WindowsAuthentication

System.Web.Security.WindowsAuthenticationModule

FormsAuthentication

System.Web.Security.FormsAuthenticationModule

PassportAuthentication

System.Web.Security.PassportAuthenticationModule

UrlAuthorization

System.Web.Security.UrlAuthorizationModule

FileAuthorization

System.Web.Security.FileAuthorizationModule

processModel

This tag configures the process model settings on an IIS web server. The <processModel> tag in the default machine.config file looks like this:

<processModel    enable="true"    timeout="Infinite"    idleTimeout="Infinite"    shutdownTimeout="0:00:05"     requestLimit="Infinite"     requestQueueLimit="5000"     restartQueueLimit="10"    memoryLimit="60"     webGarden="false"    cpuMask="0xffffffff"    userName="machine"    password="AutoGenerate"    logLevel="Errors"    clientConnectedCheck="0:00:05"    comAuthenticationLevel="Connect"    comImpersonationLevel="Impersonate" />

Two of these attributes are worth special mention, since they can improve the stability of the system. The timeout attribute controls how often every process is automatically shut down and restarted. The default value is "Infinite," indicating that the process is never restarted. It may also have a time value of the form hh:mm:ss. So, for example, if you want every process to restart every 20 minutes, use the value "00:20:00." The requestLimit attribute specifies how many requests each process can receive before it is re-started. The default value is also "Infinite." Typical values would be an integer inside quotes. So, to restart every process every 5000 requests, use the value "5000."

For a detailed description of each of these attributes, consult the SDK documentation. Note that these settings are ignored if you are using IIS 6, which has its own process model settings.

sessionState

The <sessionState> tag configures session state. Chapter 6 fully examines session state. This tag supports the attributes shown in Table 20-7.

Table 20-7. Attributes of the <sessionState> tag

Attribute

Description

mode

Specifies where the session state is stored. It has four legal values. Off disables session state. Inproc, the default value, stores session state on the local server. StateServer stores session state in a remote process, which may be hosted on the same computer or a remote server. SqlServer stores session state in a SQL Server database. One of the latter two values are required when running a web farm.

cookieless

Specifies whether cookieless sessions should be used. A value of true indicates that cookieless sessions should be used, in which case the session information will be munged as part of the URL. A value of false, the default, indicates that cookies will be used to maintain session state.

timeout

The number of minutes a session is idle before it is abandoned. The default is 20.

stateConnecti onString

Specifies the connection string to the server where session is to be stored if mode is set to StateServer.

sqlConnection String

Specifies the connection string to the SQL Server where session is to be stored if mode is set to SqlServer.

The default <sessionState> tag in machine.config is shown here:

<sessionState      mode="InProc"      stateConnectionString="tcpip=127.0.0.1:42424"      stateNetworkTimeout="10"      sqlConnectionString="data source=127.0.0.1;user id=sa;password="      cookieless="false"      timeout="20" />
trace

The <trace> tag configures the ASP.NET trace service. Chapter 7 describes tracing fully. The <trace> tag supports the attributes shown in Table 20-8.

Table 20-8. Attributes of the <trace> tag

Attribute

Description

enabled

Enables or disables tracing. Legal values are true or false. The default is false.

requestLimit

The number of trace requests to store on the server.

pageOutput

true specifies that trace output is appended to each page. false, the default, specifies that trace output is accessible only through the trace utility.

traceMode

Specifies the sort order of the trace display. SortByTime, the default value, specifies that trace information is sorted in the order processed. SortByCategory specifies that trace information is displayed alphabetically by user-defined category.

localOnly

true, the default, specifies that the trace viewer is available only on the host web server. false specifies that the trace viewer is available remotely.

The default <trace> tag in machine.config is shown here:

<trace     enabled="false"     localOnly="true"     pageOutput="false"     requestLimit="10"     traceMode="SortByTime" />
webControls

The <webControls> tag specifies the location of the script that is generated to be run client-side. It supports a single attribute, clientScriptsLocation.

The default <webControls> tag in machine.config is shown here:

<webControls     clientScriptsLocation="/aspnet_client/{0}/{1}/" />
webServices

The <webServices> tag configures web services.

The default <webServices> tag in machine.config is shown here:

webServices>    <protocols>      <add name="HttpSoap"/>       <add name="HttpPost"/>       <add name="HttpGet"/>       <add name="Documentation"/>     </protocols>    <soapExtensionTypes>    </soapExtensionTypes>    <soapExtensionReflectorTypes>    </soapExtensionReflectorTypes>    <soapExtensionImporterTypes>    </soapExtensionImporterTypes>    <wsdlHelpGenerator href="DefaultWsdlHelpGenerator.aspx" />    <serviceDescriptionFormatExtensionTypes>    </serviceDescriptionFormatExtensionTypes> /webServices>
20.3.4.4 Security settings

Many aspects of ASP.NET security are configurable, using the machine.config and web.config files. For a complete discussion of the security concepts configured here, see Chapter 19.

There are several configuration sections controlling security. They are described in the following sections.

identity

The <identity> tag controls the identity of the application at runtime. Specifically, it enables and disables impersonation, and if impersonation is enabled, it allows you to specify the userName and password to use.

The <identity> tag supports three attributes shown in Table 20-9.

Table 20-9. Attributes of the <identity> tag

Attribute

Description

impersonate

Set to true to enable impersonation or false to disable impersonation.

userName

If impersonation is enabled, specifies the username to use.

password

If impersonation is enabled, specifies the password to use.

The <identity> tag in the default machine.config file looks like this:

<identity impersonate="false" userName="" password=""/>
authentication

The <authentication> tag controls authentication in ASP.NET applications. As is described fully in Chapter 19, authentication is the process whereby ASP.NET security verifies that a client making a request is who they say they are.

The <authentication> tag has one attribute, mode, which specifies the default authentication mode for the application. There are four legal values for mode, which are shown in Table 20-10.

Table 20-10. Values of the <authentication> tag's mode attribute

Mode value

Description

Windows

Sets the default authentication mode to Windows. Using this mode allows IIS to perform authentication.

Forms

Sets the default authentication mode to Forms. Using this mode, your application controls authentication through a login form created as part of the application.

Passport

Sets the default authentication mode to Passport. Passport is a centralized authentication service offered by Microsoft.

None

No authentication will be performed. This means that only anonymous users will access the site or the application will provide its own authentication.

The <authentication> tag also has two subtags. They are <forms> and <passport>.

The <forms> tag has five attributes, listed in Table 20-11.

Table 20-11. Attributes of the <forms> tag

Attribute

Description

name

Specifies the name of the HTTP cookie used for authentication. The default name is .ASPXAUTH.

loginUrl

Specifies the URL to which the request is redirected if there is no valid authentication.

protectio n

Four legal values. All, the default and recommended value, specifies that the application use both data validation and encryption to protect the authentication cookie. None specifies that the cookies will be neither validated nor encrypted, but will be available for personalization. Encryption specifies that the authentication cookie is encrypted but not validated. Validation specifies that the authentication cookie is validated (i.e., it is verified as not having been altered in transit between the client and the server).

timeout

The integer number of minutes after the last request that the cookie expires. Does not apply to persistent cookies. Default value is 30.

path

Specifies the path for cookies. Default value is / (backslash). Note that most browsers are case-sensitive and will not return a cookie if there is a path/case mismatch.

The <forms> tag also has one subtag, <credentials>. This subtag allows you to specify the type of password encryption used and also to define name/password pairs within the <user> subtag.

The <credentials> tag has a single attribute, passwordFormat. This attribute has three legal values, which are shown in Table 20-12.

Table 20-12. Values of the <credentials> tag's passwordFormat attribute

passwordFormat values

Description

Clear

Passwords are not encrypted.

MD5

Passwords are encrypted using the MD5 hash algorithm.

SHA1

Passwords are encrypted using the SHA1 hash algorithm.

The <credentials> tag enables you to specify user/password pairs using the <user> subtag. The <user> subtag has two attributes: name and password. Their values are the username and password, respectively.

The <passport> subtag of the <authentication> tag has a single attribute, redirectUrl. The value of this attribute is the URL to redirect to if the page requires authentication and the user has not signed on with Passport.

The <authentication> tag in the default machine.config file looks like this:

<authentication mode="Windows">     <forms name=".ASPXAUTH"             loginUrl="login.aspx"             protection="All"            timeout="30"            path="/" >         <credentials passwordFormat="SHA1">                 <!-- <user name="UserName" password="password"/> -->         </credentials>     </forms>     <passport redirectUrl="internal" /> </authentication>
authorization

The <authorization> tag controls authorization in ASP.NET applications. Authorization is how ASP.NET security controls access to URL resources.

The <authorization> tag supports two subtags, <allow> and <deny>. Both subtags have the same set of three attributes, which are shown in Table 20-13. Those attributes are used to define access rules that are iterated at runtime. Access for a particular user is allowed or denied based on the first rule found that fits that user.

Table 20-13. Attributes of the <allow> and <deny> subtags

Attribute

Description

users

Comma-separated list of users either allowed or denied access. Question mark (?) allows anonymous users. Asterisk (*) allows all users.

roles

Comma-separated list of roles that are allowed or denied access.

verbs

Comma-separated list of HTTP verbs that are allowed or denied access. Registered verbs are GET, HEAD, POST, and DEBUG.

The default <authorization> tag in machine.config is shown here. It allows all users.

<authorization>     <allow users="*" /> </authorization>
machineKey

The <machineKey> tag configures keys used for encryption and decryption of authentication cookies. This section can be declared at the server level in machine.config or in web.config files at the site or application root level. The <machineKey> tag supports three attributes, which are shown in Table 20-14.

Table 20-14. Attributes of the <machineKey> tag

Attribute

Description

validationKey

Specifies the key used for validation. Supports two types of values: AutoGenerate, the default value, specifies that ASP.NET will generate a random key. Alternatively, a value can be manually set to allow operation across a web farm. This value must be between 40 and 128 hexadecimal characters long (between 20 and 64 bytes).

decryptionKey

Specifies the key used for decrypting the cookie. Uses the same values as the validationKey.

validation

Specifies the type of encryption used for data validation. There are three legal values: SHA1 specifies SHA1 encryption, MD5 specifies MD5 encryption, and 3DES specifies Triple-DES encryption.

The default authorization in machine.config is shown here:

<machineKey validationKey="AutoGenerate"              decryptionKey="AutoGenerate"              validation="SHA1"/>
securityPolicy

The <securityPolicy> tag maps named security levels to policy files. This section can be declared at the server level in machine.config or in web.config files at the site or application root level.

The <securityPolicy> tag supports one subtag, <trustLevel>. This subtag is used to specify one security level name and an associated policy level. There is a separate <trustLevel> tag for each named security level.

The <trustLevel> tag supports the two attributes shown in Table 20-15.

Table 20-15. Attributes of the <trustLevel> tag

Attribute

Description

name

Defines a name to associate with the specified level of trust. Legal values are Full, High, Low, and None. If set to None, indicates file mapping for the Full security level.

policyFile

Specifies the policy level, relative to the directory containing machine.config, associated with the specified level of trust.

The default <securityPolicy> in machine.config is shown here:

<securityPolicy>    <trustLevel name="Full" policyFile="internal" />    <trustLevel name="High" policyFile="web_hightrust.config" />    <trustLevel name="Low"  policyFile="web_lowtrust.config" />    <trustLevel name="None" policyFile="web_notrust.config" /> </securityPolicy>
trust

The <trust> tag configures the code access security permissions for an application. This section can be declared at the server level in machine.config or in web.config files at the site or application root level.

The <trust> tag supports the two attributes shown in Table 20-16.

Table 20-16. Attributes of the <trust> tag

Attribute

Description

level

Specifies the security level under which the application will be run. Legal values are Full, High, Low, and None. Required.

originalUrl

Specifies an application's URL of origin. Optional.

The default <trust> in machine.config is shown here:

<trust level="Full" originUrl="" />
location

The location section is used to apply configuration settings to specific resources, such as individual web pages or contained subdirectories. The <location> tag has a single attribute, path. The path attribute specifies a file or child directory (relative to the location of the current web.config file) to which specific configuration settings apply.

Suppose you had an application with custom error pages specified in the web.config file in the application virtual root directory. These custom error pages would apply to the entire application, including all child directories. Suppose further that there are two subdirectories under the virtual root directory, called sub1 and sub2. sub1 is to have the application-wide custom error handling, but sub2 is to have its own specific error handling.

You could put another copy of web.config in sub2 to override the custom error handling, but an alternative would be to use the <location> tag. You would add the following lines to the web.config file in the virtual root of the application:

<location path="sub2">    <system.web>       <customErrors defaultRedirect="Sub2Error.htm" mode="RemoteOnly" >          <error statusCode="404" redirect="err404-sub2.htm" />          <error statusCode="407" redirect="err407-sub2.htm" />       </customErrors >    </system.web> </location>

Notice that the <system.web> tag must be reproduced within the location section.

The configuration settings contained in a location section will apply to the directory specified in the path attribute and also to any child directories of that directory, unless they are further overridden either by another web.config file or another location section.

If you want to apply specific configuration settings to a single file, that too can be done using a location section. Suppose the application root had a web page that requires special error handling. The following location section will accomplish that.

<location path="SpecialPage.aspx">       <system.web>          <customErrors defaultRedirect="SpecialError.htm"                        mode="RemoteOnly" >             <error statusCode="404" redirect="err404-spcl.htm" />          </customErrors >       </system.web>    </location>

20.3.5 Custom Configuration

In addition to all the predefined configuration sections, you can also add your own custom configuration sections. There are two different types of custom configuration sections you might wish to add:

  • Sections that provide access to a collection of name/value pairs, similar to appSettings

  • Sections that return any type of object

Both will be demonstrated here.

20.3.5.1 Name/value pairs

Back in Example 20-14, you added an <appSettings> key to store the database DSN string. Suppose you wanted to store DSNs for multiple databases, say one called Test (for testing purposes) and one called Content (to hold the production content). A custom configuration section returning a name/value pair would be one way to handle this situation.

The finished version of lines of code inserted into web.config is shown in Example 20-18. There are several steps to adding a custom configuration section that returns a name/value pair:

  1. Determine which specific configuration file to add the custom section to. This will determine the scope, or visibility, of the custom section.

    Adding the section to machine.config will make it available to every application on that machine. Adding it to a web.config file in the virtual root directory of an application will make the section visible to that entire application, but to no other applications. Adding it to a web.config file in an application subdirectory will make it visible only to that subdirectory and its child subdirectories.

  2. Declare the section handler by adding a line to the <configSections> section of the designated configuration file. This tells ASP.NET to expect a configuration section with the specified name, and also which class and assembly file to use to process the section.

    Add the highlighted lines between the <configSections> tags in Example 20-18 to the designated configuration file. If the file you are editing does not already have a pair of <configSections> tags, then you will need to add those as well. The <configSections> element should be the first child of the root <configuration> element.

  3. Add the custom section itself to the configuration file. This consists of the highlighted lines in Example 20-18 between the <altDB> tags. This custom configuration section contains two entries, one named Test and the other named Content, each with its own value attribute.

Example 20-18. Custom sections in web.config
<configSections>    <section name="altDB"             type="System.Configuration.NameValueSectionHandler, System,             Version=1.0.5000.0, Culture=neutral,PublicKeyToken=b77a5c561934e089,              Custom=null" /> </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>

Note that the type in the <section> tag is exactly the same as that provided for appSettings in the machine.config file. It specifies the NameValueSectionHandler class in the System.dll assembly file. For further documentation, check SDK documentation, search on Custom Elements and choose Custom Element for NameValueSectionHandler.

To read the contents of this custom configuration section, you again use a method from the ConfigurationSettings class, this time the GetConfig method. The code for a sample web page for doing this is shown in Example 20-19 in VB. NET and in Example 20-20 in C#. The C# version of the code in Example 20-20 shows only the script block, since the HTML is identical to the VB.NET version in Example 20-19.

Example 20-19. Reading custom configuration values in VB.NET, vbConfig-02.aspx
<%@ Page Language="vb" %> <script runat="server">    sub Page_Load(ByVal Sender as Object, _                ByVal e as EventArgs)       if not IsPostBack then          dim strTest as string          dim strContent as string          strTest = ConfigurationSettings.GetConfig("altDB")("Test")          lblTest.Text = strTest        lblContent.Text = _                ConfigurationSettings.GetConfig("altDB")("Content")       end if    end sub </script> <html>    <body>    <form runat="server">       <h1>Configuration</h1>       <b>Test Database DSN:&nbsp;&nbsp;&nbsp;</b>       <asp:Label                    runat="server"/>       </br>       <b>Content Database DSN:&nbsp;&nbsp;&nbsp;</b>       <asp:Label                    runat="server"/>     </form>    </body> </html>
Example 20-20. Reading custom configuration values in C#, csConfig-02.aspx
<%@ Page Language="cs" %> <script runat="server">    void Page_Load(Object Source, EventArgs E)    {       if (!IsPostBack)       {          string strTest;          string strContent;          strTest = ((NameValueCollection)                   ConfigurationSettings.GetConfig("altDB"))["Test"];          lblTest.Text = strTest;          lblContent.Text = ((NameValueCollection)                   ConfigurationSettings.GetConfig("altDB"))["Content"];       }    }</script>

The code in Example 20-19 and Example 20-20 shows two equivalent ways of displaying the contents of the key value. One way is to assign the value to a string, then assign the string to the Text property of a label. The other way is to assign the value directly to the Text property. Although the latter technique is more concise, the former is often easier to debug.

In either case, notice the highlighted code in Example 20-19 and Example 20-20. These are the calls to the GetConfig method. They are different for VB.NET and C#, and a bit confusing in both.

The GetConfig method takes a configuration section name as a parameter and returns an object of type NameValueCollection. The desired value in the collection is retrieved by using the key as an offset into the collection, using the get property syntax. In VB.NET, a property is retrieved by enclosing the property name in parentheses, and in C#, the property is retrieved using square brackets.

Notice that the C# code first casts, or converts, the value returned by GetConfig to type NamedValueCollection, while VB.NET does not. This is because C# does not support late binding, while VB.NET does by default. You can disable late binding in VB.NET (almost always a smart move) by setting the Strict attribute to true in the Page directive. You must then explicitly cast the object returned by GetConfig, just as in C#. This is shown in Example 20-21.

Example 20-21. Reading custom configuration values in VB.NET using early bindingvbConfig-02b.aspx
<script runat="server">    sub Page_Load(ByVal Sender as Object, _                ByVal e as EventArgs)       if not IsPostBack then          dim strTest as string          dim strContent as string          strTest = _             CType(ConfigurationSettings.GetConfig("altDB"), _                   NameValueCollection)("Test")          lblTest.Text = strTest          lblContent.Text = _             CType(ConfigurationSettings.GetConfig("altDB"), _                   NameValueCollection)("Content")       end if    end sub  </script>
20.3.5.2 Objects

appSettings and custom configuration sections are very useful. However, they both suffer from the same limitation of only being able to return a name/value pair. Sometimes it would be very useful to return an object.

For example, suppose you have a standard query into a database. You could store the query string in an appSettings tag, then open a database connection after retrieving the string. However, it would be much more convenient to store the query string in web.config and then have the configuration system return a DataSet directly.

To do this, you must add a <section> tag and a configuration section to the designated configuration file, just as with the custom section returning name/value pairs, described in the previous section.

Edit the web.config file used in the previous example and shown in Example 20-18, adding the lines of code highlighted in Example 20-22.

Example 20-22. Custom sections returning objects in 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="ProgAspNet.Handlers.DataSetSectionHandler,                            vbSectionHandlers">          </section>       </sectionGroup>    </configSections>    <appSettings>       <add key="appDSN"             value=" SERVER=Zeus;DATABASE=Pubs;UID=sa;PWD=secret;" />       <add key="appTitle" value="Programming ASP.NET" />    </appSettings>    <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>    <!-- Custom config section returning an object -->    <DataSetSectionHandler  str="Select BugID, Description from Bugs"  />   </system.web> </configuration>

In the <sectionGroup> section within the <configSections> section, a handler declaration is created for the DataSetSectionHandler within the system.web group. This specifies that elsewhere within the file, there will be a custom configuration section called DataSetSectionHandler within the system.web custom section. Furthermore, it also specifies that the class that will handle that configuration section is called ProgAspNet. Handlers.DataSetSectionHandler, and that the class will be found in an assembly file called vbSectionHandlers.dll in the \bin directory.

Further down in the file, within the <system.web> section, there is in fact a section called DataSetSectionHandler. It has a single attribute, str. This is a string containing the SQL statement you wish to pass to the database.

Next you must create the ProgAspNet.Handlers.DataSetSectionHandler class and place it in a file called DataSetSectionHandler.vb. To do this, create a VB.NET source code file as shown in Example 20-23. (The C# version of the same class is shown in Example 20-24.)

Example 20-23. Source code for section handler in VB.NET, DataSetSectionHandler.vb
Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Xml Imports System.Configuration Namespace ProgAspNet.Handlers    public class DataSetSectionHandler           Implements IConfigurationSectionHandler       public Function Create(parent as Object, _                              configContext as Object, _                              section as XmlNode) as Object _          Implements IConfigurationSectionHandler.Create          dim strSql as string          strSql = section.Attributes.Item(0).Value          dim connectionString as string = "server=Ath13; uid=sa; " & _                         "pwd=password; database=Bugs"          ' create the data set command object and the DataSet          dim da as SqlDataAdapter = new SqlDataAdapter(strSql, _                            connectionString)          dim dsData as DataSet = new DataSet(  )          ' fill the data set object          da.Fill(dsData,"Bugs")          return dsData       end Function    end class end NameSpace
Example 20-24. Source code for section handler in C#, DataSetSectionHandler.cs
using System; using System.Data; using System.Data.SqlClient; using System.Xml; using System.Configuration; namespace ProgAspNet.Handlers {    public class DataSetSectionHandler : IConfigurationSectionHandler    {       public Object Create(Object parent,                             Object configContext,                             XmlNode section)       {          string strSql;          strSql = section.Attributes.Item(0).Value;          string connectionString = "server=Ath13; uid=sa; " +                         "pwd=password; database=Bugs";          // create the data set command object and the DataSet          SqlDataAdapter da = new SqlDataAdapter(strSql,                             connectionString);          DataSet dsData = new DataSet(  );          // fill the data set object          da.Fill(dsData,"Bugs");          return dsData;       }    } }

Be sure to set the connection string to match your specific database. The server name and password are certainly different than that shown in Example 20-23.

The database aspects of the code in this example are covered thoroughly in Chapter 11 and won't be covered here in detail.

At the beginning of the Example 20-23 are several Imports statements (when written in C#, these are using statements). Next a namespace is declared to contain the class. This is to prevent any ambiguity when calling the class.

In order for a class to be used as a configuration section handler, it must be derived from the IConfigurationSectionHandler interface. In VB.NET, this is implemented by using the Implements keyword. (In C#, this would be indicated with a colon between the class or method name and the class or interface being inherited.)

A full discussion of object-oriented concepts such as inheritance, base classes, and interfaces is beyond the scope of this book. For now, you should just know that an interface acts as a contract that the implementing class must fulfill. The interface may, for example, dictate the signature of methods that the implementing class must implement, or it may dictate which properties the class must provide.

The IConfigurationSectionHandler interface has only a single method, Create. Therefore our implementing class must implement the Create method with the specified signature. The three parameters are dictated by the interface. The first two parameters are rarely used and will not be further discussed here. The third parameter is the XML data from the configuration file.

The XML node is parsed and the value of the first item in the Attributes collection is assigned to a string variable in this line:

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

Once the SQL string is in hand, the connection string is hard-coded, a SqlDataAdapter object is instantiated and executed, and the DataSet is filled. Then the DataSet is returned.

Before this class can be used it must be compiled. Open a command prompt by clicking on the Start button, then Microsoft Visual Studio .NET Visual Studio . NET Tools Visual Studio .NET Command Prompt. Use the cd command to make the application virtual root the current directory. This assumes that the virtual root directory already has a child directory called \bin. If not, you'll have to make one. Then enter the following command line:

vbc /t:library /out:bin\vbSectionHandlers.dll /r:system.dll,System.data.dll,System.xml.dll  DataSetSectionHandler.vb

In C#, use the following:

csc /t:library /out:bin\vbSectionHandlers.dll /r:system.dll,System.data.dll,System.xml.dll  DataSetSectionHandler.cs

Using command-line compilers is explained in some detail in Chapter 16. Here the target type of output is set to be library, i.e., a dll. The name of the output file to be placed in the bin directory will be vbSectionHandlers.dll. Notice that three dll files are referenced. The input source file is DataSetSectionHandler.vb. When the source file is compiled, you will have the output dll in the \bin directory, where the classes it contains will automatically be available to the application.

The web page shown in Example 20-25 (in VB.NET) and Example 20-26 (in C#) shows how to utilize this configuration section.

Example 20-25. Section handler demonstration in VB.NET, vbConfig-03.aspx
<%@ Page Language="vb"  %> <%@ Import namespace="System.Data" %> <script runat="server">    sub Page_Load(ByVal Sender as Object, _                ByVal e as EventArgs)       if not IsPostBack then          CreateDataGrid(  )       end if    end sub    sub CreateDataGrid(  )       dim dsGrid as new DataSet       dsGrid = _           ConfigurationSettings.GetConfig( _                "system.web/DataSetSectionHandler")          dg.DataSource=dsGrid.Tables(0)       dg.DataBind(  )    end sub </script> <html>    <body>    <form runat="server">       <h1>Configuration</h1>       <asp:DataGrid                    runat="server"/>     </form>    </body> </html>
Example 20-26. Section handler demonstration in C#, csConfig-03.aspx
<%@ Page Language="C#"  %> <%@ Import namespace="System.Data" %> <script runat="server">    void Page_Load(object Sender, EventArgs e)    {       if (!IsPostBack)       {          CreateDataGrid(  );       }    }    void CreateDataGrid(  )    {       DataSet dsGrid = new DataSet(  );       dsGrid = (DataSet)           ConfigurationSettings.GetConfig(                "system.web/DataSetSectionHandler");       dg.DataSource=dsGrid.Tables[0];       dg.DataBind(  );    } </script>

The page in Example 20-25 first imports two namespaces necessary for working with the SQL Server database. The interesting work is done in the CreateDataGrid method. There, rather than supply a DSN and SQL query string, a call is made to the GetConfig method of the ConfigurationSettings class, which returns a DataSet object directly. Then the DataSet object is set as the DataSource of the DataGrid control, and the control is data bound. The parameter of the GetConfig method is a string containing the name of the section containing the configuration settings. Notice the syntax with the section name (system.web) separated from the subsection name (DataSetSectionHandler) by a slash.



Programming ASP. NET
Programming ASP.NET 3.5
ISBN: 0596529562
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net