Microsoft ASP.Net Setup and Configuration Pocket Reference James Avery PUBLISHED BY Microsoft Press A Division of Microsoft Corporation One Microsoft Way Redmond, Washington 98052-6399 Copyright © 2003 by ActiveEducation All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher. Library of Congress Cataloging-in-Publication Data Avery, James. Microsoft ASP.NET Setup and Configuration Pocket Reference / James Avery. p. cm. Includes index. ISBN 0-7356-1936-0 1. Active server pages. 2. Microsoft .NET. 3. Web site development--Computer programs. I. Title. TK5105.8885.A26A94 2003 005.2'76--dc21 2003043009 Printed and bound in the United States of America. 123456789
QWE 8 7 6 5 4 3
Distributed in Canada by H.B. Fenn and Company Ltd. A CIP catalogue record for this book is available from the British Library. Microsoft Press books are available through booksellers and distributors worldwide. For further information about international editions, contact your local Microsoft Corporation office or contact Microsoft Press International directly at fax (425) 936-7329. Visit our Web site at www.microsoft.com/mspress. Send comments to
[email protected]. FrontPage, JScript, Microsoft, Microsoft Press, MSDN, Visual Basic, Visual Studio, Windows, and Windows NT are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Other product and company names mentioned herein may be the trademarks of their respective owners. The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious. No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred. Acquisitions Editor: Anne Hamilton Project Editor: Kristen Weatherby Technical Editor: Keith Bednarczuk Body Part No. X09-45932 About the Author
James Avery is a .NET consultant working in the Cincinnati, Ohio, area. James has been developing applications since 1997 and currently works with ASP.NET, C#, and SQL Server 2000 to build enterprise Web solutions. Before becoming a consultant, James worked for numerous companies, including Schawk Inc. and Dell Computer. James has written numerous books and articles; he recently coauthored Professional ASP.NET Performance, published by Wrox Press. He has written articles on ASP.NET performance and ASP to ASP.NET migration for ASPToday, as well as maintaining a column at aspalliance.com and contributing to 4guysfromrolla.com. You can also find him answering questions on the ASP.NET forums and the ASP Advice lists. James currently lives in Cincinnati, Ohio, with his fiancée Tammy Glasgow. In his spare time, he enjoys gaming, digital photography, and blogging. You can read his Web log at www.dotnetweblogs.com/Javery. At Microsoft Press, we use tools to illustrate our books for software developers and IT professionals. Tools very simply and powerfully symbolize human inventiveness. They're a metaphor for people extending their capabilities, precision, and reach. From simple calipers and pliers to digital micrometers and lasers, these stylized illustrations give each book a visual identity, and a personality to the series. With tools and knowledge, there's no limit to creativity and innovation. Our tagline says it all: the tools you need to put technology to work. To Tammy, Only through your love, support, and patience was any of this possible. I will love you always. Acknowledgments This book would not have been possible without the hard work of a lot of people. First I have to thank Robert Kern, my agent, for making this book possible in the first place. I want to give special thanks to Anne Hamilton at Microsoft Press for giving me the original idea for this book and in signing me on to write it. Without these two people, this project would never have found its way to my desk. Thanks to all the other people at Microsoft Press including Kristen Weatherby, and the editors at Online Training Solutions, Inc. including Nancy Depper and Keith Bednarczuk. I also want to thank Dave Wanta for making the rotor source code easily available on his site at www.123aspx.com/rotor; without this I would not have realized how invaluable this code is. And last but not least, thanks to my fiancé Tammy for helping me in so many different ways.
Table of Contents Microsoft ASP.Net Setup and Configuration Pocket Reference Introduction Part I - Overview of Microsoft ASP.NET Configuration Chapter 1 - Introduction to the Microsoft ASP.NET Configuration Chapter 2 - Examining the ASP.NET Configuration Architecture Part II - ASP.NET Configuration Settings Chapter 3 - Configuration Section and Application Settings Chapter 4 - System.Web Configuration Settings Chapter 5 - Mobile Controls Configuration Settings Chapter 6 - Microsoft .NET Configuration Settings Chapter 7 - CLR Configuration Settings Chapter 8 - IIS Settings Part III - Creating Custom Settings Chapter 9 - Creating and Using Custom Sections Part IV - Appendix and Glossary Appendix - Microsoft .NET Framework Configuration Tool Glossary List of Figures List of Tables List of Code Examples List of Sidebars Index
Introduction Overview Welcome to the Microsoft ASP.NET Setup and Configuration Pocket Reference, the definitive quick reference guide to working with the ASP.NET configuration files. ASP.NET and the .NET Framework incorporate a very powerful and adaptable configuration model based on XML configuration files. The XML configuration files contain various configuration sections and elements that contain settings for servers and applications. This book provides an easy-to-use quick reference for the many configuration sections, settings, and possible values. This guide will illustrate how to use this powerful configuration model to modify an application’s behavior and add functionality. This guide is designed to provide you with a single resource about ASP.NET configuration. This book is not an attempt to be a complete reference to the configuration files, but rather a complete reference to ASP.NET configuration. The step-by-step procedures, examples, and reference tables will help you answer your questions and finish the task. You will no longer have to look for solutions in general ASP.NET books or rifle through the documentation; you can turn to this book and quickly find the solutions you need. This guide will cover the following ASP.NET configuration topics. The format and structure of ASP.NET configuration files The architecture of the ASP.NET configuration model The settings in the System.Web group The settings for the Microsoft Mobile Internet Toolkit configuration sections The .NET Framework section groups, including System.Net, System.Diagnostics, and more The settings for the common language runtime The settings that are modified through the IIS administration tool The creation of custom configuration sections and custom section handlers The use of the security configuration tool to apply security settings to .NET assemblies
Who Should Read This Book When I set out to write this book, I thought of what would be useful to me, a developer who works with ASP.NET every day. When I am modifying the configuration of my ASP.NET applications, I often have to turn to the .NET SDK documentation or the Internet for help. What I really needed was an easy-to-use guide to the configuration of ASP.NET applications. I wrote this book for ASP.NET developers who, like me, wanted such a guide. Advanced, intermediate, and beginning ASP.NET developers will all be able to benefit from this guide. To fit the maximum amount of information in this book while keeping it concise and pocketsized, this book is written under the assumption that readers already know the following. How to use ASP.NET to build Web applications How to develop ASP.NET applications with either Visual Basic .NET or C# How to work with Microsoft Windows 2000 Server or Microsoft .NET Server and Internet Information Services
How This Book Is Organized The goal of this book is to provide an easy-to-use guide to ASP.NET configuration. To do this, I have divided the book into logical parts. By looking at the Table of Contents, or even just by flipping through the book, you should be able to find the answer you are looking for. 1
The book is broken down into the following parts and chapters. Part I, Overview of Microsoft ASP.NET Configuration The chapters in this section provide an overview of the ASP.NET configuration files and the architecture that surrounds them. Chapter 1 is an introduction to how the ASP.NET configuration works and a look at the structure and format of the configuration files. Chapter 2 looks “under the hood” of the configuration model to see how the files and settings actually work. Part 1 of this book will give you a better understanding of how ASP.NET configuration works and make it easier for you to use the other parts of this book. Part II, ASP.NET Configuration Settings The chapters in this section are a complete guide to the sections, settings, and values that can be used in the ASP.NET configuration files. Chapter 3 is a guide to working with section declarations and adding or removing values from the section. Chapter 4 covers the sections and settings for the System.Web namespace, which includes the majority of the settings that you will be using with ASP.NET. Chapter 5 is a guide to the settings that configure the Microsoft Mobile Internet Toolkit, which is now included with ASP.NET 1.1. Chapter 6 is a guide to the settings for the other .NET namespaces, including the System.Net and System.Diagnostics namespaces, among others. Chapter 7 is a guide to working with the configuration sections that contain settings for the .NET common language runtime. Chapter 8 is a walkthrough of the configuration settings that are configured using the Internet Information Services management tool. Part III, Creating Custom Settings This section covers how to use custom settings in the configuration files. Chapter 9 is a complete walkthrough of how to add custom sections and settings and use them in your applications. Part IV, Appendix and Glossary The appendix covers the security configuration tool, which is used to set the security levels of assemblies.
Conventions Used in This Book I’ve used a variety of elements to help keep the text clear and easy to follow. You’ll find code terms and listings in monospace type, except when I tell you to actually type a command. In that case, the command appears in bold type. When I introduce and define a new term, I put it in italics. This book also includes the following elements. To provide additional details on a particular point that needs emphasis.
Note Tip
To offer helpful hints or additional information.
Caution More Info Real World
To warn you when there are potential problems you should look out for. To provide more information on a subject. To provide real-world advice when discussing advanced topics.
I very much hope that Microsoft ASP.NET Setup and Configuration Pocket Reference finds a home on your desk and that you find this book useful while developing ASP.NET applications. If you have any questions or comments, please feel free to send them to me in care of Microsoft. Thank you for reading this book!
2
Support Every effort has been made to ensure the accuracy of this book and the companion content. Microsoft Press provides corrections for books and companion content through the World Wide Web at http://www.microsoft.com/mspress/support. To connect directly to the Microsoft Press Technical Support Knowledge Base and enter a query about a question you might have, go to http://www.microsoft.com/mspress/support/ search.asp. If you have comments, questions, or ideas about this book and do not find your issue mentioned in the Knowledge Base, please contact Microsoft Press using either of the following methods: Postal Mail: Microsoft Press Attn: Editor, Microsoft ASP.NET Setup and Configuration Pocket Reference One Microsoft Way Redmond, WA 98052 E-mail:
[email protected] Please note that product support is not offered through the mail addresses. For support information, visit Microsoft’s Web site at http://www.microsoft.com/support.
3
Part I: Overview of Microsoft ASP.NET Configuration Chapter List Chapter 1: Introduction to the Microsoft ASP.NET Configuration Chapter 2: Examining the ASP.NET Configuration Architecture
Part Overview Part 1 covers how the ASP.NET configuration model works and provides a solid overview of the ASP.NET configuration model, which will aid in the understanding of the rest of this book. Chapter 1 details the structure and format of the configuration files, as well as the security and modification detection features of the configuration model. Chapter 1 also includes a walk through of editing a configuration file. Chapter 2 focuses on the architecture of the configuration model and how the settings are interpreted and used by the Microsoft .NET Framework.
4
Chapter 1: Introduction to the Microsoft ASP.NET Configuration Highlights This chapter covers the structure and format of the configuration files, demonstrates how to edit a configuration file, and looks at the security and modification detection of the configuration model. Some of the features and benefits of the ASP.NET configuration model include: The configuration settings are stored in XML files with the .config extension. This enables you to edit the files with a text editor. The configuration files are cached by the Microsoft .NET Framework and not “locked,” which enables you to make changes to live configuration files with minimal impact on users. Settings can be configured in multiple configuration files and propagated from server to application and from parent application to child application. This enables you to configure settings for a server, application, directory, or even a single file. Custom sections and settings enable you to specify your own custom settings, which can be stored in the configuration files and accessed by your applications. Configurations files are secure and cannot be accessed through HTTP requests.
ASP.NET Configuration Overview ASP.NET and the .NET Framework include a very powerful and adaptable configuration model based on XML configuration files. These files contain a large range of different configuration settings that can be specified using well-formed XML. When a change is made to one of the configuration files, the configuration settings are recompiled and recached the next time the file or application is accessed. After the compilation, the configuration files are cached, not locked, so you can continue to modify the files. Because the files are XML, you can use any text editor to edit the files. The two main file types that you will use are called machine.config and web.config. The machine.config file contains the settings for the entire server and the base settings that are used for each web application. The machine.config file can be found in the c:\%winndir%\Microsoft.Net\Framework\version\config directory. Replace version with the installed version of the .NET framework. Note
%winndir% represents the Windows installation directory, whether that is c:\winnt, c:\windows, or another directory.
The web.config file contains settings that are specific to the application and to any child applications or directories. The web.config file for a web application is stored in the root directory of that application. Settings in an application’s web.config file can override the settings contained in the machine.config file. The settings in a particular web.config file can be overridden again by an additional web.config file in a child application of that application. For instance, if tracing is disabled in the machine.config file of a server, that would be the default setting for all the ASP.NET applications running on the server. If you enabled tracing in the web.config file of the ASP.NET web application App1, tracing will be enabled for App1 but still disabled for all other applications because settings in the web.config file take precedence over settings in the machine.config file. If a child application to App1 is added, the child application will also 5
have tracing enabled because it will inherit first from the machine.config file, and then from the web.config file of App1. This is covered in more detail in Chapter 2, but for now remember that server-level settings are stored in the machine.config file and can be overridden by application level settings that are stored in each application’s individual web.config file.
Dissecting the ASP.NET Configuration Files The machine.config and web.config files serve different roles in the configuration architecture, but the format and available settings of the files are virtually identical. Because the files are XML based, there are some XML rules that pertain to the configuration files. XML is case sensitive, so the files are case sensitive as well. Tag sets must have a start tag and an end tag. For instance, must have a closing or be self closing . Tags can have multiple attributes and values, and the values must be contained inside parentheses. Because the files are case sensitive, it is important to know the two different conventions that are used in the configurations files: Camel caseEach word is all lower case except for the first letter of appended words. For example, appSettings, maxRequestLength, userName. Pascal caseEach word starts with a capital letter, including the first and any appended words. For example, PublicKeyToken, RemoteOnly, AutoGenerate. This stripped down machine.config file shows the different sections and general structure of the file. <sectionGroup name="system.web"> <section name="httpRuntime" type ="System.Web.Configuration.HttpRuntimeConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <section name="compilation" type= "System.Web.Configuration.CompilationConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <system.web> At the beginning of the machine.config file is an XML declaration. This specifies that the file is an XML 1.0 compliant document and uses UTF-8 encoding. The next line is the start of the configuration data. This is the opening tag of the tag set that contains all the different configuration sections and settings. At the end of the file there is a tag. All the sections and settings must be in between these two tags. There are a variety of section types located between the configuration tags.
Configuration Section Handler Declaration The section is first in the configuration files. This section provides configuration section handler declarations for each of the configuration sections that follow. Each configuration section is linked to a handler that will process the settings for that section. Each declaration links its configuration section to a handler that will process the settings for that section. A configuration handler is a class that implements the IConfigurationSectionHandler interface and interprets the different settings and values of a configuration section. More Info
An interface is a kind of .NET blueprint. The interface contains methods that the implementing class must contain. In this example, the class that implements IConfigurationSectionHandler must contain the Create() method. 7
Let’s take a closer look at one of these declarations. <section name="httpRuntime" type= "System.Web.Configuration.HttpRuntimeConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> Thename=setting specifies the name that will be used when declaring the section later in the configuration file. In this example, it is httpRuntime. The type=setting specifies the handler that will process the section and interpret its values. In this example, the handler is the class System.Web.Configuration.HttpRuntimeConfigurationHandler. The type=value is the GAC info needed to locate the correct class. More Info
The GAC, or Global Assembly Cache, is the .NET Framework’s method of storing references to different .NET assemblies that need to be available to multiple applications.
Inside is also where section groups are declared. You can see that multiple declarations are grouped under a section group like this. <sectionGroup name="system.web"> <section name="httpRuntime" type= "System.Web.Configuration.HttpRuntimeConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <section name="compilation" type= "System.Web.Configuration.CompilationConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <system.web> 8
This means that the sections named httpRuntimeandcompilationmust be located in the system.websection group. Declaration handlers are covered in detail in Chapter 2, and creating custom handlers are covered in Chapter 9.
Section Groups As shown in the declarations section, different configuration sections can be grouped into section groups for organizational purposes. This makes it much easier to read and understand all the different configuration sections. Here’s how sections are grouped into groups. <system.web> Different sections are grouped inside tags representing the declared section group name. In this example, the httpRuntime and compilation sections are grouped under the system.web section group.
Configuration Sections Configuration sections are the meat of the configuration files; these sections are where all the different settings are configured. The sections use the name that was declared in the section handler declaration and can contain multiple settings, values, and sub-sections. This is a configuration section from the sample machine.config. This section groups a number of different settings like executionTimeout and maxRequestLength that are all related to the HTTP runtime. These settings are also all handled by the same configuration handler, which is specified in the handler declaration area. The section name is always presented in Camel case.
Sub-Sections Sections can also contain sub-sections. A sub-section is a setting that allows multiple values. Sub-sections are part of the parent section and handled by the same configuration handler. This example compilation section contains a number of different sub-sections. The section name is compilation and it contains a sub-section for compilers and multiple sub-sections named compiler. There is no limit to the number of sub-sections that a section can contain. Sub-section names should always follow the Camel case convention.
Settings Configuration settings are found in either sections or sub-sections and include the name of the setting followed by an equal sign and a value enclosed in parentheses. Here is a setting and its value. The name of the configurations section is compilation, the name of the settings is debug, and the value of the setting is set to the Boolean value false. The names of settings almost always follow the Camel case convention. The values generally follow the Pascal case convention, but there are a couple of exceptions. The words true and false are always lower case. The value of a setting can also be a literal string, like a database connection string, and in that instance, it does not conform to any casing standard.
Applying Configuration File Modifications When a user first accesses a URL, ASP.NET looks at the machine.config file and any applicable web.config files and determines what configuration settings should be applied to that URL. This information is then cached so that on the next request to that URL, the information is available without having to read from the configuration files again. When a change is made to an applicable configuration file, the cached settings are removed, and the next time the URL is accessed, the process starts over again. 10
Because the applications do not have the files open while they run, you can freely modify the files without worrying about stopping the application. After the changes have been made, you can simply save the file, and the next time the affected page is accessed, the settings will be applied—virtually seamless to the users visiting the site. There is no compilation of the configuration files, which can be both a good thing and a bad thing. It is a good thing because it makes it possible to edit the files with a normal text editor and does not require any sort of special application or compiler. It can be a bad thing because there is not a step between the modification of the file and the application recompiling with the new configuration. If there is an incorrect value, the application will throw an error on compilation, or if the modification was in the machine.config file, all the applications would throw an error. This would make the application unavailable to users until the error could be corrected. For this reason, it is always a good idea to test configuration changes on a development server before performing the change on the production server.
Looking at Security Files with the .config extension cannot be accessed through a browser. Any attempts to access the files are responded to with an HTTP 403 Access Denied Error. This is the same level of protection that is applied to .aspx files. It is obvious why you would not want these files to be viewable by the public, and this level of security ensures that they can’t be. Because the general public cannot access this information, you can store database connection strings, passwords, and license keys in the configuration files with confidence that they will be secure.
Editing Configuration Files Let’s take a quick look at editing a configuration file, which is a pretty simple procedure. If you have edited configuration files before, you can skip this section. 1. Navigate to C:\winnt if you are running Windows 2000 or C:\Windows if you are running Windows XP. 2. Open the Microsoft .NET Directory. 3. Open the Framework Directory. 4. Open the directory that is named after the version of the Framework that you have installed, for example, “v1.1.4322”. 5. Open the CONFIG directory where the different .config files are available for editing. 6. Right-click the machine.config file, click Open With on the shortcut menu, and click Notepad in the list of applications. As shown in Figure 1-1, you can now see the XML text of the configuration file.
11
Figure 1-1: The machine.config file in Notepad. Because the files are XML, you can make changes right in Notepad. For this example, you are going to enable tracing for all the applications running on this server. To do so, you will need to find the trace configuration section, which can be seen in Figure 1-2.
Figure 1-2: The value that needs to be changed to enable tracing is highlighted. After you’ve found the trace configuration section, change the value of the enabled= setting from false to true. Doing so will enable tracing for all applications, unless of course 12
the web.config of that application overrides this setting. All you need to do now is save the configuration file. The modification of the file will be detected and the next time a user accesses an affected URL, the settings will be recompiled and cached again. Caution
Remember that there is no error-catching layer in this editing process. If you had set the value to truth instead of true, all the applications would fail. When a configuration handler encounters a problem, it throws a configuration error that will be displayed to users. You should be extra careful during the editing process, and if at all possible, apply changes to a stage or development server before making changes to the production server.
Configuring IIS What’s this? IIS? Internet Information Services? I thought we were done with changing settings and configuration applications in IIS. Although most settings for ASP.NET applications are configured in the .config files, you still have to use the Internet Information Services (IIS) admin tool for some of your configuration changes. When a user initiates a Web request, it is handled by IIS first. If it is an ASP.NET request, it is then routed to the ASP.NET runtime for processing. Because of this, some of the front-end settings still have to be configured in IIS so the request can be properly routed. To make the following changes, you will need to use the IIS admin tool. Creating and removing applications Setting and modifying security settings for applications Modifying file extensions handled by ASP.NET When working with Windows Server 2003, the ASP.NET process configuration settings are configured in IIS rather than the configuration files. How to make these changes is covered in Chapter 8.
Key Points ASP.NET Configuration files are XML based and have certain XML rules that must be followed, including case sensitivity, beginning and ending tags, and attributes enclosed in parentheses. The machine.config file settings apply to the entire server, whereas web.config files are application specific. If settings in an application’s web.config conflict with the serverwide machine.config settings, the web.config setting takes precedence. There are Section Handler Declarations, Section Groups, Sections, and Settings and Values all included in the configuration files. When configuration files have been modified, the changes are detected by the Framework and are applied when the affected files are next accessed. Configuration files are secure and cannot be accessed by HTTP requests. If it is attempted, an Access Denied Error is returned to the user. This chapter covered the basics of ASP.NET configuration. The next chapter looks under the hood of the ASP.NET configuration model and provides a better idea of how the configuration architecture works.
13
Chapter 2: Examining Architecture
the ASP.NET
Configuration
Overview The first chapter provided a quick overview of ASP.NET Configuration. This chapter takes a closer look at the configuration architecture and how it works. Topics covered in this chapter include: The rules of the hierarchical model, and how you can apply settings to a server, an application, a directory, and even a single file. How configuration sections are processed and how the values are accessed by applications. The internals of a sample configuration section handler.
Hierarchical Configuration Model As discussed in Chapter 1, the ASP.NET configuration model inherits settings from server to application through a hierarchical model. With a hierarchical model, you can specify settings in the machine.config or web.config file of a parent application, and those settings will propagate to any child applications. Child applications can inherit from parent applications, and all applications inherit from the machine.config file. You can specify settings for an entire server, a single or multiple applications, single or multiple directories, or even a single file. The following rules apply to the inheritance of configuration settings.
Applications first inherit their settings from the machine.config file of the server, then from the web.config file of any parent applications, and finally from their own web.config file. The settings in each web.config file override the settings from the machine.config and web.config files before it. Inheritance follows the URL of the requested resource and not necessarily the physical structure of the files. The settings in the machine.config file or a parent application’s web.config file can prevent settings from being overridden. The settings can be targeted to a specific directory, application, or file using the location setting.
To better demonstrate these inheritance rules, let’s take a look at a scenario involving multiple applications and directories. For this example, you will use three applications: App1, App2, and App3. Figure 2-1 is an overview of the virtual structure of these applications. More Info
The virtual structure of the applications is the structure when viewed through the IIS admin tool. This structure is not tied to the physical location of the directories and is simply how you set up the applications in IIS.
14
Figure 2-1. The virtual structure of the sample applications. In Figure 2-1 , App1 and App3 are root applications, and App2 is a sub-application of App1. More Info
App3 is a virtual directory in IIS. A virtual directory is a pointer from IIS to the real physical directory on the drive. The other applications are not virtual directories because they appear in the same location under the wwwroot on the physical structure as they do in the virtual structure.
The inheritance in the hierarchical model looks first at virtual structure, and then at the physical structure of the applications. Figure 2-2 shows the physical structure of the applications. Figure 2-2 shows that App1 is a sub-directory of the wwwroot directory, and that App2 and App3 are sub-directories of App1. You will notice that SubDir is also a sub-directory of App1, but it is not an application or virtual directory in IIS. 1. Enable tracing in the machine.config file on the server by following the steps in “Editing Configuration Files” in Chapter 1. By making this change in the machine.config file, tracing will be enabled for all the applications and .aspx files on the server. 2. Disable tracing in the web.config file of App1, the first Web application.
15
Figure 2-2. : The physical structure of the sample applications. You will see the following results on the following URLs when they are accessed. In this example we are using http://www.northwindtraders.com/ as the site name. Replace this with your site name when testing.
http://www.northwindtraders.com/App1 This URL inherits enabled tracing from the machine.config file, but the setting in the web.config file of App1, which disables tracing, overrides it. Therefore, tracing is disabled for this URL. http://www.northwindtraders.com/App1/App2 Because App2 is a sub-application of App1 in the virtual structure, tracing is disabled here also because App2 inherits from the web.config file of App1, and there is no conflicting setting in the web.config file of App2. http://www.northwindtraders.com/App1/SubDir All files in the SubDir directory have tracing disabled because they inherit the setting from the web.config file of App2. http://www.northwindtraders.com/App3 App3 still has tracing enabled because it inherits only from the machine.config file of the server. Even though it is a physical child of App1, it is not a virtual child of App1. http://www.northwindtraders.com/App1/App3 App3 is its own application, but it is still a sub-directory of App1 and can be accessed by that path. As a result, App3 has tracing disabled because it inherits from the web.config file of App1.
Note
This adds an interesting dimension because a single directory or application can have multiple configuration settings based on which URL is being used to access the resource.
The URL of the resource determines which configuration settings the resource will inherit. In other words, identical resources can inherit different configuration settings depending on the URL used to access them. With this understanding of how configuration settings are inherited from server to applications, let’s take a look at how to target configuration settings.
Targeting Configuration Settings By using the location tag, you can target settings to a particular path, application, or file. This is particularly useful when you want to use a different setting for a physical directory but don’t want or need to make that directory an application. For example, you might want a single directory to have different trace settings. You can accomplish this by using the location tag and adding the following text to the web.config file of App1. 16
<system.web>
<system.web> This disables tracing for all the files in the SubDir directory. Note
Notice that you will still need to include the system.web section group tag inside the location tag. Whenever you use the location tag, the name of the section group must be included.
Tracing would also be disabled for any sub-directories of the SubDir directory. You can also use this procedure to assign configuration settings to a single file. This disables tracing for the single file notracepage.aspx in the root directory of App1. Note
Using the location tag can be very useful when you want to set security permissions for a single file in your application. Keep in mind that this will only work on files that are handled by the ASP.NET process, which means that you can’t apply configuration settings to html or graphics files because they are handled by IIS and not ASP.NET.
Preventing Configuration Settings from Being Overridden As you have seen, you can override settings in the web.config file of an application. However, there are times when you might like to prevent settings from being overridden. Luckily, there is a setting that enables you to do this. By setting allowOverride to false in either the machine.config or web.config file, no matter what you specify in the inheriting web.config file of the application, in this example, tracing will always be disabled. <system.web>
<system.web> Real World
Preventing configuration settings from being overridden can be particularly useful if you are an administrator or run a hosting company. It would enable you to set global settings for your server that cannot be changed by your customers in the individual applications.
Keep in mind that if you use the allowOverride=”false” property, any application that attempts to override this setting will throw a configuration error. Be sure that none of the applications are attempting to set this value before you set it to allowOverride=”false” or using this property will break those applications.
Examining Configuration Section Handlers So far, I have covered where to specify the settings, how the settings inherit, and how you can target and lock settings. Now let’s look at how the configuration settings are used. Configuration section handlers process the settings that are specified in configuration files and make them available to applications. Configuration section handlers are classes that implement the IConfigurationSectionHandler interface. These classes interpret and process the configuration file settings and return a configuration object based on those settings. Configuration section handlers are first declared in configSections, as discussed in the last chapter. Let’s take a look at the configuration handler declaration again. <section name="appSettings" type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
This declaration is for the section of the configuration file. The section is used to store name/value pairs that you want to access from any of the application files. The declaration points the configuration file to the class that will 18
handle this section. Here is a sample section that adds a couple of sample name/value pairs. These settings can then be accessed from the applications, which makes it very simple to keep track of and change settings that you will need to use on different pages or in different applications. You have seen where the declaration handler is declared, but you cannot look at the actual declaration handler code of the .NET Framework. However, you can look at the Microsoft Shared Source CLI Implementation (codename: Rotor) source code for the same handler, which is the next best thing. More Info
The Microsoft Shared Source CLI Implementation, affectionately known as Rotor, is an open source implementation of a substantial portion of the .NET Framework made available from Microsoft. Although it is not the exact code that is used in the .NET Framework, it is very similar and it performs the same function. However, there will be numerous differences because the Rotor code is designed to be more portable and readable. For more information see http:// msdn.microsoft.com/downloads/default.asp?url=/ downloads/topic.asp?URL=/MSDN-FILES/028/000/ 123/topic.xml.
The following is the configuration section handler for the section, which is called NameValueFileSectionHandler. I have removed code unrelated to this discussion. //----------------------------------------------------------------// // //
Copyright (c) 2002 Microsoft Corporation.
All rights
reserved. //
The use and distribution terms for this software are contained in the file named license.txt, which can be found in the root of
// this //
distribution. By using this software in any fashion, you are agreeing
//
to be bound by the terms of this license.
//
You must not remove this notice, or any other, from this software.
// // //----------------------------------------------------------------19
#if !LIB namespace System.Configuration { using System.IO; using System.Xml; public class NameValueFileSectionHandler : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) { object result = parent; // parse XML XmlNode fileAttribute = section.Attributes.RemoveNamedItem("file"); result = NameValueSectionHandler.CreateStatic(result, section); if (fileAttribute != null && fileAttribute.Value.Length != 0) { / *Removed for Brevity, this section would handle if there was a file="" property in the appSettings section
*/
} return result; } } } #endif This handler checks if a file=”“ property is present, and then returns a value based on the NameValueSectionHandler.CreateStatic method if that property is blank. This is the method that will create the configuration object. This is the code for the NameValueSectionHandler. //----------------------------------------------------------------// // //
Copyright (c) 2002 Microsoft Corporation.
All rights
reserved. //
The use and distribution terms for this software are 20
contained in the file named license.txt, which can be found in the root of
// this
distribution. By using this software in any fashion, you
//
are agreeing //
to be bound by the terms of this license.
//
You must not remove this notice, or any other, from this software.
// // //----------------------------------------------------------------#if !LIB namespace System.Configuration { using System.Collections; using System.Collections.Specialized; using System.Xml; using System.Globalization; public class NameValueSectionHandler : IConfigurationSectionHandler { const string defaultKeyAttribute = "key"; const string defaultValueAttribute = "value"; public object Create(object parent, object context, XmlNode section) { return CreateStatic(parent, section, KeyAttributeName, ValueAttributeName); } internal static object CreateStatic(object parent, XmlNode section) { return CreateStatic(parent, section, defaultKeyAttribute, defaultValueAttribute); } internal static object CreateStatic(object parent, XmlNode section, string keyAttriuteName, string valueAttributeName) { 21
ReadOnlyNameValueCollection result; //
start result off as a shallow clone of the parent
if (parent == null) result = new ReadOnlyNameValueCollection(new CaseInsensitiveHashCodeProvider( CultureInfo.InvariantCulture), new
CaseInsensitiveComparer(
CultureInfo.InvariantCulture)); else { ReadOnlyNameValueCollection parentCollection = (ReadOnlyNameValueCollection)parent; result = new ReadOnlyNameValueCollection(parentCollection); } // process XML HandlerBase.CheckForUnrecognizedAttributes(section); foreach (XmlNode child in section.ChildNodes) { // skip whitespace and comments if (HandlerBase.IsIgnorableAlsoCheckForNonElement( child)) continue; // handle <set>, , tags if (child.Name == "add") { String key = HandlerBase.RemoveRequiredAttribute( child, keyAttriuteName); String value = HandlerBase.RemoveRequiredAttribute( child, valueAttributeName, true /*allowEmptyString*/); HandlerBase.CheckForUnrecognizedAttributes(child); result[key] = value; } else if (child.Name == "remove") { String key = HandlerBase.RemoveRequiredAttribute( child, keyAttriuteName); HandlerBase.CheckForUnrecognizedAttributes(child); result.Remove(key); } else if (child.Name.Equals("clear")) { 22
HandlerBase.CheckForUnrecognizedAttributes(child); result.Clear();
}
else { HandlerBase.ThrowUnrecognizedElement(child); } } result.SetReadOnly(); return result; } protected virtual string KeyAttributeName { get { return defaultKeyAttribute;} } protected virtual string ValueAttributeName { get { return defaultValueAttribute;} } } } #endif This code creates a configuration collection object that contains the different key and value pairs from the configuration section. I won’t spend a large amount of time focusing on this handler’s exact code, but let’s take a look at a couple of the more important parts. The CreateStatic method is called from the first section handler, and it will create the configuration object. This method creates a ReadOnlyNameValueCollection object that will hold all the different key and value pairs of information. Let’s take a look at the code that is used to parse the XML. if (child.Name == "add") { String key = HandlerBase.RemoveRequiredAttribute(child, keyAttriuteName); String value = HandlerBase.RemoveRequiredAttribute(child, valueAttributeName, true/*allowEmptyString*/); HandlerBase.CheckForUnrecognizedAttributes(child); result[key] = value; } If the XML child name is equal to “add,” this code adds the key/value pair to the ReadOnlyNameValueCollection object called result. When you reference the collection in the code, you access this collection to reference the values you are storing in this section. Configuration section handlers interpret and make available all the settings in a particular section. Chapter 9 will cover how to create custom configuration section handlers to interpret the settings for the custom sections. 23
Key Points
The hierarchical configuration model inherits from server to application and from application to application in a variety of ways. This inheritance is based on the URL that is used to access the resource in question. You can use the location tag to target configuration settings to a particular directory or even a single file. You can use the allowOverride setting to prevent a setting from being overridden by a later web.config file. Configuration section handlers make the settings in the configuration available to applications by processing the XML and returning a configuration object.
24
Part II: ASP.NET Configuration Settings Chapter List Chapter 3: Configuration Section and Application Settings Chapter 4: System.Web Configuration Settings Chapter 5: Mobile Controls Configuration Settings Chapter 6: Microsoft .NET Configuration Settings Chapter 7: CLR Configuration Settings Chapter 8: IIS Settings
Part Overview Part II of this book covers all the different ASP.NET configuration settings that you can use to customize applications. Chapter 3 covers the first two sections that appear in the configuration files: the and sections. Chapter 4 covers all the sections and settings directly related to ASP.NET, including all the different sections and settings in the System.Web section group. Chapter 5 covers the sections and settings pertaining to the Microsoft Mobile Internet Toolkit. Chapter 6 covers the settings for the rest of the Microsoft .NET Framework namespaces. Chapter 7 covers the settings for the Common Language Runtime. Chapter 8 covers the settings that you use with the IIS admin tool.
25
Chapter 3: Configuration Section and Application Settings Overview This chapter covers the and sections of the configuration files. You looked at the section in Chapter 1, and this chapter will go into more detail. This chapter also covers the section, which you can use to add settings to the configuration file and then access the settings from your applications. This chapter covers all the different sections, settings, and values for each of these different sections. You will also see how you can use these settings, including examples of common techniques. This chapter covers the following topics.
This section contains all the configuration section handler declarations. This was discussed in the last chapter, but now you will see the different elements that can be used in this section. This section enables you to store strings in a central location. This section uses a key/value pair to store and retrieve the string. You will see how to store these values as well as how to use this in an application.
Working with The section contains all the various configuration section handler declarations. Configuration section handlers are the .NET classes that interpret the settings and values contained in the configuration section. In the section, you can declare a new section, remove a section, and even clear out all the section declarations.
Declaring a Section The first element in the section is <section>. This element is used to declare a configuration section that will be used later in the configuration file. This is the syntax of the <section> element. <section name="SectionName" type="ConfigurationHandler" allowLocation="true | false" allowDefinition="true | false" /> Table 3-1 lists the <section> element’s attributes. Table 3-1: <section> attributes Attribute name
Attribute values
Name
string The name you will use when to refer to this section in your configuration file. This can be any value that does not conflict with another section name but for the most part the Pascal case convention is used to name the sections.
Type
string The configuration section handler. This should include full Global Assembly Cache location information for the class.
AllowLocation
true | false This determines if the section can be used inside a 26
Table 3-1: <section> attributes Attribute name
Attribute values location tag. A value of true means that the section can be used inside a location tag. A value of false means the section cannot be used inside a location tag.
AllowDefinition
Everywhere This value allows the section to be used in any type of configuration file. MachineOnly This value allows the section to be used only in the machine.config file. MachineToApplication This value allows the section to be used in either the machine.config file or the application configuration file.
This is an example of how to add a section to the configuration file. <section name="runtime" type="System.Configuration. IgnoreSectionHandler, Culture=neutral,
System,
Version=1.0.330.0,
PublicKeyToken=b77a5c561934e089" allowLocation="false" /> This example is the section declaration for the runtime section. In the name attribute, the name of the section is specified, which in this example is runtime. The type attribute points to the configuration section handler that will interpret this section; in this example, it is System.Configuration.IgnoreSectionHandler.
Declaring a Section Group The <sectionGroup> element declares a section group and the declarations for all the included sections. A section group is a logical grouping of multiple sections. In configuration files, each namespace that you will be configuring will have its own section group. Generally, machine.config files have various section groups including System.Web and System.Net. If you are going to include multiple configuration sections for your namespace, it is a good idea to place those sections in a section group. This is the syntax for declaring a section group. <sectionGroup name="section group name" > Table 3-2 displays the attribute for the <sectionGroup> element. Table 3-2: <sectionGroup> attributes Attribute name
Attribute value
Name
string The name of the section group. These names generally follow the Pascal case convention.
The following example declares the System.Web section group and includes a section declaration for the section. <sectionGroup name="System.Web"> <section name="httpRuntime" type= 27
"System.Web.Configuration.HttpRuntimeConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> Later in the configuration file, you will include the section inside the <sectionGroup>. <system.web> Removing a Section You can use the element to remove either sections or section groups from your configuration file. This is the syntax of the element. Table 3-3 lists the attribute for the element. Table 3-3: Attributes Attribute name
Attribute value
Name
string The name of the section or section group that you want to remove.
This is how to remove a section declaration that is inherited from an earlier configuration file. This example will remove the section from the group, which will prevent you from configuring the httpRuntime settings in the configuration file or any configuration files that inherit from it.
Clearing All Sections To remove all the sections and section groups, use the element. This element will remove all sections declared before it and any sections declared in earlier configuration files. This is how to use the element in the configuration files. _Machine.Config File‡ <section name="httpRuntime" type= "System.Web.Configuration.HttpRuntimeConfigurationHandler, System.Web, Version=1.0.3300.0, Culture=neutral, 28
PublicKeyToken=b03f5f7f11d50a3a" />
_web.config File‡
In the configuration file, the section would no longer be available. Although the section is not one of the more common sections when working with ASP.NET, it is very important to understand its function in the configuration architecture. Part III of this book looks at this section in even greater detail when you create your own sections and section handlers.
Working with The section enables you to store literal strings in the configuration file and retrieve these values from any application. The strings, or values, are stored with a key that is used to retrieve the string in the applications. Let’s look at the different elements that you can use in the section. Later you will look at the file attribute you can use to point to an XML file containing various elements.
Adding a Value When you have a string that you want to access from various files in your application, you can add it to the section of your configuration file. If you want the value to be available to all the applications on your server, you can also add it to your machine.config file. To add a value to the collection, you can use the element. To add a value, set a key that identifies the value in your collection and the actual value that you want to store. Use the following syntax to incorporate the element. Table 3-4: attributes Attribute name
Attribute value
Key
string This is the unique key that you will use to access the value in the collection. If you add a key that already exists in the collection, you will overwrite that value.
Value
string This is the value that you will store in the configuration 29
Table 3-4: attributes Attribute name
Attribute value file.
This example demonstrates how to add a database string to the configuration file: In this example, you add a key/value pair to the collection. The key is ConnString, and the value of the pair is the server connection string. At the end of this section, you will see how to access this value through ASP.NET. Real World
Being able to store a value like a database connection string in a central location is invaluable to good application design. If this connection value where to change, whether you are moving to a different server or simply changing the user name, you can change the string in one location and it will be updated everywhere. You don’t even need to recompile the applications because the changes take affect the next time the resource is accessed.
Removing a Value The tag is used to remove a key/value pair from the collection. You specify the key of the pair that you want to remove, and the specified pair will no longer be available through the collection. This can be very useful when you want to remove a setting that has been added to the collection in a higher level. For instance, a key/value pair that is added in the machine.config file can be taken out at the web.config level using the following syntax. Table 3-5 lists the attribute for the element. Table 3-5: attributes Attribute name
Attribute value
Key
string The key of the key/value pair that you want to remove from the collection.
The following is an example of how to remove the string that you added in the last section. This key/value pair will no longer be available to this application or any of the applications that inherit from this web.config file.
30
Clearing All Values The element can be used to completely clear out the collection. Like the element, you can use the element to remove different key/value pairs, but the element removes all the pairs. This is how you can use the element. Adding this element to the section completely clears it out.
Using the File Attribute The element includes only one attribute, the file attribute. The file attribute can be used to point to an XML file that contains , , or elements. This method is very similar to a server-side include in that it includes only the settings from the XML file. To use the file attribute, set the value in the section tag. Table 3-6 lists the attribute for the section.
Table 3-6: attribute Attribute name
Attribute value
File
string A relative path to an file. This path is relative to the application root of the ASP.NET application. Values can still be added to the section, but if there is a conflict, the values loaded from the file will override the values added in the section.
This is how to use the file attribute. To use the file attribute, you will need to create an XML file that contains numerous key/value pairs. This is a sample settings file that you can use in conjunction with the file attribute: As you can see, this file is a miniature configuration file with a single configuration section. Inside this section, the child elements are treated just as if they were written in the web.config or machine.config file. This is a very effective technique when you want to include the same values in multiple applications because you can create a file like this one and store it in a central location where all applications can access it.
31
Reading Values Now let’s take a look at how to read values from the section in ASP.NET. The configuration section handler for the section makes these settings available through a name value collection called <AppSettings>. This is the code that accesses the values in both VB.NET and C#. VB.NET Dim sConnString as string 'Create our string value 'Next we read the value from the collection sConnString = Configuration.AppSettings("connString") Dim oConn as SqlConnection 'Create our connection object 'Use our string to create the connection oConn = new SqlConnection(sConnString)
C# \\First we read our value from the AppSettings collection string sConnString
= Configuration.AppSettings["connString"];
\\Then we use our value to create our connection SqlConnection oConn = new SqlConnection(sConnString);
As you can see, it is very easy to access the values that you added to the configuration file. Simply access the <AppSettings> collection and use the name that you specified in the configuration file. The section makes it easy for you to add various values to the configuration file. This is particularly valuable when working with values that you will use on many different pages because you will not have to change the value on each page. Instead, you change it in the configuration file and each page will read the new value.
Key Points
You can use the section to declare sections and section groups. You can use the and elements to remove sections or section groups declared in an earlier configuration file. You can use the section and the element to add values to a collection that can then be accessed from various files or applications. You can use the and elements to remove and clear values that are declared in earlier configuration files.
The next chapter covers how to configure the System.Web namespace.
32
Chapter 4: System.Web Configuration Settings This chapter covers all the different settings available in the <System.Web> section group. This section group contains a large number of settings that can configure ASP.NET, and this chapter examines them all. You will spend the majority of your time working in this section group. The following sections are covered in this chapter.
This section configures the type of authentication employed for your ASP.NET applications. This section configures the authorization of your Web applications. Authorization is the act of determining whether a user should be allowed to access the resource. This section defines the browser capabilities search strings. It works with the browser capabilities component to determine the type of browser being used to access your Web application. This collection-based section contains aliases that link to a specific user agent. These aliases can force a page to render for a specific browser. This section contains settings that configure the compilation of ASP.NET pages. You can use this section to add new programming languages that can be used with ASP.NET. <customErrors>This section customizes the error messages that are sent to users. This section configures the globalization settings for the server or application. This section configures and adds new HTTP handlers. HTTP handlers are the classes that handle requests to various file extensions. This section configures and registers additional HTTP modules. HTTP modules are used to perform operations on the HTTP request before the HTTP handler handles it. This section contains settings that configure the HTTP runtime. This section configures and implements impersonation for your Web applications. <machineKey> This section configures the encryption keys that will be used by the other sections. <pages> This section contains settings that configure the page-level settings for all the pages affected by the configuration file. <processModel> This section contains settings that configure the ASP.NET ISAPI extension. This section is not used when running Windows Server 2003. <securityPolicy> This section declares mappings of named security levels to the correct security policy file. <sessionState> This section configures how session information will be stored for your Web applications. This section configures how the ASP.NET trace service behaves. <trust> This section configures the security level under which the application runs. <webControls> This section configures where the client-side validation script file is located. <webServices> This section contains settings that configure the XML Web services created using ASP.NET.
Working with the Section Authentication is the process of verifying the identity of the user accessing an application. Authentication does not determine if the user is allowed to access a particular resource; that is done by the section in the <System.Web> system group. 33
Authentication verifies only a user’s identity so authorization can determine if that user can access the requested resource. Authentication plays a huge role in developing ASP.NET applications, and in this section, you see how to configure the authentication method used for your application. By working with the configuration files, you can configure your application to use a number of authentication methods. The authentication modes available include the following.
Windows Authentication This method of authentication relies on Microsoft Windows to validate a user. Windows requests a user name and password when a user accesses a site, and then validates the user name and password against the Windows users. This method is very popular on intranets because most users already have domain accounts that can be used for authentication. Forms Authentication This method of authentication uses a basic ASP.NET form to accept a user name and password that can be verified against a database or XML file. This method is popular on Internet sites because it does not rely on the operating system user database. Passport This method of authentication enables users to log into a site using their Microsoft Passport. A Microsoft Passport is a single user name and password (administered by Microsoft) that can be used at many different sites.
To configure the authentication of your application, you will work with the section, which is contained in the <System.Web> section group. This section contains a number of settings and elements that you can use to configure the authentication of your application. Unlike most sections contained in the <System.Web> section group, this section can be used only in the web.config file for your root application. It cannot be configured for an individual directory or file.
Configuring the Authentication Mode The first step in configuring the authentication for your application is to set the mode of authentication. To do this, you need to use the mode property of the element. Here is the syntax of the mode property. The mode property has a number of values that you can use to set different authentication modes. The values are listed in Table 4-1.
Table 4-1 : mode property values Property value
Description
Windows
This value specifies Windows authentication mode. This value should be used whenever Windows is providing user authentication.
Forms
This value specifies forms authentication mode.
Passport
This value specifies that Microsoft Passport is used authenticate users.
None
This value sets the authentication mode to none; that is, no 34
Table 4-1 : mode property values Property value
Description authentication mode is used.
Configuring Authentication Mode for Windows Authentication The first step to setting the mode of authentication to Windows is to add the following line to your web.config file. This is the only change needed in your web.config file. The next step is to set up the method of Windows authentication you will use. To set up Windows authentication, you will use the IIS administration tool. You can use this administration tool to set up Basic, Digest, or Integrated Windows Authentication. Because this section is about using the configuration files, I won’t cover how to set up Windows authentication in the IIS admin tool here. Chapter 8 covers the IIS admin tool and configuring Windows authentication. Configuring Authentication Mode for Forms Authentication In forms authentication, users submit their user name and password for authentication in an ASP.NET form. You will use a variety of sections and settings to set the authentication mode of your application to forms authentication. The ASP.NET configuration files make it easy for you to use and even automate some of the tasks involved. The first step is to set the mode to forms. The next step involves a new element that is used in the section: the element. The element contains properties with settings that you need to configure before using forms authentication. These settings configure the authentication cookie that authenticates a user. Here is the syntax for this element.
Table 4-2 lists the properties, descriptions, and possible values of the element. Table 4-2: properties Property name
Description
name
This property is set to the name of the cookie that is used for authentication. The default value is .ASPXAUTH, but if you have multiple applications running on the same Web server, you will need to customize this value so different cookies are used for each application. 35
Table 4-2: properties Property name
Description
loginUrl
This property is the URL of the page that contains the logon for your site. Requests will be redirected to this page when an unauthenticated user tries to access a page. The default value for this property is default.aspx.
protection
This property specifies the type of encryption used for the authentication cookie. Possible values include: AllSpecifies that the cookie should use both data validation and encryption. This is the default value. NoneSpecifies that both validation and encryption are disabled for cookies. This can be very useful when cookies are not necessarily essential to the application but you are using them to personalize a site. EncryptionSpecifies that the cookie will be encrypted using Triple-DES or DES, but it will not have data validation performed on it. ValidationSpecifies that the cookie will be validated by a scheme that verifies that its contents have not been altered in transit. The cookie is created by concatenating a validation key with the cookie data, computing a message authentication code (MAC), and appending the MAC to the cookie. This protection value ensures that the information has not been tampered with or altered in an attempt to compromise the security of the site.
timeout
This property specifies the time in minutes after which the authentication cookie will expire.
path
This property specifies the path used for the authentication cookie. By default this value is (/).
requireSSL
This property specifies whether SSL is required to transmit the cookie. The possible values are: trueSpecifies that SSL is required. falseSpecifies that SSL is not required. The default value is false.
slidingExpiration
This property specifies whether sliding cookie expiration is enabled. Sliding cookie expiration resets a cookie’s timeout on each request to the application. If a cookie has a timeout of 10 minutes and sliding expiration is not enabled, the cookie expires 10 minutes from when the cookie was first assigned. If sliding cookie expiration is enabled, the cookie expires 10 minutes from the last request to the application. trueSpecifies that sliding expiration is enabled. falseSpecifies that sliding expiration is disabled. The default value is false. This property is new to ASP.NET 1.1.
Here is an example of the element. 36
In this example, I set the name of the cookie to .SiteCookie, the URL of the logon page to login.aspx, and the protection level to all. Setting the protection level to all means that the cookie will be protected through both data validation and encryption. The timeout for the cookie is set to 30 minutes, the path to “/,” and SSL is not required. Sliding Expiration is set to true, which means that the timeout for the cookie will be reset for each request. The timeout value for the cookie is a very important setting. Nothing is more frustrating than filling out a long form and submitting it only to find out that your cookie has expired and the information might be lost. Be sure to either make the timeout long enough or break up long forms across a number of pages.
Real World
Before I discuss how to incorporate forms authentication in your application, let’s look at the sub-element. The sub-element of the element contains a list of user names and passwords that can be used to authenticate users. This is not the only option for maintaining a list of user names and passwords, but it is one of the easier methods and it can be very useful for sites with a small, rarely changed, user/password list. To use the section, first set the passwordFormat property of the element. Here is the syntax for the and passwordFormat property. Table 4-3 lists the available values for the passwordFormat property. Table 4-3: passwordFormat values Value
Description
Clear
This value specifies that the passwords are stored in plain text with no encryption.
MD5
This value specifies that the passwords are stored using the MD5 hash algorithm.
SHA1
This value specifies that the passwords are stored using the SHA1 hash algorithm.
After the method of storing passwords is set, user name and password pairs can be stored in the section using the <user> element. Here is the syntax of the <user> element. <user name="user name" password="encrypted password" / > <user name="user name2" password="encrypted password" 37
/>
The name property is the user name, and the password property is the user’s encrypted password. You can store a group of user names and passwords in the section and then authenticate against this group from your application. Implementing Forms Authentication Now let’s look at the ASP.NET code necessary to use form authentication. Here are the configuration settings for this example. <user name="James" password="HisPassword" /> <user name="Tammy" password="HerPassword" /> The next step is to build your logon.aspx page. This page will accept the user name and password and then authenticate the information against the information in your configuration file. Here is the form you will use to capture the user name and password. Username:
Password:
This is just a simple ASP.NET form that accepts a user name and password, and runs a server-side event when the login button is pressed. Here is the code used to validate this information against the user names and passwords stored in the configuration file. C# <script language="C#" runat="server"> void btnLogin_OnClick(object sender, EventArgs e) { if(FormsAuthentication.Authenticate(tbUserName.Text, tbPassword.Text) { FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, 38
cbPersist.Checked); } else { lblResults.Text = "Invalid Username and Password"; } }
VB.NET <script language="vb" runat="server"> Sub btnLogin_OnClick(sender as object, e as EventArgs) If FormsAuthentication.Authenticate(tbUserName.Text, _ tbPassword.Text) Then FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, _ cbPersist.Checked) Else lblResults.Text = "Invalid Username and Password" End If End Sub
Let’s look at this code step by step. If FormsAuthentication.Authenticate(tbUserName.Text, _ tbPassword.Text) Then First this code checks if the supplied user name and password authenticate against the stored user names and passwords. Because in this example the user names and passwords are stored in the configuration file, you use the FormsAuthentication.Authenticate() method to authenticate the supplied user name and password against the pairs in the configuration file. For larger, more robust applications, the user names and passwords will need to be stored in a database where they can be modified quickly. When storing user names and passwords in a database, you will need to create a method that checks for a matching pair in the database and returns a value of true or false. This method could be used in place of the FormsAuthentication.Authenticate method and this example would work nicely. If either the FormsAuthentication.Authenticate method or your custom method returns a true value, the following line is processed.
FormsAuthentication.RedirectFromLoginPage(tbUserName.Text, _ cbPersist.Checked) 39
This line of code calls the FormsAuthentication.RedirectFromLoginPage method. This method returns the user to the referring page (the page that the user form transferred from, which is stored in the ReturnURL querystring value) or if there is no referring page, the user is transferred to default.aspx. The first parameter supplied is the user name and the second is a Boolean value representing whether the authentication cookie should be persisted. If the second value is set to true, the cookie is persisted indefinitely, otherwise, the cookie will timeout after the amount of time you set in the configuration file. If the FormsAuthentication.Authenticate() method or the custom authentication method returns false, you have to let the user know that he or she needs to try again. Else lblResults.Text = "Invalid Username and Password" End If In this code, you set the label text to the message that lets the user know that the user name and password did not authenticate. This is all that is necessary to implement forms authentication on your Web application. Here’s how this authentication works with your application. When users try to access a protected portion of the application, they are redirected to the logon.aspx page. A user logs onto the logon.aspx page and an authentication cookie is created. Depending on whether the cbPersist check box is selected, this cookie is persisted or times out after a set amount of minutes. The user is then returned to the page that he or she originally tried to access. Configuring Passport Authentication The last type of authentication I will cover is Microsoft Passport authentication. Microsoft Passport is a single user name and password with which a user can access sites all over the Internet. This method of authentication has already been adopted by a number of companies, including CitiBank and Monster.com. Although this is a great feature to offer to your visitors, it does require certain licensing that might be too expensive for small sites. In addition, this type of authentication would not be appropriate for an intranet site in which Windows authentication is easily available. The first step to configuring Passport authentication is setting the authentication mode to Passport. The authentication section includes a <passport> element that contains a single property called redirectURL. The redirectURL property is used to point to the page where a user signs in. This URL should point to the Passport logon page that authenticates users for your site. Here is the syntax of the <passport> element. <passport redirectURL="url" /> If an unauthenticated user attempts to access a protected portion of your Web application, he or she will be redirected to the URL specified in the redirectURL property. This is the only configuration setting needed when setting up Passport authentication.
Key Points The authentication section contains a number of very important settings. Here are the key points for working with the section. 40
You can set the mode property of the authentication section to Windows, forms, or passport authentication. You configure the Windows authentication settings with the IIS administration tool. The forms authentication method uses the element to configure various settings for the authentication cookie. You can configure and implement forms authentication on your application with an ASP.NET form and a small bit of .NET code. The passport authentication method uses the <passport> element to configure the location of the passport login page.
Working with the Section After the authentication method verifies a user’s identity, authorization determines whether that user is allowed to access the resource. Authorization can be configured for the server, site, application, sub-directory, or a single page. ASP.NET authorization is based on allowing or denying access based on either the user name or on a role of the user. When a user requests a resource, the ASP.NET process checks if that user has permission to do so before the request is processed. If the user is authorized, the request is processed. If the user is denied, a 401 error is returned. There are two elements that are used in the section: and <deny>. These elements allow or deny access to the resource based on the user name, role, or how the resource is accessed. The ASP.NET process assumes that the user can access the resource, and unless there is a deny rule that applies to the user, the process will grant the user access. Here is the syntax for using the and <deny> elements. <deny users="list of users" roles="list of roles" verbs="list of verbs" /> Both of these elements contain the same properties, which are listed in Table 4-4. Table 4-4: and <deny> properties Property
Description
users
This property is a comma-separated list of users who are either allowed or denied access to the resource. A question mark (?) is used to represent anonymous users and an asterisk (*) is used to represent all users. By placing the domain name in front of the user name. (mydomain\domainuser), you can use this property to authorize domain users as well.
roles
This property is a comma-separated list of roles that are allowed or denied access to this resource. If you are using Windows authentication, Windows groups are used as roles. If you want to use other roles, you will need to create and manage them through your own code.
verbs
This property is a comma-separated list of HTTP access methods 41
Table 4-4: and <deny> properties Property
Description that are allowed or denied to this resource. Available verbs are GET, HEAD, POST, and DEBUG.
Here is an example of how you can deny access to anonymous users and then grant access to a number of different users. <deny users="*" /> In this example, when James or Tammy logs into this site, they will be allowed to access this resource. All other users will be denied. The process will look only for the first rule that applies to the user, and that rule will determine if the user is given access to the resource. In this example, when Tammy tries to access this application, the process will find the first rule and grant her access. If the rules were listed the other way around, she would be denied access because the first rule that applies to her is a deny rule. After the process finds the first rule that applies to the user, it stops reading from the configuration file. Real World
The ability to include domain users in the users property can be very useful when you are building an intranet site. If users are already logging into a domain, and you are using Windows authentication, you can easily set up your application security without any additional user names or passwords. Users simply need to remember to include the domain name followed by a backslash(\) in front of the user name (mydomain\James).
The roles property allows or denies access based on the role of the user. Here is an example of using roles to allow access. <deny users="*" /> In this example, you deny access to all users, and then allow access to any users who are members of the Windows Power Users group. You can use the Windows groups because in this example you are using Windows authentication. If you are not using Windows authentication, you will need to build your own implementation of roles. The other option for allowing and denying access to users is the verb property. The verb property allows or denies access based on how the user is accessing the application, whether the user is accessing it using the GET, POST, HEAD, or DEBUG HTTP method. Here is an example of allowing POST access to the administrator, and denying it to all other users. <deny users="*" verbs="POST" /> 42
In this example, users in the Windows Admins group are allowed to POST to the application; all other users are denied access if attempting to POST to the application. I discussed the location tag in Chapter 2 briefly, but now let’s see how to use the location tag with authorization to control who can access an individual file. In the next example, you will use the location tag to specify the authorization permissions for a single file called admin.aspx. <System.Web> <deny users="*" /> In this example, the only user who would be able to access the admin.aspx file is the user identified as Administrator. Using the location tag is the only way that you can apply authorization permissions to a single file. Real World
Using the location tag comes in very handy when you want to restrict a single directory or single file. You can use the location tag to restrict access to the administration section of your application without having to add a second logon.
You can also apply authorization permissions to a sub-directory of the application. There are two methods of doing this. Use the location tag as in the example just shown and list the name of the directory in the path property. Add a web.config file to the sub-directory and include the authorization permissions in that file.
File Authorization So far, I have discussed request-based authorization, but there is another type of authorization that can be used with ASP.NET. With Windows authentication, if a user attempts to access the .aspx or .asmx file, the ASP.NET process performs an access control list (ACL) check to see if the user has permission to access that file. This means that ASP.NET checks if the user has NTFS permissions to access the file as well as if the user has request-based authorization to access the URL. This provides you with an additional way to restrict users from accessing particular files, but it can be used only when using Windows authentication.
Key Points Authorization is crucial to securing your applications. ASP.NET authorization is based on the URL that the user is accessing and a combination of and <deny> rules in your configuration section. Here are the key points to remember when working with the section.
43
ASP.NET authorization is performed when a user requests a resource. The request is allowed or denied based on the rules contained in the authorization section of the configuration file. You can allow or deny users based on the user name, the user’s roles, or the HTTP method used to access the resource. ASP.NET will use the first rule it finds that applies to the user accessing the resource. ASP.NET assumes that a user has permission to access a resource. The user is denied only if there is a deny rule applied to the requesting user. You can use the location tag to target authorization settings for a directory or even a single file.
Working with the Section ASP.NET uses the section to detect the type of browser that is accessing the application. There are many different browsers, mobile devices, and cell phones that can browse the Web, and each browser can handle a different mix of HTML, script, and other browser features. This section makes it possible for ASP.NET to serve the correct mix of HTML and client-side script for each browser and keep track of what browser can handle which features. Because determining what browser is accessing an application is not what I would call an exact science, this section relies on the HTTP request header and regular expressions to determine what browser or mobile device is accessing the application. When a client requests a file from the server, the client sends an HTTP request including a header. This header contains a number of variables including one that identifies the type of browser accessing the resource, but the name and value of this variable is not exact. ASP.NET reads this value and uses regular expressions to determine the browser and browser version that are accessing the page. This method of detection is not exact, but it is about as close as we are going to get. After ASP.NET determines the type of browser accessing the page, it can customize the HTML output that it sends back to the browser. The information needed to customize the HTML output is also contained in this section, from whether a browser supports frames or tables, to the color depth and screen size of a mobile device. The machine.config file contains a large amount of information in the section. This information includes regular expressions and settings for a large number of browsers and mobile devices. A company called cyScape publishes this information and in the future, you should be able to find updates on their Web site at http://www.cyscape.com/browsercaps. (Currently there are no updates available.) This company also publishes the BrowserHawk browser detection software. However, there have been updates to the mobile controls portion of this section. For more information about the mobile controls updates, please see Chapter 5. The majority of developers do not need to know how to add new browsers or customize settings; they need only to know how to replace the existing information with updated information when it is released. No updates have been released yet, but I assume it will be a pretty simple procedure that does not require much more than cutting and pasting the information into your machine.config file. Some developers will need a deeper understanding of this section, including how the section works and how to add custom browsers or mobile devices to the configuration section.
Understanding Elements There are a number of elements that can be used in the section. The first element in the section is the element. The element specifies the name of the class that holds all the information gathered from the 44
section. Here is the element from the machine.config file on the server. The type property points to the class that holds all the name/value pairs. The class pointed to by the result tag can then be used by the ASP.NET process to read the values and customize the HTML output. The section uses IIS server variables pulled from the HTTP request header. The <use> element defines which server variable will be used as the information source. Here is an example of using the <use> element. <use var="HTTP_USER_AGENT" as="Agent" /> This example specifies that the browser capabilities information will be pulled from the “HTTP_USER_AGENT” IIS server variable. The as property makes the server variable available to the rest of the section. In this example, you would reference the Agent variable in the section, and read the data from the server variable. Later in this chapter, I cover a couple of ways that this is used, but first let’s look at the other element that can be used in the section. The heart of the section is the element. This element matches regular expressions to text found in the server variables and then lists the browser settings that should be included in the browser class. Here is the syntax of the element. name=value name=value The regular expression in the match property is compared to the string in the with property. If there is no with property declared, the string declared in the <use> statement is used. If there is a match between the regex listed in the match property and either the string in the with property or the string declared in the <use> statement, the name/value pairs listed are included in the browser caps class and generate the correct HTML to send to the client. The element includes a sub-element named . The element is used much like the element in that it contains both match and with properties that can match regular expressions to strings. The element is used much like the way a case statement is used in VB. Multiple elements can be included in a element. When a statement is found to match, it will skip the rest of the statements in that group. Here is the syntax for using the element. name=value name=value name=value name=value 45
The first element that finds a match is used and all the other case elements are ignored. This can be a little confusing, so let’s look at an example. <use var="HTTP_USER_AGENT" /> platform=Win95 platform=Win98 platform=WinXP platform=Win2000 This example has no with properties declared, so the elements will search the string that was declared in the last <use> statement. In this case, that string is the HTTP_USER_AGENT server variable. Here is how this element is processed. 1. The first case is processed, and the HTTP_USER_AGENT variable is searched to see if it contains the strings “Windows 95” or “Win95.” 2. If the string contains one of these values, the name/value pair inside the element is added to the browser capabilities class stated in the element. 3. If a match is found, none of the other elements are processed and the element is complete. 4. If a match is not found, the next element is processed and this procedure is repeated. If no match it found, the element is completed without adding any name/value pairs to the class, and the next element begins. In this process, the section handler steps through the section filter by filter and case by case until the browser capabilities class is filled with name/value pairs that describe the browser or device being used to access the resource. To get a better grasp on this, let’s look at a more complex element taken directly from the machine.config file. <use var="HTTP_VIA" as="via"/> gatewayVersion = ${nokiaVersion} gatewayMajorVersion = ${gatewayMajorVersion} gatewayMinorVersion = ${gatewayMinorVersion} This is one of the more complex elements, whose purpose is to detect if the accessing device is a Nokia device. If it is a Nokia device, the element extracts the gatewayVersion, the gatewayMajorVersion, and the gatewayMinorVersion from the server variable. This information is added to the browser capabilities class and can be referenced when tailoring the HTML to be sent back to the browser. There are a couple of conventions used in this statement that were not used in the prior statement; most of these involve the use of regular expressions. I will detail each of them as you go through this statement. The first element in this example is the <use> element. <use var="HTTP_VIA" as="via"/> This element makes the “HTTP_VIA” server variable available to the elements as the via variable. The <use> element is necessary because the information you are looking for is not held in the default HTTP_USER_AGENT server variable, but in the HTTP_VIA variable. Here are the first and elements. The first statement searches the via variable for the Nokia string. If the Nokia string is found in the via variable, the and elements inside the statement will be processed. Here’s a closer look at the and elements included in this statement. gatewayVersion = ${nokiaVersion} gatewayMajorVersion = ${gatewayMajorVersion} gatewayMinorVersion = ${gatewayMinorVersion} The statement in this example matches a number of different variables and makes them available to the browser capabilities class, which will custom tailor the HTML sent to the browser. If you look through the section in the machine.config file, you will find many different and elements that look much like the one just shown. The amount of information here is amazing; it gives ASP.NET the ability to customize HTML for a large number of browsers and mobile devices. 47
Key Points The section makes it possible to customize HTML output for a large number of browsers and mobile devices. You will most likely not need to use this section in your day-to-day development duties, but it is important to know the role this section plays and how this information can be updated in the future to accommodate new browsers or mobile devices. Here are the key points about this section.
The section customizes HTML output based on the browser or mobile device that is accessing the resource. The section uses server variables made available by the HTTP request header to determine what browser or device is accessing the resource. Regular expressions are used to match strings against the request variables to not only determine what browser or device is accessing the resource, but also the version of the browser and its various capabilities. Updates to this information should soon be available from http://www.cyscape.com/browserCaps.
Working with the Section For the majority of the pages you build in ASP.NET, you can rely on the browser detection performed by ASP.NET and the section, but there are times when you’ll want to target or force a page to the level of a particular browser. This is where the section comes into play. The section contains a number of browser aliases that can be used to generate content targeted to a particular browser. Each alias contains a matching userAgent value that represents the targeted browser. The userAgent value is the string that is found in the userAgent server variable when the user accesses the application. This section works much like the or sections in that you can add, remove, or clear out aliases from the section. Here is the default section in the machine.config file. Each alias is added to the collection and linked to a specific userAgent value. The first two aliases target Internet Explorer 4 or 5 level browsers. These targets are very similar, if not the same as using the uplevel browser target. The uplevel alias forces a page to render ASP.NET controls using uplevel settings. The last alias type is the downlevel alias, which forces a page to render ASP.NET controls in downlevel mode.
Uplevel vs. Downlevel There are a number of differences in how ASP.NET controls render, depending on whether clientTarget is set to uplevel or downlevel. A downlevel browser is one that only understands HTML 3.2. If you target a page to the downlevel alias, the page will use only 48
HTML 3.2 when sending HTML to the browser. An uplevel browser or device should be able to handle the following technologies.
ECMAScript version 1.2 (JScript, JavaScript) HTML 4.0 CSS The Microsoft Document Object Model (MSDOM)
When you target a page to uplevel browsers, the page will render using CSS, HTML 4.0, ECMAScript 1.2, and the MSDOM to take full advantage of all the capabilities of the target browser. Examples of uplevel browsers are Internet Explorer 4.0 and above, among others.
Using Client Target in Your Pages It is easy to target your pages to a particular client target alias. Every ASP.NET page has a @page directive at the top of the page, and the @page directive has a property called clientTarget. This property can be set to an alias that is present in the collection, and the page will render based on that alias. Here is an example of using the clientTarget property. This page will now render using only downlevel technologies, meaning HTML 3.2. This setting will override any browser detection that is performed by ASP.NET and the section. Real World
An example of the usefulness of the clientTarget property is when working with the TabStrip Web control. When targeting up-level browsers, the tab strip renders using layers, and then switches the layers when a tab is pushed without using a postback. When the control targets a downlevel browser, it sends only one layer to the browser and sends postbacks whenever a tab is pushed. Although the uplevel version of the control is faster, it causes all the tabs to be loaded no matter what tab is currently being viewed. For this reason, I among others have used the clientTarget property to force the tab strip control to render in downlevel mode. This has the unfortunate effect of forcing the entire page to downlevel mode.
Adding and Removing Aliases It’s easy to add and remove aliases from the section using the same elements you use in the section. Here is the syntax for adding aliases to the section. The alias property is referenced from the clientTarget property of the ASP.NET page. The userAgent property replicates the userAgent server variable that would be sent with the browser. If you want to add a new alias based on a specific browser, you capture this userAgent server variable when the browser accesses your site, and then use the userAgent value to add the alias and target the browser in the future. 49
Here is the syntax of how to remove an alias that was defined in an earlier section. Removing an alias from the collection will make that alias unavailable to any pages affected by this configuration file. Just like in the section, you can also use the element to clear out all the aliases previously added to the section. Here is the syntax for the element.
Key Points The section enables you to bypass the default ASP.NET browser detection and target your pages to a particular browser or range of browsers. Here are the key points pertaining to the section. The section works just like the section in that you can use the , , and elements to add, remove, and clear out the collection. You can use the clientTarget property of the @page directive to force a page to render for a particular browser, rather than the browser detected by ASP.NET.
Working with the Section The section includes a number of settings and elements that enable you to configure how ASP.NET is compiled. You can use various elements to add new ASP.NET scripting languages compilers and custom assemblies, and configure various compilation settings. The section has a number of sub-sections, but first we are going to look at the properties that can be set in the element. Here’s the syntax of the element.
Table 4-5 lists the properties for the element.
Table 4-5: properties Property
Description 50
Table 4-5: properties Property
Description
batch
This property controls compilation is supported.
whether
batching
trueBatching is enabled. falseBatching is disabled. batchTimeout
This property specifies the timeout period for batching compilation to complete. If the compilation does not complete in this time frame, the compiler reverts back to single page compilation for just this page.
debug
This property specifies whether debug binaries are compiled. trueDebug is enabled. falseRetail binaries are compiled.
defaultLanguage
This property specifies the default programming language to be used by ASP.NET. This name must match one of the names declared in a sub-tag. The default value is vb.
explicit
This property sets whether the Visual Basic explicit option is enabled. Visual Basic’s explicit option requires that each and every variable is declared using the Dim, Private, Public, or ReDim statement. trueExplicit is enabled. falseExplicit is disabled.
maxBatchSize
This property specifies the maximum number of files that will be included in a batch compilation.
maxBatchGenerated FileSize
This property specifies the maximum size in kilobytes of the generated source file for each batch compilation.
numRecompilesBeforeAppRestart
This property specifies the number of dynamic recompiles that can occur before the entire application is restarted.
tempDirectory
This property specifies the directory to use for temporary file storage during compilation.
strict
This property specifies whether the Visual Basic strict compile option is enabled. The Visual Basic Strict option ensures best programming practices by throwing errors when performing unadvised operations like implicit conversions that could cause data loss. trueStrict is enabled. 51
Table 4-5: properties Property
Description falseStrict is disabled.
Table 4-5 includes a lot of new information, so let’s cover some of it in more detail.
Visual Basic explicitBy default, Visual Basic enables you to use variables that have not been explicitly declared, but this is not a good practice. The Visual Basic Explicit option ensures that each variable is declared using the Dim, ReDim, Private, or Public statement. If you use Visual Basic .NET, I would strongly suggest leave this option enabled in your configuration file. Visual Basic strictBy default, Visual Basic enables some questionable programming operations. When you enable the Strict option, Visual Basic throws an error if either of the following programming procedures are performed. Implicit conversion, which could lead to data loss. Late binding, which is the assigning of a variable that was declared as an object. Batch CompilationPages are compiled when first accessed, which causes a slight delay to the user accessing the page. Batch compilation compiles all the files that have not been compiled in a directory when the first file in that directory is accessed. This means that the first file accessed will be even slower, but there will be no delays at all for subsequent requests.
Here’s a sample section. There are also a number of sub-sections that can be used in the section. The section declares the compiler programs that can be used to compile ASP.NET pages. There are a number of default compilers included with ASP.NET, and you can add compilers to process languages including Delphi. Here’s the syntax of the section. The properties for the section are listed in Table 4-6.
Table 4-6: properties Property
Description
language
This property is a semicolon separated list of language names. These are the names that the language can be referenced by in 52
Table 4-6: properties Property
Description the language property of the @page directive.
extension
This property is the file extension of the code file for this language. Examples are .cs for C# and .vb for Visual Basic.
type
This property is the class that is used to compile files programmed using this language.
warningLevel
This property is the warning level of the compiler.
compilerOptions
This property is a list of options that will be passed to the compiler during compilation.
Here is the entry for the C# language. By listing three different language names, you can use any of those names(c#; cs; csharp) when specifying c# in the @page language property. The element enables you to add a new programming language with which to write ASP.NET.
Adding Assemblies to Compilation If you have ever used one of the .NET command line compilers, you know you need to include the assemblies that you want to use while compiling the application. The section adds the assemblies that should be included when compiling ASP.NET applications. Like the section, this section assembles a collection of the assemblies to use when compiling ASP.NET applications. Here is an example of how to add an assembly to the section. This assembly would be included whenever ASP.NET applications are compiled. You can also remove assemblies using the element. When an assembly is removed from the collection, it is no longer included in the compilation of ASP.NET pages. Again, just like the other collection-based sections, you can use the element. 53
This clears out all the assemblies previously added to the collection.
Key Points The compilation section includes a number of important settings for optimizing the compilation of ASP.NET pages. Here are the key points for working with the section.
The strict and explicit properties of the element enable you to set the Visual Basic strict and explicit settings to true for all your ASP.NET files. Batch compilation can help make the user experience much smoother by compiling all the ASP.NET pages that have not been compiled when the first of those pages is accessed. The element enables you to add languages (even languages like COBOL.NET!) for programming ASP.NET. The section enables you to add assemblies that will be included during the compilation of ASP.NET pages.
Working with the <customErrors> Section The <customErrors> section enables you to control the error messages that users see. This is a very important step in developing a user-friendly application. There are two types of errors that can be sent to users.
HTTP Errors HTTP errors are thrown for a number of reasons including when a page is not found (404) or access is denied to a page (403). Code ErrorsErrors in your code can be caused by a connection to a database failing, an invalid cast, or any number of illegal procedures.
By default, both of these error types produce an “ugly” error message that is sent to a user. This is not only an aesthetic issue but a security issue as well because the error message could include sensitive user name or password information. The <customErrors> element has two properties: the mode property and the defaultRedirect property. Here is the syntax of the <customErrors> element. <customErrors mode="On" defaultRedirect="customerror.aspx"> The mode property determines when the “friendly” error messages should be displayed and when the actual error should be displayed. Table 4-7 lists the possible values for the mode property.
Table 4-7: mode property values Value
Description
On
This value enables custom errors. If no defaultRedirect page is specified, users are presented with a generic error message. A generic message will not reveal the reason for the error, only that an error has occurred. (The error message is big and yellow; I will show 54
Table 4-7: mode property values Value
Description you how to change this as well.)
Off
This value disables custom errors. When disabled, users will see the complete error message whenever an error occurs. Although not desirable when your applications are in production, this information is invaluable during development and debugging stages.
RemoteOnly
This value is the best of both worlds: the RemoteOnly setting presents a complete detailed error message when the application is accessed from the system that hosts it, but when accessed by a different system, only friendlier custom errors are displayed. If you develop on the same machine that hosts your application, this value is very useful because it will not require changes when you move from development to production.
When an application is in development, you want to see detailed error messages so you should set the mode to either Off or RemoteOnly. When the application has been pushed to production, it is essential to set the mode to On or RemoteOnly so that users do not see the detailed error messages. When the mode is set to RemoteOnly or Off, the user sees a generic error message (the big ugly yellow page). It would be nice to be able to customize this generic error message for the application and perhaps include the company logo or technical support instructions. The defaultRedirect property is used to set the generic error message to a page other than the default. This way you can create a custom error message for your application and then set the URL of that page in the defaultRedirect property of the <customErrors> element. Here is an example of the defaultRedirect property. <customErrors mode="On" defaultRedirect="customerror.aspx"> Whenever there is an error in the application, the user will see the customerror.aspx instead of a detailed or generic error message.
Customizing HTTP Error Messages You can further customize this error message by using the <error> element to redirect certain HTTP errors to custom error pages. The <error> element enables you to specify a particular HTTP error code and the page to which users will be redirected. Here is the syntax of the <error> element. <customErrors mode="On" defaultRedirect="customerror.aspx"> <error statusCode="HTTP status code" redirect="httperror.aspx" /> Table 4-8 lists the properties for the <error> element.
Table 4-8: <error> properties Property
Description
statusCode
This property specifies the HTTP code to which this redirection 55
Table 4-8: <error> properties Property
Description will apply. Whenever this type of error occurs, the user will be redirected to the URL specified in the property.
redirect
This property specifies the URL that the user will be redirected.
The <error> element enables you to further customize the error messages for each type of HTTP code. For instance, you might want to have a different error message for a 404 error code vs. a 403 error code. For a 404 error code, you would want to display a message containing a method of searching for the page that could not be found. For a 403 error code, you would most likely want to provide the user with login information or possibly a way for the user to get a password reminder. More Info
You can add custom error handling to your applications using the Application_Error method in the global.asax. This is beyond the scope of this book, but it is an effective method of catching each error produced by an application and sending the user to another page, or generating an e-mail based on that error. You can find some great this procedure at this URL: information on http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnaspnet/html/asp07232001.asp
<customErrors> Key Points The <customErrors> section enables you to customize the error messages that are sent to users.
The mode property of the <customErrors> element enables you to specify the type of errors that are displayed to users. The defaultRedirect property enables you to specify a custom error page where users are sent when an error occurs on your site. The <error> element enables you to customize your error messages even further by specifying custom error pages for specific HTTP error codes.
Working with the Section ASP.NET has the capability to handle requests, responses, and files through a number of encoding methods. The section enables you specify the encoding type and culture for various ASP.NET operations. Here is the syntax for the section. Table 4-9 lists the properties for the section.
Table 4-9: properties Property
Description 56
Table 4-9: properties Property
Description
requestEncoding
This property specifies the expected encoding type for incoming requests including post and querystring data. This value can be overridden by the Accept-Charset value of the request header. By default this value is set to UTF-8.
responseEncoding
This property specifies the type of encoding to use when responding to requests. The default value is UTF-8.
fileEncoding
This property specifies the type of encoding of the various ASP.NET file types including .aspx, .asmx, and .asax.
culture
This property specifies the default culture setting for incoming Web requests. Appendix B lists all the available culture strings.
uiCulture
This property specifies the default culture setting for locale-dependent resource searches.
Here is a sample section. This sets the request, response, and file encoding to UTF-8 and the culture to English. Caution
If you set the fileEncoding property to use UTF-16 encoding and the file is not actually encoded with UTF-16, the output sent to the client could be corrupted and might even include the source code for the page. If you set the fileEncoding property to UTF-16, make sure all of your pages are encoded using UTF-16.
Key Points Globalization plays an important part in developing applications in the multi-cultural Internet world of today.
You can set the type of encoding for requests, responses, and ASP.NET files using the properties of the element. You can set the culture for Web requests using the culture property of the element.
Working with the Section HTTP handlers are classes that process HTTP requests for a particular file extension, much like ISAPI extensions. HTTP handlers exist for .aspx, .asmx, .rem and many of the other default ASP.NET file extensions. The section maps HTTP requests to the correct HTTP handler based on the HTTP verb, the file extension, and the URL of the resource. The section is yet another collection-based section, which means that you can add, remove, and clear out entries in the section. Here is the syntax for adding a HTTP handler mapping to the section. 57
Table 4-10 lists the properties of the section.
Table 4-10: properties Property
Description
Verb
This property is a comma-separated list of the HTTP verbs that this mapping should apply to. You can also use a wildcard (*) to map all HTTP verbs to the handler.
Path
This property is the location where you specify the URL that this mapping should apply to. Generally, the path is a wildcard that includes all files of a particular extension, for instance, *.aspx.
type
This property is the .NET class/assembly that is the HTTP handler.
validate
This property is a value that specifies when ASP.NET loads the HTTP handler class. When set to false, ASP.NET does not load the HTTP handler class until a request comes that fits the criteria listed in the request mapping. When set to true, the class will be loaded when the configuration file is first processed.
Here is a sample of the .aspx handler mapping. Whenever a request using any of the HTTP verbs is made for a page with the .aspx extension, the page will be handled by the System.Web.UI.PageHandlerFactory HTTP handler. You can remove an HTTP handler mapping using the following syntax. You use the ever-popular element to clear out any handler mappings added in earlier configuration files. Next let’s look at how to create a custom HTTP handler for a new extension type.
58
Creating a Custom HTTP Handler ASP.NET makes it easy to create custom HTTP handlers that can handle requests for custom file extensions or file paths. In this section, you see how to create a very simple HTTP handler and map it to a new extension, .asbx. There are three types of HTTP handlers: synchronous, asynchronous, and handler factory. A synchronous handler processes the entire request before returning results to the user. An asynchronous handler processes lengthy requests and enables you to send information back to the user during different steps of the request processing. HTTP Handler factory handlers generate multiple handlers depending on the request. .aspx files are handled by a HTTP Handler factory handler so that each request can be passed to the page class for each file. The page class implements the IHttpHandler interface and is the handler for each page. A custom HTTP handler is a .NET class that implements either the IHttpHandler or the IHttpAsyncHandler interface. The first step in creating the handler is to declare the handler and implement the interface. C#
using System.Web; public class asbxHandler : IHttpHandler { }
VB.NET Imports System.Web Public Class asbxHandler Implements IHttpHandler End Class When implementing the IHttpHandler interface, you must include the ProcessRequest method and the IsReusable property. When an HTTP request is mapped to the HTTP handler, it calls the ProcessRequest method and passes the current HTTP context to the method. You can then use the HTTP context object to either read from the request or write to the response.
C# using System.Web; public class asbxHandler : IHttpHandler { public void ProcessRequest(HttpContext currentContext) { HttpResponse currentResponse = currentContext.Response; 59
currentResponse.Write(""); currentResponse.Write("You have accessed an .asbx file"); currentResponse.Write(""); } }
VB.NET Imports System.Web Public Class asbxHandler Implements IHttpHandler Public Sub ProcessRequest(ByVal currentContext as HttpContext) _ Implements IHttpHandler Dim currentResponse As HttpResponse = currentContext.Response currentResponse.Write("") currentResponse.Write("You have accessed an .asbx file") currentResponse.Write("") End Sub End Class
This is a very simple ProcessRequest method; it simply writes a short message to the user through the current HTTP context using the popular write method. When a user tries to access a .asbx file on the server, this handler is called and sends the simple message to the user. Before the handler will work, you must implement the IsReusable property. This property determines whether the handler will be kept in memory to be used again or disposed of and re-created the next time it is needed. Here is the code needed to implement the IsReusable property. C# using System.Web; public class asbxHandler : IHttpHandler { public bool IsReusable { get{return false;} } }
VB.NET 60
Imports System.Web Public Class asbxHandler Implements IHttpHandler Public ReadOnly Property IsReusable() As Boolean Implements _ IHttpHandler.IsReusable Get Return False End Get End Property End Class
Returning a value of false means the handlers will not be stored in memory but instead be disposed of after the request has been handled. The handler is complete, but you still need to register it in the configuration file. You also need to register the extension in IIS. All requests go through IIS before they are routed to the aspnet.dll ISAPI extension. If you want the file extension to be interpreted by the handler, you will also need to route the extension to the aspnet.dll ISAPI extension. Here is how to register the .asbx extension with Internet Information Services. 1. Open the IIS administration tool. 2. Navigate to the directory or application you want to add this extension to. 3. Right click the application or directory, and click Properties. 4. A screen similar to the one displayed in Figure 4-1 appears.
61
Figure 4-1: . The application or virtual directory properties page. 5. Click the Configuration button. The screen displayed in Figure 4-2 appears.
62
Figure 4-2: The application configuration mappings page. 6. Click the Add button to add a new extension to the mappings list. The screen displayed in Figure 4-3 appears.
Figure 4-3: Add extension mappings configuration page 7. Set the path to the ASP.NET ISAPI .dll file, which can be found here. :\%windir%\Microsoft.NET\Framework\v1.1.4322\aspnet_isapi.dll 8. Enter .asbx in the Extension box, and click OK. Now that the extension is routed to the ASP.NET ISAPI filter, you need to add the handler to the machine.config file on the server. Any requests with the .asbx extension will now be handled by the custom handler. To give you a better idea of the entire process, here is a walk through the short life of an HTTP request. A user requests a Web page from the Web server. The request is handled by IIS and is routed to the ASP.NET ISAPI extension. ASP.NET receives the request and passes it through a number of HTTP modules. (I will be covering those next.) After it has passed through the HTTP modules, it is sent to the custom handler. The handler’s ProcessRequest method is called, and the response is sent back to our user. This process occurs each time a resource that matches the handler mapping for the handler is requested.
File Extension-Based Security ASP.NET employs a large number of extensions, and many of them must remain hidden from users. Extensions like .config, .cs, or .vb must be protected so that users cannot access the files and read the code or configuration settings. This is done by routing the extensions to the ASP.NET IIS ISAPI extension, and then to the System.Web.HttpForbiddenHandler. This handler cancels the request and returns a 403 63
access denied HTTP error code. This is a very effective means of securing these extensions from any requests. You can also use this method of security for any custom file extensions that you do not want available to users by mapping your extension to the System.Web.HttpForbiddenHandler handler.
Key Points ASP.NET really puts the power in your hands when it comes to working with HTTP requests and creating custom handlers. Here is a list of the key points of the section. • • • •
The section enables you to add, remove, and clear out handler mappings. HTTP handlers are classes that implement one of the HTTP handler interfaces. These interfaces are IHttpHandler, IHttpAsyncHandler, and IHttpHandlerFactory. You can create custom HTTP handlers to handle requests to a custom file type. You can protect files from being accessed by users by adding a handler mapping entry for the file extension and mapping it to the HttpForbiddenHandler HTTP handler.
Working with the Section HTTP modules are components that sit between the ASP.NET HTTP runtime and the HTTP handlers. ASP.NET uses these modules for a number of procedures including authentication, authorization, and session management. With HTTP modules, you can perform operations on the HTTP request or the HTTP response on its way from IIS to the handler, and vice versa. Modules can encrypt, compress, authenticate, or record the request and response streams, among other things. Using the section, you can configure the default HTTP modules as well as register your own custom HTTP modules.
Adding a Module The section is a collection-based configuration section. You can add, remove, and clear entries from this collection much like the other collection-based sections. Here is the syntax for adding a module to the section. The properties for the element are listed in Table 4-11.
Table 4-11: properties Property
Description
type
This property specifies the HTTP module class.
name
This property specifies the name of the http module. This name can be used to remove the module if needed.
You can remove an HTTP module using the following syntax. 64
This removes the specified module from the collection. This is very useful when you are trying to implement your own custom forms authentication because you can easily remove the default forms authentication module and add your own.
Creating a Custom HTTP Module You can create a module to do anything from compressing the HTTP response to authenticating the HTTP request. In this example, you create a simple module that adds a company copyright notice to the end of each one of the requests. First you’ll create a basic class structure. Let’s look at the basic structure of the module. C# using System; using System.Web; using System.Collections; public class CopyrightModule : IHttpModule { public void Init(HttpApplication application) { } public void Dispose() { } }
VB.NET Imports System Imports System.Web Imports System.Collections Public Class CopyrightModule Implements IHttpModule Public Sub Init(ByVal application as HttpApplication) _ Implements IHttpModule.Init
65
End Sub Public Sub Dispose() Implements IHttpModule.Dispose End Sub End Class
This is the base of the class. The class first implements the IHttpModule interface, which requires two methods: the Init and Dispose methods. The Init method enables you to wire up HTTP events to your custom event handlers. The Dispose method enables you to clean up any connections or resources before the module is closed. There are a number of events that you can wire up in the Init method, each of which is fired at a different stage in the HTTP request execution process. Table 4-12 lists all the events that you can wire up in our HTTP module.
Table 4-12: HTTP application events Event
Description
AcquireRequestState
This event occurs when ASP.NET first acquires the current state for the current request. Use this event if you need to change the state of the request.
AuthenticateRequest
This event occurs when ASP.NET establishes the identity of the user generating the request.
AuthorizeRequest
This event occurs when ASP.NET has verified the user authorization.
BeginRequest
This event occurs when ASP.NET starts processing a request. It is the first event in the process that you can use.
Disposed
This event occurs when the HTTP application has been disposed.
EndRequest
This is the last event in the ASP.NET request execution.
Error
This event occurs when the application throws an unhandled exception.
PostRequestHandlerExecute
This event occurs when the ASP.NET HTTP handler finishes executing.
PreRequestHandlerExecute
This event occurs just before ASP.NET passes the request off to the HTTP handler.
PreSendRequestContent
This event occurs just before ASP.NET sends content to the user.
PreSendRequestHeaders
This event occurs just before ASP.NET sends the HTTP headers to the user.
ReleaseRequestState
This event occurs after ASP.NET has finished 66
Table 4-12: HTTP application events Event
Description executing all the request handlers. This event triggers the state modules to save the current state data.
ResolveRequestCache
This event occurs when ASP.NET completes the authorization event. This event then triggers any caching modules to serve cached pages instead of passing the request to a handler.
UpdateRequestCache
This event occurs when ASP.NET completes executing a HTTP handler. This event then triggers any caching modules to cache the response for future requests.
All these events are available in custom HTTP modules. Let’s look at how to add events to a custom HTTP module. The first step is wiring up the event in the Init method. C# public void Init(HttpApplication application) { application.EndRequest += (new EventHandler(this.Application_EndRequest)); }
VB.NET Public Sub Init(ByVal application as HttpApplication) Implements _ IHttpModule.Init AddHandler application.EndRequest, _ AddressOf Me.Application_EndRequest End Sub When the module is initialized, the Application object’s EndRequest event is wired to the Application_EndRequest method. When the response is about to be sent, the Application_EndRequest method is called and the Application_EndRequest modifies the response. In this code, the method modifies the response.
C# private void Application_EndRequest(Object source, EventArgs e) { HttpApplication application = (HttpApplication) source; 67
HttpContext context = application.context; context.Response.Write("Copyright James Avery 2003"); }
VB.NET Private Sub Application_EndRequest(ByVal [source] As [Object], _ ByVal e As EventArgs) Dim application as HttpApplication = CType([source], _ HttpApplication) Dim context As HttpContext = application.Context context.Response.Write _ ("Copyright James Avery 2003") End Sub
When a request is made to an ASP.NET application, the request is processed as normal. Right before the response is sent, the method is run and the copyright text is added to the end of the request. Before the module is processed, you need to register it in your configuration file. The copyright module will now be processed during the HTTP execution and the copyright text will be appended to the end of the response stream.
Key Points The section and custom HTTP modules enable you to work directly with the HTTP pipeline. The section is a collection-based section in which you can add, remove, and clear out HTTP modules. HTTP modules are .NET classes that implement the IHttpModule interface. This interface requires the class to include both an Init method and a Dispose method. The HTTP application exposes a number of events that you can capture in the module. Each of these events occurs at a different step in the HTTP execution and enables you to modify the request and response objects at different times in the process.
Working with the Section The section includes a number of various settings pertaining to the ASP.NET HTTP runtime. The settings available in this section include the maximum allowable requests, request size, and request timeout settings. Here is the syntax for the section. Table 4-13 lists the properties of the section.
Table 4-13: properties Property
Description
appRequestQueueLimit
This property specifies the maximum number of requests that will be queued. When not enough free threads exist to handle a request, that request is queued. When the queue becomes full, the runtime returns a 503 Server Too Busy error. This setting specifies how many requests will be queued before that error is returned.
executionTimeout
This property specifies the maximum number of seconds that a request can run before being shut down by ASP.NET.
maxRequestLength
This property specifies the maximum request size supported by the runtime. This setting relates to the maximum file upload size because uploaded files are included in the HTTP request. This setting also helps protect your application from denial of service attacks because one method of attack includes sending very large files to the server. The default value for this setting is 4096 KB, or 4 MB.
minFreeLocalRequestFreeThreads
This property specifies the minimum number of threads that ASP.NET keeps available for the execution of new local requests. These threads are reserved for requests that come from the local host. Requests sometimes issue child requests to the local host, and if a request is not available, there is a deadlock. The special threads reserved for local host requests help prevent the possibility of a deadlock.
minFreeThreads
This property specifies the minimum number of free threads to use for the execution of new requests.
useFullyQualifiedRedirectUrl
This property specifies whether client-side redirects use fully qualified URLS or relative URLS. A fully qualified URL is one that includes the site information in the URL (for instance, http://server/path). A relative URL 69
Table 4-13: properties Property
Description includes only the path relative to the server already set (for instance, path /path/app2/admin.aspx).
versionHeader
This property specifies the version header value that ASP.NET sends with each HTTP response. This header value is used by Microsoft Visual Studio .NET to determine which version of ASP.NET is being used. This value is not necessary for production sites and can be disabled by setting the attribute to a blank value or removing the attribute.
Here is a sample section. One of the most widely modified settings is the maxRequestLength property. This property is commonly changed to allow the upload of larger files. Remember, though, that each time you increase the amount, you increase the susceptibility of your server to denial of service attacks.
Key Points The section enables you to configure a number of settings related to the ASP.NET HTTP runtime.
The maxRequestLength property controls the maximum allowable request size in Kbytes. This property also controls the maximum allowable upload, which protects your server from denial of service attacks. The appRequestQueueLimit property sets the number of requests that will be queued before users start getting 503 Server Too Busy errors.
Working with the Section The configuration section enables you to configure impersonation settings for your ASP.NET application. Impersonation is the ability of an application to act on behalf of a user when accessing other resources. After a user is authenticated with IIS, the authentication token is passed to ASP.NET and it can be used to impersonate the user to other resources. If the user is not authenticated with IIS, an unauthenticated token is passed to the ASP.NET application. Real World
Impersonation is very useful when working in an intranet environment that uses Windows authentication and where users are part of a domain. When users are authenticated with IIS, ASP.NET can impersonate that user when accessing file shares or servers. 70
Here is the syntax of the section. The properties of the section are listed in Table 4-14.
Table 4-14: properties Property
Description
impersonate
This property specifies whether impersonation is enabled. trueImpersonation is enabled. falseImpersonation is disabled.
username
This property specifies the user name to use if impersonation is enabled.
password
This property specifies the password to use if impersonation is enabled.
There are two modes of impersonation that you can employ in your application. The first mode uses the user name and password forwarded from IIS, and the second mode uses the user name and password specified in the configuration file. Here is an example of implementing the first mode of impersonation. This method of impersonation uses any user name and password passed from IIS to the ASP.NET runtime. Here is an example of how to implement the second type of impersonation. When your application attempts to access another resource that requires authentication, the user name and password specified here are used to authenticate for that resource. Storing the user name and password in a clear text format like this presents a security issue. The .config files are protected from requests by users and can’t be accessed through IIS or any other Web-based method. However, these files can be accessed if a user has access to the server or if the impersonated user has access to the file. It is possible to store the user name and password in an encrypted format in the registry. Here is how to do that. In the configuration file, set the user name and password values to: The configuration file will now read the user name and password values from the registry of the server.
71
To set the values in the registry, use the aspnet_setreg.exe console application. This is a small application that can be downloaded from the Microsoft Download Center or directly from this link. http://download.microsoft.com/download/asp.net/Utility/1.0/WIN98MeXP/ENUS/Aspnet_setreg.exe. Unzip the application, open a command prompt, and navigate to the directory where you unzipped the files. Type the following at the command prompt. aspnet_setreg –k:Software\AspNetLogin\Identity – u:UserName –p:Password Replace AspNetLogin\Identity with whatever key you would like to use. This key will be created for you. Replace UserName and Password with the correct user name and password values for your application. Find the key in the registry and check that the ASP.NET process has access to it by right clicking the key and clicking Permissions. If the ASP.NET user name is not listed, add it to the list. You will need to restart the IIS process before the permissions will take effect. These entries will now be encrypted in the registry and ready to be accessed from the configuration files.
Key Points The section provides settings that enable and disable impersonation for ASP.NET applications. The first mode of impersonation reads the user name and password from the authenticated token passed from IIS and uses it to access resources. The second mode of impersonation uses the user name and password that are specified in the configuration file. The aspnet_setreg.exe enables you to encrypt and store the user name and password in the registry and then read the values from the configuration file.
Working with the <machineKey> Section There are a number of objects and resources in ASP.NET that need to be encrypted for security purposes. The <machineKey> section contains validation and decryption keys used to encrypt a number of ASP.NET objects, including forms authentication cookie data, viewstate data, and out-of-process session state information. Here is the syntax of the <machineKey> section. <machineKey validationKey="validation key" decryptionKey="decryption
key"
validation="validation
/> The properties of the <machineKey> are listed in Table 4-15.
Table 4-15: <machineKey> properties 72
setting"
Property
Description
validationKey
This property specifies the key that will be used to validate the encrypted data. When enableViewStateMAC is set to true in the <page> section, this key creates a message authentication code (MAC) that ensures that the view state has not been modified. This key is also used to create out-of-process application specific IDs to keep session state variables isolated between different sessions. AutoGenerateSpecifies that ASP.NET should generate a random key and store it in the Local Security Authority. If you can add the IsolateApps modifier, ASP.NET generates a unique encrypted key for each application using the application ID. Specific ValueYou can manually specify the validation key so that the same value can be used across an entire Web farm. This value must be between 40 characters (20 bytes) and 128 characters (64 bytes) long.
decryptionKey
This property specifies the key that is used to encrypt and decrypt the forms authentication data as well as the view state information if validation is set to 3DES. AutoGenerateSpecifies that ASP.NET should generate a random key and store it in the Local Security Authority. If you add the IsolateApps modifier, ASP.NET generates a unique encrypted key for each application using the application ID. Specific ValueYou can manually specify the validation key so that the same value can be used across an entire Web farm. The key must be 16 characters in length when using DES encryption and 48 characters in length when using Triple DES encryption. Triple DES can only be used on systems where 128-Bit encryption is available.
validation
This property specifies the type of encryption that will be used to validate data. SHA1Specifies that validation will use SHA1 encryption. MD5Specifies that validation uses MD5 encryption. 3DESSpecifies that validation uses 3DES encryption. Forms authentication still uses SHA1 encryption.
Here is a sample <machineKey> section. <machineKey validationKey="AutoGenerate, IsolateApps" decryptionKey="AutoGenerate, IsolateApps" validation="SHA1 " /> In this example, both keys are auto-generated, and IsolateApps option is in effect. This is the default configuration set in the machine.config file.
<machineKey> Key Points The <machineKey> section is very important to the inner workings of ASP.NET, but it is not one that you use often in day-to-day programming. Here are the key points of this section. 73
The validationKey and decryptionKey can be autogenerated and specified manually. When working with a Web farm, you must specify the keys manually so they are consistent among all the servers in the farm.
Working with the <pages> Section The <pages> section contains page level configuration settings. These are the same settings that you can set on a page level in the @page directive, but they apply to all the pages affected by the configuration file. Here is the syntax of the <pages> section. <pages buffer="true | false" enableSessionState= "true | false | ReadOnly" enableViewState="true | false" enableViewStateMac="true | false" autoEventWireup="true | false" smartNavigation="true | false" pageBaseType="typename" userControlBaseType="typename" validateRequest="true | false" /> Table 4-16 lists the properties of the <pages> section.
Table 4-16: <pages> properties Property
Description
buffer
This property specifies whether the page should use response buffering. Response buffering prevents the response from being sent to the user until the response in complete. If buffering is disabled, the results are sent to the user as they are determined. trueResponse buffering is enabled. falseResponse buffering is disabled.
enableSessionState
This property specifies whether session state is enabled. trueSession State is enabled. falseSession State is disabled.
enableViewState
This property specifies whether view state is enabled. trueView State is enabled. falseView State is disabled.
enableViewStateMac
This property specifies whether view state is validated using a message authentication code(MAC). When enabled, the viewstate of a page is encrypted to ensure that it is not tampered with. trueMAC verification is enabled. falseMAC verification is disabled.
smartNavigation
This property specifies whether smart navigation is enabled. Smart navigation is a group of client side behaviors that simulates console application behavior through a browser. Internet Explorer 5.5 is required for smart navigation to be effective. trueSmart navigation is enabled. 74
Table 4-16: <pages> properties Property
Description falseSmart navigation is disabled.
pageBaseType
This property specifies the default code-behind class from which pages will inherit.
userControlBaseType
This property specifies the default code-behind class from which user controls will inherit.
autoEventWireup
This property specifies whether page events are automatically wired to event handlers. This event is normally enabled when you are using in-line code and disabled when using code-behind with VS.NET. trueAuto event wire-up is enabled. falseAuto event wire-up is disabled.
validateRequest
This property specifies that all the input from the browser should be examined for potentially dangerous data. If an dangerous code is found, HttpRequestValidationException is thrown. trueInput from the browser is checked. falseInput is not checked.
Here’s a sample <pages> section. <pages buffer="true" enableSessionState="true" enableViewState= "true" enableViewStateMac="true" autoEventWireup="false" smartNavigation="false" pageBaseType="PageClass1" userControlBaseType="UserControl1" validateRequest="true" /> The <pages> section includes a number of important decisions about your ASP.NET pages. These decisions can be made for each individual page or in the configuration file for a large group of page files. Let’s take a look at a couple of these decisions.
Enable or Disable View State? View state is a very important and useful feature of ASP.NET, but it can also quickly increase and bloat the size of your pages. Whether to use view state is a question you should ask yourself each time you create a new page or application. If you can create a page without using view state without losing functionality, you should do so. This is particularly important when creating Internet pages that might not rely on view state because this information would only make pages bigger. View state does add incredible functionality to Web applications and you should not shy away from using it, as long as it is necessary.
To Mac or Not to Mac? The ability to validate the information contained in the view state of a page is a very valuable resource, but this feature is disabled by default for a reason. The validation procedure has performance costs, and you have to consider that a key is encrypting the information, which has to be decrypted and verified when it is returned. Whether you should enable this feature depends on the information you are storing in view state. If your page does not use view state or uses it only for small controls that are not submitted to the 75
server, enabling this feature is most likely not justified, especially considering the performance cost involved. If you use view state to store the values of controls that contain sensitive data, especially data that will be resubmitted to the server, enabling the feature might be a smart decision. By default, view state is stored only in Base-64 encoded text and can easily be decoded, modified, and resubmitted to the server through an edited HTML file. MAC validation can prevent this data from being modified. The decision of whether to enable MAC validation is best done on a page-by-page basis, unless safety concerns outweigh the small performance hit.
<pages> Key Points The <pages> section gives you the ability to set @page level properties for all files affected by the configuration sections.
EnableViewStateMac enables MAC validation for all view state information. Validation ensures that users cannot tamper with the view state data. The decision to enable or disable view state should be made on a page-by-page basis because many pages might not need to employ view state at all.
Working with the <processModel> Section The <processModel> section is unique in the configuration file because it is completely ignored when you are running Windows Server 2003. In addition, when this section runs with Windows 2000 or Windows XP, it is read directly by the ASP.NET ISAPI extension. For this reason, any changes to the section require a restart of IIS before the changes take effect. If you are using Windows Server 2003, you do not need to worry about this section because you can modify these settings in the administration tool. For information about modifying these sections, refer to Chapter 8. When using Windows 2000 or Windows XP, this section contains a large number of settings pertaining to the ASP.NET process. Here’s the syntax of the <processModel> section.
<processModel clientConnectedCheck="amount of time" comAuthenticationLevel="authentication level" comImpersonationLevel= level" cpuMask="number" enable="true | false" idleTimeout="amount of time" logLevel= "event types" maxWorkerThreads="amount of threads" maxIoThreads= "amount of password="password"
threads"
memoryLimit="memory
size"
pingFrequency="amount of time" pingTimeout="amount of time" requestLimit="number of requests" requestQueueLimit= "number of requests" responseDeadlockInterval="amount of time" responseRestartDeadlockInterval="not used" serverErrorMessageFile="file name" shutdownTimeout= "amount of time" timeout="amount of time" userName="username" webGarden="true | false" />
76
There are a number of properties in the <processModel> section that require a time value. The formatting of this time value is Hours : Minutes : Seconds. It can also be set to Infinite. Table 4-17 lists the properties of the <processModel> section.
Table 4-17: <processModel> properties Property
Description
clientConnectedCheck
This property specifies how long ASP.NET leaves a request in the queue before it checks whether the client is still connected and waiting.
comAuthenticationLevel
This property specifies the security level that should be used for DCOM security. The default setting is Connect. DefaultSpecifies that the DCOM Authentication level is determined by its normal security negotiation algorithm. NoneSpecifies that no authentication is used. ConnectSpecifies that DCOM will authenticate the credentials of the client only when the client connects to the server. CallSpecifies that DCOM authenticates the credentials of the client at the beginning of each remote procedure call. PktSpecifies that DCOM authenticates that all data received is from the expected client. Datagram transports will always use Pkt authentication. PktIntegritySpecifies that DCOM authenticates that all data received from the client has not been modified. PktPrivacySpecifies that DCOM verifies that all data received from the client has not been modified and encrypts the arguments of each remote procedure call.
comImpersonationLevel
This property specifies the authentication level used for COM. DefaultSpecifies that impersonation level is determined by the normal security negotiation algorithm. AnonymousSpecifies that an empty impersonation token is used when the client is connected anonymously to the server. This value is disabled in version 1.1. IdentitySpecifies that the server will obtain the client’s identity. This identity can be used to impersonate the user for ACL checking but not to access other system objects. ImpersonateSpecifies 77
that
the
server
will
Table 4-17: <processModel> properties Property
Description impersonate the user whenever acting on behalf of the user. When using this level of impersonation, the token can only be passed across one machine boundary. DelegateSpecifies that the server can impersonate the user for both local and remote resources and pass tokens across multiple machine boundaries. This is the strongest level of impersonation.
cpuMask
This property determines the processors that are utilized on a multiple processor server. ASP.NET creates a worker process for each server on a system, and uses all the processors available on the server by default. Sometimes you’ll want to restrict the number of processors that ASP.NET is using, especially if other applications or databases are running on the server. A hexadecimal value is used to determine what processors should be used.
enable
This property specifies whether the process model is enabled. trueThe process model is enabled. falseThe process model is disabled.
idleTimeout
This property specifies how long ASP.NET will wait before ending the ASP.NET worker process. By default, this value is set to infinite.
logLevel
This property specifies the types of events that are logged in the server’s event log. AllAll process events are logged. NoneNo events are logged. ErrorsOnly unexpected shutdowns, memory limit shutdowns, and deadlocks are logged. This is the default value.
maxWorkerThreads
This property specifies the maximum number of worker threads that can be created on each processor. This value must be greater than or equal to the minFreeThreads property value in the section. Possible values are 5 to 100.
maxIoThreads
This property specifies the maximum number of I/O threads that can be created on each processor. This value must also be greater than or equal to the minFreeThreads property value in the section. Possible values are 5 to 100. 78
Table 4-17: <processModel> properties Property
Description
memoryLimit
This property specifies the maximum amount of memory that the worker process can consume before ASP.NET launches another process and reassigns existing requests to the new process. This value is a percentage of the total system memory. The default value is 60%.
password
This property is used in conjunction with the username property to configure which user the ASP.NET worker process will run as. The default value is AutoGenerate.
pingFrequency
This property specifies the interval at which the ISAPI extension should ping the worker process to be sure that is it still active and responsive. If the process does not respond, the process is restarted. The default value is 30 seconds.
pingTimeout
This property specifies how long the ISAPI extension will wait for a response after pinging the worker process before restarting it. The default is 5 seconds.
requestLimit
This property specifies the number of requests that ASP.NET will handle before launching a new worker process to replace the current one. The default value for this is infinite.
requestQueueLimit
This property specifies the number of requests that are allowed in the queue before 503 Server Too Busy errors start being returned to new requests. The default is 5000.
responseDeadlockInterval
This property specifies the amount of time after which the process will be restarted when there are queued requests and there has not been a response. The default value is 3 minutes.
responseRestartDeadlockInterval
This property is no longer used by ASP.NET.
serverErrorMessageFile
This property specifies which file to use instead of the default “Server Unavailable” message when there is a problem with the process. This path is relative to the machine.config file of the server.
shutdownTimeout
This property specifies the amount of time the worker process has to shut itself down. If shut down takes longer than this amount of time, ASP.NET shuts the process down. The default is 5 seconds.
Timeout
This property specifies the number of minutes until ASP.NET launches a new worker process to take the place of the current one. The default 79
Table 4-17: <processModel> properties Property
Description is Infinite.
userName
This property is used in conjunction with the password property to specify the user name and password that should be used to run the ASP.NET process. This can be set to a predefined account, a specific domain, or a local user account. MachineSpecifies that ASP.NET runs under a restricted account that was created when ASP.NET was installed. This account has very low privileges and helps minimize the security threat if a security fault is found. This is the default value. SystemSpecifies that ASP.NET will run as an administrative account with much greater privileges. This setting was the default in Beta 2, but is no longer suggested because it creates a major security risk if any security flaws are found. CustomSpecifies that the process should run as a custom user name and password. This can be either a local system account or a domain account. This value is stored as clear text in the configuration file. Just like when working with the section, these values can be stored in the registry. For more information, please refer to the section and the procedure detailed on pages 72–73.
webGarden
This property specifies whether individual worker processes should be used for each processor, or one process should be used and processor usage should be handled by the operating system. A Web garden is a multiprocessor Web server. trueSpecifies that the cpuMask property is used to specify the processors that should be used. falseSpecifies that only one process is used and the OS will handle the cpu usage.
Here is a sample <processModel> section. <processModel clientConnectedCheck="0:0:25" comAuthenticationLevel= "None" comImpersonationLevel="Delegate" cpuMask="0x0d" enable="true" idleTimeout="25" logLevel="All" maxWorkerThreads= "25" maxIoThreads="25" memoryLimit="75" password="AutoGenerate" pingFrequency="30" pingTimeout="5" requestLimit="Infinite" requestQueueLimit="5000" responseDeadlockInterval="00:03:00" 80
serverErrorMessageFile="c:\inetpub\wwwroot\serverunavail.html" shutdownTimeout="00:00:05" timeout="Infinite" userName="machine" webGarden="false" /> The default <processModel> section does not contain all these settings; many of them are optional and use their default value if not specified.
Customizing the Server Unavailable Message One of the most important steps in developing a first-class Web application is ensuring that users will not see unprofessional error messages. The first step is catching errors in application code and catching HTTP errors; the next step is providing friendly error messages whenever the application is being restarted or temporarily unavailable. Here is the procedure for customizing this error message. • •
Configure the <processModel> section to point to a customized file using the serverErrorMessageFile property. This file contains the message that you want to display to users. Create a file that is not handled by the ASP.NET process and place it in the location pointed to by the configuration file.
I would suggest an error message that lets the user know that the site is down for maintenance or is experiencing temporary difficulties and to try again.
Running ASP.NET on a Domain Controller There are some special considerations for running ASP.NET on a domain controller. When you first install ASP.NET on a domain controller and try to access an ASP.NET application, you will get a Server Application Unavailable error message because by default ASP.NET runs as a local system account, which does not exist on domain controllers. There are two options for configuring ASP.NET to successfully run on a domain controller. •
• • • • •
Configure ASP.NET to run as the system account by setting the username property to System. This enables ASP.NET to run as an administrator on the system. This option, although valid, is not a good idea because it gives ASP.NET full run of the domain controller. Configure ASP.NET to use a weak domain account to log into the domain controller. This is a much better option because it causes a much smaller security risk. Here is the procedure for correctly creating and configuring this account. Create an account on the domain controller and add the account to the users group. Grant the user “log on as a batch job” rights. Make sure that the user has access to all the necessary directories, including all ASP.NET application directories. Set the user name and password of the account as the username and password properties in the <processModel> section.
Troubleshooting ASP.NET Deadlocks ASP.NET deadlocks can be a major problem. When a deadlock occurs, the application does not respond for three minutes, after which the process is restarted, which takes at least another minute. When the process is restarted due to a deadlock, an entry is added to the event log on the server. Check this event log periodically to be sure that deadlocks are not occurring with your application. If you find that deadlocks are occurring on the server, 81
find the problem-causing application and the problem-causing code. Frequent deadlocks can be caused by a couple of different problems. One thing that can cause deadlocks is if your application routinely performs lengthy processor-intensive operations. If this is the case, the first step you should take is to increase the responseDeadlockInterval time setting. This will give your application a longer time to complete these operations without causing a restart. If this solves your problem, you might want to increase your server hardware so that these operations can be completed faster. If this does not solve your problem, you most likely have code that is causing lockups or performing operations that would take too long even on better server hardware. The best way to find this problematic code is to isolate your application, test it manually, and find the operation or page that is causing the problems.
<processModel> Key Points
The serverErrorMessageFile property enables you to customize the server unavailable message that is displayed when the worker process is being restarted or otherwise not available. When installing ASP.NET on a domain controller, special user configuration steps are required before ASP.NET will operate correctly. Finding, troubleshooting, and resolving ASP.NET deadlock issues is key to providing the best possible user experience.
Working with the <securityPolicy> Section The <securityPolicy> section is a mapping of security-level names to the security policy file. Security policy files contain security settings pertaining to ASP.NET. The <securityPolicy> section contains only a single element named <trustLevel>. Here is the syntax for the element. <securityPolicy> <trustLevel name="security name" policyFile="security policy file" /> The two properties for this section are listed in Table 4-18.
Table 4-18: <securityPolicy> properties Property
Description
name
This property specifies the named security level that this policy file is linked to. Possible values are Full, High, Medium, Low, and Minimal. The Full value does not require a policy file linked to it.
policyFile
This property specifies the configuration file that contains the security settings for this security level.
Here is a sample <securityPolicy> section. <securityPolicy> <trustLevel name="Full" policyFile="internal" /> <trustLevel name="High" policyFile="web_hightrust.config" /> <trustLevel name="Medium" policyFile="web_mediumtrust.config" /> <trustLevel name="Low" policyFile="web_lowtrust.config" /> 82
<trustLevel name="Minimal" policyFile="web_minimaltrust.config" /> The Full trust level does not require that a file be linked to it. The Full level is the same as having full trust on the local machine.
<securityPolicy> Key Points
The <trustLevel> element maps a friendly trust-level name to the security policy file that contains the settings. The friendly trust-level names are used in the <trust> section to specify under which security sections an application should be run.
Working with the <sessionState> Section The <sessionState> section contains a number of settings that configure how ASP.NET works with sessions. Using this section, you can configure sessions to be stored on the local system, on a remote state server, or on a remote SQL server. There are a number of properties, but only one is required. Here are the syntax and values for that required property. <sessionState mode="session mode" /> The possible values for the mode property are listed in Table 4-19.
Table 4-19: mode property values Value
Description
Off
This value specifies that session state is disabled.
InProc
This value specifies that session state is enabled and session information will be stored locally.
StateServer
This value specifies that session state is enabled and session information will be stored on a remote server.
SQLServer
This value specifies that session state is enabled and that session information will be stored on a remote SQL server.
There are two other properties that can be used in the section and that apply to all modes of session state. Here is the syntax of those two properties. <sessionState mode="session mode" cookieless="true | false" timeout="amount of time" /> These two properties are listed in Table 4-20.
Table 4-20: cookieless and timeout properties Property
Description
cookieless
This property specifies whether cookies are used to identify client sessions. trueSpecifies that cookies will not be used when managing 83
Table 4-20: cookieless and timeout properties Property
Description sessions. falseSpecifies that cookies will be used when managing sessions.
timeout
This property specifies the amount of time a session can be idle before it is abandoned. The default value is twenty minutes.
Here is an example of how to use these properties. <sessionState mode=”InProc” cookieless=”true” timeout=”20” /> The session data for your application will be stored locally and will not use cookies. If a session is idle for 20 minutes, the session and any data will be abandoned.
Configuring State Server State server enables you to set one server in your Web farm as a dedicated session state server. This server keeps track of session state and data for all the other servers. This is very important because you would otherwise not know which server handles each user request. This way, no matter which server handles the request, the session information is stored and retrieved on the dedicated state server. The state server will still handle Web requests as long as it is not overtaxed with session information. The first step in configuring your application to use state server is setting the mode property to the StateServer value. Then you must configure two additional properties to the <StateServer> section. Here is the syntax for these two properties. <sessionState mode="StateServer" stateConnectionString= "connection string" stateNetworkTimeout="amount of time" /> Table 4-21 lists these two properties:
Table 4-21: State server properties Property
Description
stateConnectionString
This property specifies the connection string to the state server in the following format: “tcpip=192.168.31.0:42424”
stateNetworkTimeout
This property specifies the number of seconds that the tcpip connection can be idle before the session is abandoned. The default value is 10.
Here is an example of the <sessionState> section configured to work with a state server. <sessionState mode="StateServer" stateConnectionString= "tcpip=192.168.31.0:42424" stateNetworkTimeout="15" /> The only other step necessary is configuring a server that will act as the state server. Start the state server service, which is done through the Services MMC plug-in or by running the following file. :\%windir%\Microsoft.NET\Framework\version\aspnet_state.exe State server will not be running on the remote server and can be used by the other servers. 84
Configuring SQL State Server Another method of maintaining state across multiple servers or in a Web farm is to use SQL server. The first step is to configure a server in your farm to act as the session state server. To do this, run the InstallSQLState.sql script, which is located in the :\%windir%\Microsoft.NET\Framework\version directory. This script has to be run on a server that is running SQL server. It will create a database named ASPState including tables, stored procedures, and everything else required to run SQL state server on this server. The next step is to configure your application to use SQL state server. Here is the syntax for this configuration. <sessionState mode="SQLServer" sqlConnectionString="connection string" /> Table 4-22 lists this property.
Table 4-22: SQL state server property Property
Description
sqlConnectionString
This property specifies the connection string that should be used to connect to the SQL state server.
Here is an example of this section configured to work with SQL state server. <sessionState mode="SQLServer" sqlConnectionString= "data source=192.168.0.1;Integrated Security=SSPI" /> The session state data for this server will now be stored in the SQL server located at 192.168.0.1.
<sessionState> Key Points
The mode property enables you to configure your applications to store session information locally, on a State Server, or on a SQL Server. The cookieless property enables you to configure your application to record session information without the use of cookies. State server enables a single Web server to become a dedicated session state server and be used by multiple Web servers. This removes some of the stress from the other Web servers and makes programming for a Web farm easier.
Working with the Section The section enables you to configure tracing sections on a machine, application, or site level. Tracing is one of the most useful features introduced with ASP.NET It enables you to see a large amount of information about the page compilation and debugging. Here is the syntax of the section. The properties for the section are listed in Table 4-23.
Table 4-23: properties 85
Property
Description
enable
This property specifies whether tracing is enabled for this application. trueSpecifies that tracing is enabled. falseSpecifies that tracing is disabled.
localOnly
This property specifies whether the trace viewer is available only on the host server. trueSpecifies that the trace viewer is available only locally. This is the default value. falseSpecifies that the trace viewer is available remotely.
pageOutput
This property specifies whether trace output is appended to the end of each page. trueSpecifies that trace output is appended to the end of each page. falseSpecifies that trace output is not appended to the end of each page. This is the default value.
requestLimit
This property specifies the number of trace requests that the server can handle before it is automatically disabled. The default value is 10.
traceMode
This property specifies the sort method that is used to sort the trace information. SortByTimeSpecifies that trace information is sorted based on when it is processed. SortByCategorySpecifies that alphabetically by category.
trace
information
is
sorted
Here is a sample section. Tracing will now be enabled for applications, and trace output will not be appended to the end of each page but available through the trace viewer.
Key Points
You can specify whether tracing is enabled and how it behaves. The localOnly property enables you to enable tracing for local requests only. The pageOutput property enables you to specify whether trace information will be added to the end of each page or will be viewable only through the trace viewer.
Working with the <trust> Section The <trust> section enables you to configure the code access security level for a machine or application. Here is the syntax of the <trust> section. <trust level="security level" originUrl="url" /> The properties for the <trust> section are listed in Table 4-24. 86
Table 4-24: <trust> properties Property
Description
level
This property specifies the security level under which the application will run. The values correspond to the levels outlined in the <trustLevel> section. Possible values includes Full, High, Medium, Low, Minimal.
originUrl
This property specifies the application URL of origin. This can be used for some applications that allow connectivity back the host or origin. This property is optional.
Here is a sample <trust> section. <trust level="Full" originUrl="" /> The applications that are affected by this configuration setting will run with Full security permissions. <trust> Key Points The <trust> section enables you to specify the security level at which an application should be run.
Working with the <webControls> Section This small section has only one property. This property specifies the location of the clientside validation script file. Here is the syntax for using this section. <webControls clientScriptsLocation="path" /> The clientScriptsLocation property points to the location of the client-side validation script file. This file contains the script used for the client-side validation of Web controls. Here is an example of this section. <webControls clientScriptsLocation= "/aspnet_client/{0}/{1}/" /> The {0} will be replaced with the namespace name, and the {1} will be replaced with the version number of the Framework. For ASP.NET 1.1 and the System.Web namespace, this would result in a file path of /aspnet_client/System.Web/ 1_1_4322/.
<webControls> Key Points
The clientScriptsLocation property can be used to specify the path where the script validation files are located.
Working with the <webServices> Section This section includes a number of settings that can be used to configure the XML Web services that are created using ASP.NET. This section includes a number of different subsections that function as collection-based sections.
<protocols> Sub-Section The protocols sub-section specifies the protocols that can be used to send data to the Web services hosted on this machine. Data is sent through the HTTP request to the Web services and is then decrypted by the service. This data can include method calls and 87
parameters. This is a collection-based section so you can add, remove, or clear out all the entries in this section. Here’s the syntax for adding a protocol to the section. <protocols> The name property is used to specify the protocol that you want to add to the <protocols> section. The protocols you can add to this section are listed in Table 4-25.
Table 4-25 : Protocols Protocol
Description
HttpGet
This protocol adds the HTTP GET protocol to the collection. GET information is passed through the querystring of the URL.
HttpPost
This protocol adds the HTTP POST protocol to the collection.
HttpPostLocalHost
This protocol adds the HTTP POST protocol to the collection, but allows only information posted from the local machine.
HttpSoap
This protocol adds the HTTP SOAP protocol.
HttpSoap1.2
This protocol adds the new HTTP SOAP version 1.2 protocol.
Documentation
This protocol creates documentation information when the .asmx file is accessed directly.
Here is a sample <protocols> section. <protocols> These protocols will now be available when accessing the Web services on this server. You can also remove a protocol from the collection using the element. Here is an example of how to use the element. <protocols> The HttpSoap protocol will no longer be available to the Web services on this server. You can also use the element to clear out any protocols added to the collection in an earlier configuration file.
<serviceDescriptionFormatExtensionTypes> Sub-Section This is a collection-based sub-section that enables you to specify the service description format extensions that should be run. Because this is a collection-based section, you can 88
add, remove, or clear out all the entries in the collection. Here is the syntax for adding an extension to the collection. <serviceDescriptionFormatExtensionTypes> This extension will now be added to the collection. Here is the syntax for removing a type from the collection. <serviceDescriptionFormatExtensionTypes> This type will now be removed from the collection. You can also use the element to clear out all the information.
SOAP Extensions Sub-Sections There are a number of SOAP extensions sub-sections that enable you to add SOAP extensions to your server. All these sections include the same elements. Table 4-26 lists the sub-sections to which these elements apply.
Table 4-26 : SOAP extensions sub-sections Section name
Description
<soapExtensionTypes>
This section specifies the SOAP extensions to be run with all the Web services.
<soapExtensionImporterTypes>
This section specifies the SOAP extensions to be run when a service description for a Web service is accessed to create a proxy class.
<soapExtensionReflectorTypes>
This section specifies the SOAP extensions to be run when a service description for a Web service is generated.
Here is the syntax for adding an extension to any one of these sub-sections. <soapExtensionTypes> Table 4-27 lists the properties for the element.
Table 4-27: properties Property
Description
type
This property specifies the soap extension class that you want added to the section.
priority
This property specifies the priority of the extension being added. 89
Table 4-27: properties Property
Description SOAP extensions will be processed based on this priority number, starting at 1 and moving up.
group
This property works with the priority property to determine order in which the extensions should run. Extensions can grouped into two different groups; the first group is run first in order specified by the priority property. The second group is in the order specified by the priority property.
the be the run
Here is an example of how to use the add method. <soapExtensionTypes> These extensions will be run in this order. 1. SOAPExt 2. SOAPExt4 3. SOAPExt3 4. SOAPExt2 Because all these sub-sections are collection-based, you can use the remove and properties.
<wsdlHelpGenerator> Section This is the last sub-section in the <webServices> section. This section enables you to specify the location of a help file for your Web services. Here is the syntax for this section. <wsdlHelpGenerator href="file path" /> The href property, contrary to what the name implies, should actually point to the physical location of the file. This location can be absolute or relative to the location of the configuration file.
<webServices> Key Points
The <protocols> section enables you to specify the protocols that can be used to access Web services on your server. The SOAP extensions sections enable you to add extensions and prioritize them using groups and the priority property. The <wsdlHelpGenerator> sub-section enables you to specify a particular help file to be provided with your Web services.
90
Chapter 5: Mobile Controls Configuration Settings Overview This chapter provides an in-depth look at the settings that configure the Microsoft Mobile Internet Toolkit (MMIT), which is now included with version 1.1 of the Microsoft .NET Framework. MMIT is a collection of namespaces and controls that are used to develop applications for mobile devices. The MMIT uses the section in conjunction with the <mobileControls> and <deviceFilters> sections to determine the type of device that is accessing the resource. After determining the type and capabilities of that device, the MMIT customizes the content that is sent to the client. Here are descriptions of these sections.
<mobileControls> This section enables you to define new device adapters that are mapped to ASP.NET mobile controls. <deviceFilters> This section enables you to add device filters that are used in your code to manually customize the content that is sent to the client.
Defining a mobile device in the section is the easiest way to accommodate that device. More Info
There are a number of different devices that are considered “mobile.” These include phones, PDAs, pagers, or any device that does not use a full-features browser (Internet Explorer, Netscape, and so on).
When you need more customization than is possible with the section, the <mobileControls> and <deviceFilters> sections enable you to further customize the content sent to the client.
Working with the <mobileControls> Section The <mobileControls> section defines adapter sets that map to ASP.NET mobile controls. An adapter is a class that customizes each mobile control for a particular device or language. Table 5-1 lists the adapters that are installed by default with MMIT.
Table 5-1: Default mobile adapter sets Adapter
Description
HTML
This adapter is used for devices that can understand HTML 3.2 without any client-side scripting.
CHTML
This adapter is used for devices that understand HTML 3.0 without any client-side scripting.
WML
This adapter is used for devices that understand WML 1.1.
For instance, when a Pocket PC device accesses your application, the HTML adapter generates HTML 3.2 content. Adapter sets are declared in the <mobileControls> section. Here is the syntax for that section. <system.web> 91
<mobileControls allowCustomAttributes="true | false" sessionStateHistorySize="size of history" cookielessDataDictionaryType="dictionary type"> <device name="device name" inheritsFrom="parent adapter set" predicate predicateMethod="method to call" pageAdapter="Adapter Class"> There are many properties and elements in the syntax just shown, and I will cover each element one step at a time. Configuring the <mobileControls> Properties The properties of the <mobileControls> element are global settings for the mobile runtime. These properties are used to configure how the mobile runtime maintains state and whether custom attributes are enabled. Table 5-2 lists the properties for the <mobileControls> element.
Table 5-2: <mobileControls> properties Property
Description
allowCustomAttributes
This property specifies whether pages can contain custom attributes. Enabling custom attributes makes it possible to include attributes in controls that are specific to a particular adapter. Any attribute added to the control will be saved as a custom attribute and be made available to any adapter interpreting the control.
sessionStateHistorySize
This property specifies the maximum size in kilobytes of the history to be stored on the sessions. Because mobile devices generally have a very small amount of free memory and the majority of them cannot store cookies, session state and view state information are stored in session variables.
cookielessDataDictionaryType
This property specifies the dictionary class that will contain the cookieless forms authentication information. You can disable this feature by setting this property to an empty string.
Here is an example of the <mobileControls> section with only these properties displayed. <mobileControls allowCustomAttributes="true" sessionStateHistorySize="6" cookielessDataDictionaryType="System.Web.Mobile.CookielessData"> 92
Using Custom AttributesSetting the allowCustomAttributes property to true enables custom attributes for all mobile controls. This means you can specify any type of property in a mobile control and it will be saved and passed to the adapter. Using custom attributes enables you to specify attributes that will be used only by a particular adapter. Any property set on a control that is not recognized as a default property for that control is saved and passed to the adapter. For example, you could add the following property to the mobile:Label control. <mobile:Label runat="server" id="lblLabel" text="Our Label Text" wmlFormat="NNN" /> The wmlFormat property will be saved and passed to the adapter that is handling the control. The WML adapter will use the property; other adapters will ignore it. Caution
If you accidentally type “txt” instead of “text,” the control will save this property as a custom attribute instead of prompting you with an error because of an invalid property name.
The adapter can then access the property using the CustomAttributes dictionary class and use that property to generate custom content for the client. Working with Devices The <mobileControls> section contains the <device> subsection, which declares a new adapter to be used with the mobile controls. The properties of the <device> section are listed in Table 5-3.
Table 5-3: <device> properties Property
Description
name
This property specifies the name for this adapter set.
inheritsFrom
This property specifies the adapter set from which this adapter should inherit. This adapter must be declared either earlier in this <mobileControls> section, or in the <mobileControls> section of an earlier configuration file.
predicateClass
This property specifies the class that will be used to determine whether this adapter should be used for the current requesting device. The value of this property should be the fully qualified reference to this class. The value can be inherited from the class listed in the inheritsFrom property.
predicateMethod
This property specifies the .NET method that will be used to determine whether this adapter should be used for this device. This method must be in the class that is specified in the predicateClass property. The value of this property can be inherited from the class listed in the inheritsFrom property.
pageAdapter
This property specifies the .NET class for the page adapter of this adapter set. The value of this property should be the fully qualified reference to this class. A page adapter class must implement the IPageAdapter interface. This value can 93
Table 5-3: <device> properties Property
Description be inherited from the class listed in the inheritsFrom property.
Each <device> section can contain a number of subsections. Each of these sections can map a control to the adapter that will be used to handle that control. Each control that you want to be customized for this device must have an adapter to handle it. Table 5-4 lists the properties for the section.
Table 5-4: properties Property
Description
name
This property specifies the name of the mobile control for which you are specifying an adapter.
adapter
This property specifies the adapter that will customize this control for the requesting device.
To get a better idea of how this all works, here is a sample <device> section plucked directly from the default machine.config file. <device name="ChtmlDeviceAdapters" inheritsFrom="HtmlDeviceAdapters" predicate predicateMethod="DeviceQualifies" pageAdapter= "System.Web.UI.MobileControls.Adapters.ChtmlPageAdapter"> This <device> section is for the ChtmlDeviceAdapters adapter and shows what a normal <device> section will look like. Creating a Custom Adapter Set The complete procedure of creating a custom adapter is beyond the scope of this book, but this section provides a brief overview and some tips for creating adapters. The best way to create a custom adapter is to model it after the free source available from Microsoft. Even though the MMIT is installed by default with ASP.NET 1.1, you will still need to download and install the MMIT to obtain the device adapter source code. You can search for MMIT on http://mdsn.microsoft.com. 94
After installing the MMIT, you will find an adapter source folder in the c:\Program Files\Microsoft Mobile Internet Toolkit directory. This is the source code for the three default adapters and it is invaluable when creating a custom adapter for your device. Use this source code as your base code and then modify it with the changes needed for your device. First create the page adapter that will serve as your predicate class. The predicate class contains the predicate method that determines whether your adapter should be used. Here is an excerpt from the HtmlPageAdapter file, which can be found in the adapter source folder. C# public static bool DeviceQualifies(HttpContext context) { String type =((MobileCapabilities)context.Request.Browser). PreferredRenderingType; bool javascriptSupported = context.Request.Browser.JavaScript; bool qualifies = (type == MobileCapabilities.PreferredRenderingTypeHtml32) && javascriptSupported; return qualifies; }
VB.NET Public Shared Function DeviceQualifies(ByVal context As _ HttpContext) As Boolean Dim type As String = (CType(context.Request.Browser, _ MobileCapabilities)).PreferredRenderingType Dim javascriptSupported As Boolean = _ context.Request.Browser.JavaScript Dim qualifies As Boolean = (type = _ MobileCapabilities.PreferredRenderingTypeHtml32) And _ javascriptSupported Return qualifies End Function
This function returns a Boolean value so that the mobile runtime can determine whether this adapter should handle the request. This function accepts the current HTTP context object and reads whether this device can handle HTML and JavaScript. If the device can handle HTML and JavaScript is supported, a value of true is returned, and this adapter handles the request. The page adapter also contains a number of other methods that render the page, but I will not cover them in this book. 95
After you complete your page adapter, including the predicate method, create control adapters for each control. The easiest way to do this is to base your custom adapters on the code that is included in the MMIT code examples. Creating a custom adapter set is a long procedure that will not be covered here, but with the information I have covered so far and the source code available, you should be able to build an adapter set for your device.
Working with the <deviceFilters> Section Like the <mobileControls> section, the <deviceFilters> section is also used to customize the content that is sent to the client. You can use this section to configure filters that are evaluated at runtime to be either true or false. These filters can then be used to decide the content that should be sent to the client. There are two different types of filters.
Comparison Filters Comparison filters are used to make a basic comparison between a capability and the value specified in the filter. You can use any capability that can be read from the MobileCapabilities class. Evaluator Delegate Filters Evaluator filters create a custom method that returns true or false. With this method, you can check a number of capabilities and perform other checks to determine if this filter should return true or false.
Both of these filters implement the element within the <deviceFilters> section. Here is the syntax of the <deviceFilters>, including both types of filters. <system.web> <deviceFilters> The first filter in the syntax is a comparison filter; the second is an evaluator filter. The properties for the element are listed in Table 5-5.
Table 5-5: properties Property
Description
name
This property specifies the unique name of the filter. This is the name that you will use to call this filter in your code. If you specify a filter name that already exists, it will be overwritten.
compare
This property specifies the name of the capability that you want to compare. This can be any of the capabilities included in the mobileCapabilities class or any custom capabilities you have added. This property is used when building a comparative filter.
argument
This property specifies the argument that will be used when comparing to the capability specified in the compare property. This property is used when building a comparative filter.
type
This property specifies the class that will supply the evaluator method. The value of this property should follow the .NET standards 96
Table 5-5: properties Property
Description for specifying a fully qualified class. This property is used when building an evaluator filter.
method
This property specifies the method that will be used to determine if the filter is true or false. This property is used when building an evaluator filter.
Building a Comparative Filter Here are the steps for building a comparative filter. 1. Decide which capability you want to compare against. This can be any capability available through the mobileCapabilities class. In this example, you will use the isColor capability, which determines whether a device has a color display. 2. Decide which value you want to check for; in this example, you will check for the true value. 3. Create a new element with the information from steps 1 and 2, and add it to the <deviceFilters> section of your machine.config or web.config file. Here is an example of this element. <deviceFilters> This filter will return a true value when the isColor capability is true.
Building an Evaluator Filter Evaluator filters rely on a custom class to return either true or false. Because you are writing the class, it can evaluate any number of properties or variables. The first step is to build the class that will determine if the filter is true or false. The class must follow this example. C# public bool methodName(System.Web.Mobile.MobileCapabilities mobileCaps, string optionalString) { //Class Logic Here }
VB.NET Public Function methodName(mobileCaps as _ 97
System.Web.Mobile.MobileCapabilities, optionalString as String) _ as Boolean 'Class Logic Here End Function
The method accepts an instance of the MobileCapabilities class, which you can use to read browser capability properties and determine whether the class should return true or false. The second parameter is a string that you can use to pass any additional information that you might want to use in the class. Here are the steps for creating and configuring an evaluator filter. 1. Create a custom class to evaluate to true or false. A sample evaluator class follows this procedure. This class will check both the isColor and ScreenBitDepth browser capabilities to determine whether the requesting device can handle high-color images. 2. Add this filter to the <deviceFilters> section. <deviceFilters> This filter will evaluate to true if the requesting device can handle high-color images. C# public bool isHighColor(System.Web.Mobile.MobileCapabilities mobileCaps, string OptionalString) { bool bIsHighColor; if(mobileCaps.IsColor == true && mobileCaps.ScreenBitDepth >= 16) { bIsHighColor = true; } else { bIsHighColor = false; } return bIsHighColor; }
VB.NET 98
Public Function isHighColor(mobileCaps As _ System.Web.Mobile.MobileCapabilities, OptionalString As String) _ As Boolean Dim bIsHighColor As Boolean If mobileCaps.IsColor = True And _ mobileCaps.ScreenBitDepth >= 16 Then bIsHighColor = True Else bIsHighColor = False End If Return bIsHighColor End Function
Using Filters with Mobile Controls Now let’s look at how to use these filters to customize the content generated by the mobile controls. Both of the filters just discussed looked at how to detect the color capabilities of the requesting device, so it is only fitting that you look at using these filters with the <mobile:Image> control. Here is an example of a <mobile:Image> control that doesn’t use any filters. <mobile:Image runat="server" ImageURL="logo.gif" /> This control renders the logo.gif file for every device that accesses your page. This would suffice for desktop and laptop computers, but mobile devices might require that the image be customized based on the color capabilities of that device. To use the filters you defined in the last section with this control, you can utilize the element. The element can be used within any of the mobile controls to specify parameters based on filters. Here is the syntax for the element. <mobile:Image runat="server" ImageURL="logo.gif"> You can specify any number of control properties in the element. When the control is rendering, if the filter evaluates to true, the properties in the element will be applied to the control. Here is an example using the two filters defined earlier. <mobile:Image runat="Server" ImageURL="logoBW.gif"> 99
Here is the order of events that will take place when this control is rendered. 1. The ImageURL property is first set to logoBW.gif (the black and white logo). 2. The element and the included element are processed. 3. If the IsColor filter evaluates to true, the ImageURL property is set to logoColor.gif. If it is false, the filter does nothing. 4. If the IsHighColor filter evaluates to true, the ImageURL property is set to logoHighColor.gif. If it is false, the filter does nothing. 5. The <mobile:Image> control renders using the current ImageURL property. Using filters in this way enables you to customize the properties of a control based on any number of browser capabilities or other criteria.
Updating the Mobile Controls Devices The most important part of designing applications for mobile devices is making sure you can detect and accommodate a large number of different mobile devices. By default, ASP.NET detects a large number of devices, but as you know, new mobile devices are being released every day. To accommodate this, Microsoft releases Mobile Controls Device Updates periodically. These updates can include updates to any of the following areas.
configuration settings <mobileControls> configuration settings Adapter assemblies configuration settings
There have been two mobile controls updates so far, but because they are cumulative, you only need to worry about the most recent device update. One of the features included in the device updates available at the time of this writing is a new XHTML adapter. This adapter can generate XHTML-compliant content for mobile devices that can handle it. In the future, you can expect even more device updates including new browser detection, new adapters, and more. To download the most recent browser update, check this Web page for new releases: http://msdn.microsoft.com/vstudio/device/mobilecontrols/aspmobiledrivers.asp
Key Points
Using the <mobileControls> section, you can declare and configure the adapters used to generate content for specific formats, including HTML, CHTML, and WML. Using the code examples available with the MMIT as a base, it is easy to create a custom adapter for a new mobile device. Using the <deviceFilters> section, you can create filters that can evaluate any number of browser capabilities and then return either true or false. Using the <deviceSpecific> element, you can use the filters defined in the <deviceFilters> section to customize the output of an individual mobile control. Microsoft releases periodic mobile controls device updates that contain updates to the browser detection code as well as new adapters and other configuration settings to accommodate new mobile devices.
100
Chapter 6: Microsoft .NET Configuration Settings There are a number of sections that, although they are not directly related to Microsoft ASP.NET, are used when building ASP.NET applications. There are four sections and each is used to configure a different .NET namespace. Here are the sections I will cover in this chapter.
<system.diagnostics> This section group contains information related to the system.diagnostics namespace including settings related to tracing and switches. <system.net> This section group contains a number of sections related to proxy settings, as well as settings related to authentication and Web requests. <system.runtime.remoting> This section contains settings for .NET remoting, including channels and client providers. I will cover all the different settings, as well as how to add custom channels and providers. <system.windows.forms> This section contains one setting related to JIT (Just in Time) compilation.
Examining the <system.diagnostics> Group The <system.diagnostics> section group contains a number of settings that configure tracing and debugging for the system.diagnostics tracing objects. The system.diagnostics tracing should not be confused with the ASP.NET trace object. The ASP.NET tracing object can be used only in ASP.NET and can be configured using the section in the <system.web> section group. The tracing and debugging objects in the system.diagnostics namespace can be used by both ASP.NET and console applications. Real World
The only reason you would want to use the system.diagnostics tracing object in ASP.NET applications is if the applications are being deployed and you want to save the trace information to a remote event log or database. If you are not deploying the applications to a server other than your own, it is best to stick with the Page.Trace method of application tracing.
There are a number of sections contained in the <system.diagnostics> group, and each of these sections configure a different part of tracing or debugging. By keeping these settings in the configuration files, you can make changes to the way tracing information is stored without having to recompile the application.
Working with the Section The section is used to configure trace listeners. Trace listeners are objects that receive and store the tracing information that is written from the application. There are a number of listeners that route the tracing information to a different destination, including listeners that route the tracing information to a text file or the event log. The properties of the section are listed in Table 6-1.
Table 6-1: properties Property
Description
autoflush
This property specifies whether the trace listener should automatically flush the trace content after each time information is written to the trace object. 101
Table 6-1: properties Property
Description true The trace output will be automatically flushed. false The trace output is not automatically flushed and the Trace.Flush method will need to be called for the content to be flushed.
indentsize
This property specifies the amount of spaces to indent the trace text when Trace.Indent method is called.
Here is an example of the section. <system.diagnostics> In this example, tracing information will be automatically flushed after each write.
Using the <listeners> Sub-Section The <listeners> sub-section is a collection-based section, which means you can add or remove trace listeners. This section enables you to modify where trace information is sent without having to modify the code or recompile the application. Here is the syntax of using the <listeners> sub-section. <listeners> Table 6-2 lists the properties of the element.
Table 6-2: properties Property
Description
name
This property specifies the name of the listener.
type
This property specifies the class name, version, culture, and public key of the listener class.
initializeData
This property specifies a parameter that will be sent to the listener class when it is initialized.
Here is an example of adding a trace listener to the <listeners> section. <listeners> This example will add a trace listener named CustomListener that will record all the text written to the trace object and then save the information to the Event Log named EventLogName.
Working with the <switches> Section The <switches> section enables you to add trace switches to an application. A switch is a setting that is read from the code and then determines whether and what type of tracing information should be written. Because your code reads the switch values from the configuration file, you can change switch values in the configuration files without having to modify code or recompile the applications. Here are definitions for the two types of switches.
Boolean switches These switches can be set to either 1 or 0. They determine if something should be written. Trace switches These switches contain a number of settings that can specify different levels of tracing information.
Both of these switch types are added to the <switches> section in a similar fashion. Here is the syntax for adding a switch to the <switches> section. <system.diagnostics> <switches> The properties for the element are listed in Table 6-3.
Table 6-3: properties Property
Description
name
This property specifies the name of the switch that will be used in your code to reference this switch.
value
This property specifies the value that will be used to determine the type of trace information that will be output.
Using Boolean Switches Boolean switches can be used to either write trace information or not write it. The value of a Boolean switch can be set to either 1 for true or 0 for false. Here is an example of adding a Boolean switch to the <switches> section. <switches> This switch can then be read in your application using the following code. 103
C# static BooleanSwitch bSwitch = new BooleanSwitch("TraceInfo", "Write Trace Information"); if(bSwitch.Enabled == true) { Trace.WriteLine("Database Connection Opened"); }
VB.NET Dim bSwitch As New BooleanSwitch("TraceInfo", _ "Write Trace Information") If bSwitch.Enabled = True Then Trace.WriteLine("Database Connection Opened") End If If the switch’s value is set to 1, the Trace.WriteLine method will be executed and the trace information written. If the switch value is set to 0, the trace information will not be written.
Using Trace Switches Trace switches offer much more flexibility than Boolean switches. Boolean switches can be set only to true or false, trace switches can be set to a number of different values. Table 6-4 lists the possible values for a trace switch.
Table 6-4: Trace switch values Value
Tracing level
Description
0
Off
This value specifies that no trace information will be written.
1
Error
This value specifies that only error messages will be written.
2
Warning
This value specifies that messages will be written.
3
Info
This value specifies that information messages as well as error and warning messages will be written.
4
Verbose
This value specifies that all messages will be written.
error
and
Here is an example of how to add a trace switch to the <switches> section. <switches> 104
warning
You can then read this switch in your application using the following code. C# TraceSwitch tSwitch = new TraceSwitch("TraceLevel", "Tracing Level"); Trace.WriteLineIf(tSwitch.TraceWarning, "Here is a warning message"); Trace.WriteLineIf(tSwitch.TraceError, "Here is a error message");
VB.NET Dim tSwitch As New TraceSwitch("TraceLevel", "Tracing Level") Trace.WriteLineIf(tSwitch.TraceWarning, "Here is a warning message") Trace.WriteLineIf(tSwitch.TraceError, "Here is a error message") If you set the TraceLevel switch to level 1, only the first error message will be written to the trace listener. If the TraceLevel switch is set to level 2, both of the messages will be written to the trace listener.
Working with the Section The section can configure what happens when the Trace.Fail or Debug.Assert methods are called. By default, a window with a specified error message and the stack trace opens. This window pauses the application and gives you the option to either abort, retry, or ignore. This is very useful when trying to debug your application, but it is a function that you should disable before the application is sent to users. Using the section, you can disable this feature as well as save the information to a text file. Here is the syntax for the section. <system.diagnostics> Table 6-5 lists the properties of the element.
Table 6-5: properties Property
Description
assertuienabled
This property specifies whether a window will open displaying 105
Table 6-5: properties Property
Description the trace message and the stack trace. true The window will appear. false The window will not appear.
logfilename
This property specifies the path to a text file where the assert information will be saved. This can be used whether assertuienabled is set to true or false.
Here is a sample section. <system.diagnostics> Using this example the assert window would be suppressed and the text would be saved to the c:\application\tracelog.txt text file.
<system.diagnostics> Key Points The <system.diagnostics> section group provides a number of configuration settings that modify tracing behavior without the need to modify code or recompile the application.
The section and the <listeners> sub-section enables you to specify new trace listeners that save information to databases, text files, or the event log. The <switches> section can add new Boolean and trace switches that can set whether certain information will be sent to the trace listener or be ignored. The section controls whether the assert window is displayed and whether the information is written to a text file.
Examining the <system.net> Group The <system.net> section group contains a number of sections that can configure a variety of settings pertaining to the System.Net namespace including authentication modules, connection management, proxy server settings, and Internet request modules. The following sections are covered.
This section adds and removes authentication modules that are used to authenticate Internet requests. This section configures the maximum number of connections to an Internet host. <defaultProxy> This section configures the proxy server used for HTTP requests. <settings> This section configures a number of miscellaneous settings. <webRequestModules> This section configures the modules that are used to request information from Internet hosts.
106
Working with the Section The section is a collection-based section that can add, remove, and clear out authentication modules. These authentication modules authenticate with protected resources. Because this section is collection-based, you can add, remove, and clear out the modules listed here. Here is the syntax for adding an authentication module to the collection.
<system.net> The type property points to the authentication module class. Here is an example of adding authentication modules to the collection.
Adding these two modules to the collection makes these types of authentication available when making requests to secured resources. You can also remove modules previously added to the collection by using the element and specifying the module to remove in the type property. The digest method of authentication would no longer be available when making requests. You can also use the method to remove all modules that were previously added to the collection.
Working with the Section The section can specify the maximum number of connections to a particular site. This is a collection-based section, which means you can add, remove, and clear out settings. Here is the syntax for specifying the maximum number of connections for a particular server. <system.net> Table 6-6 lists the properties for the element.
Table 6-6: properties Property
Description
name
This property specifies the IP address or DNS name of the server. The “*” wildcard can be used to specify all other servers not already specified in the collection.
maxconnection
This property specifies the maximum number of connections that will be made to the specified server.
Here is an example of using the element. <system.net> In this example, the maximum number of connections for the server located at 192.168.0.1 is four, and the maximum number of connections for www.microsoft.com is five. All other servers are limited to two connections. You can also remove a server specification using the element. <system.net> You can also use the element to remove all previously added connection restrictions.
Working with the <defaultProxy> Section The <defaultProxy> section configures when a proxy server should be used and the address of the server to be used when making Web requests. There are also a number of elements and settings that can be used to configure which requests are sent through the proxy.
Using the <proxy> Element The <proxy> element specifies which proxy should be used, and if the proxy should be used for local requests. Here is the syntax of the <proxy> element. <system.net> 108
<defaultProxy> <proxy usersystemdefault="true | false" bypassonlocal= "true | false" proxyaddress="URI or IP of proxy server" /> Table 6-7 lists the properties for the <proxy> element.
Table 6-7: <proxy> properties Property
Description
usersystemdefault
This property specifies whether the default system proxy should be used for Web requests. true The default system proxy will be used. false The default system proxy will not be used.
bypassonlocal
This property specifies whether the proxy server should be bypassed when accessing local resources. true The proxy server will not be used for local requests. false The proxy server will be used for local requests.
proxyaddress
This property specifies the URI or the IP address for the proxy server.
Here is an example of the <proxy> element. <system.net> <defaultProxy> <proxy usersystemdefault="false" bypassonlocal="true" proxyaddress="192.168.0.2" /> If a Web request is created and a proxy is not specified using the proxy property of the Web request, the proxy specified here is used. In this example, that proxy would be located at 192.168.0.2 unless the request is to a local resource, in which case no proxy would be used.
Using the Element The element can specify any number of regular expressions that will determine whether the proxy server should not be used for a request. If the URI or IP requested matches one of the regular expressions in this collection, the proxy will not be used for that request. The element is a collection-based element, which means you can add, remove, and clear entries. Here is the syntax of the element. <system.net> <defaultProxy> 109
Any request URL that matches the expression specified in the address property will not use the proxy server for the request. Here is an example of regular expressions and the . <system.net> <defaultProxy> Any request that matches either of these expressions will not use the proxy server.
Using the <module> Element The <module> element can specify a custom HTTP proxy to use instead of the default proxy. The default proxy is System.Net.WebProxy. Here is the syntax for the <module> element to specify the proxy. <system.net> <defaultProxy> <module type="Proxy Class" /> The type property must point to the class that will serve as the HTTP proxy. Here is an example of declaring a custom proxy class. <system.net> <defaultProxy> <module type="System.Net.WebProxy, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Working with the <settings> Section The <settings> section contains a number of miscellaneous settings pertaining to various System.Net components. As of this writing, you will have a tough time trying to find any sort of documentation for this section even though it contains some very useful settings.
110
Using the Element The element sets the maximum response header size that should be allowed from a Web request. Here is an example of how to limit the response header length using the element. <system.net> <settings> The maximumResponseHeadersLength property limits the maximum number of kilobytes that will be allowed in the response header.
Using the Element The element enables or disables Internet Protocol version 6 addressing. Internet Protocol version 6 is the new standard that is replacing the old Internet Protocol version 4. More Info
Internet Protocol version 4 is the standard addressing that we are all used to: 4 numbers separated by periods, for example, 192.168.1.1. Internet Protocol version 6 introduces 128 bit long addressing, which will provide a much larger range of addresses as well as increased routing A sample IPv6 address looks like this: abilities. 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562
You can enable IPv6 addresses by first ensuring that your operating system can handle IPv6 addresses. At this time, that includes Microsoft Windows Server 2003, Microsoft Windows XP (with SP1), and Microsoft Windows CE .NET. The second step to using IPv6 addressing is enabling it in the machine.config file of your server. Here is an example of how to enable IPv6 addressing on your server. <system.net> <settings> IPv6 addressing is now enabled for this server. Enabling IPv6 does not disable IPv4.
Working with the <webRequestModules> Section This section registers Web request modules that handle Web requests to a particular type of resource. By default, there are modules registered for requests with the http://, https://, and file:/ / prefixes. Using this section, you can overwrite or remove these modules, as well as register new modules. This is a collection-based section, which means you can add, remove, and clear out the modules registered here. Here is the syntax for adding a new module to the <webRequestModules> section. <system.net> <webRequestModules> 111
Table 6-8 lists the properties for the element.
Table 6-8: properties Property
Description
prefix
This property specifies the prefix of the request in which this module should be used, for example, http, https, file.
type
This property specifies the module class that will handle this request.
Here is an example of adding the HTTP module to the section. <system.net> <webRequestModules> The element can also be used to remove a previously added module. Here is an example of removing the HTTP module from the section. <system.net> <webRequestModules> Just like the other collection-based sections, you can remove all previously added modules using the element.
<system.net> Key Points The <system.net> section group contains a number of very useful sections pertaining to how to connect to other resources.
The section can add or remove authentication modules that are used when accessing resources with System.NET. The section enables you to specify a maximum number of server connections based on regular expressions that are matched against the IP or DNS name of the server. The <defaultProxy> section can configure a new proxy server. The <webRequestModules> section can configure the modules that are used to request information from remote resources. 112
Examining the <system.runtime.remoting> Group The <system.runtime.remoting> group contains a large number of sections and elements that can be used to configure remoting. I will not explain how to use or master remoting in this section; rather I will explain how this configuration section can be used. You can also use the .NET Configuration tool to work with and modify these settings. This tool is covered in the Appendix of this book.
Tip
Here are the four sections that I will cover.
This section declares the remote objects that the application consumes and the objects that the application exposes. This section contains channel templates. This section contains the providers of channel sinks that can be used in the channel sink chain. <debug> This section can be used to require the remoting system to load all the remoting types when the application starts. This makes it easier to catch errors made in the configuration file.
Note
There are a number of elements that are used in multiple sections. To avoid duplicating information in this book, I will point out the sections that are used repeatedly when I explain them, and then cross reference that explanation in the other sections that use that element.
Working with the Section The section contains a large number of sub-sections that define the remote objects that an application exposes and consumes. Before I go into the different sections, I will first discuss the name property of the section. This property specifies the application name to be used for the activation URL. When hosting the application through IIS, this property cannot be used. More Info
An activation URL is the URL that can be used to access the remote object. A syntax URL includes the protocol, computer name, port, and application name. The syntax for an activation URL is protocol//:computername:port/applicationname
Here is the syntax of the name property. <system.runtime.remoting> The application name specified here is now used in the activation URL. There are a number of different sub-sections in the section.
113
This section specifies the channels that can be used to communicate with remote objects. This section specifies the objects that the application consumes. This section configures the lifetime of all the remote objects for this application. <service>This section specifies the objects that the application exposes. <soapInterop>This section specifies type mappings for SOAP.
Using the Section This section configures the channels that the application will use to communicate with remote objects. You can use this section to configure channel-referencing templates as well as declare new channels to use. The single section included in this section is called . Using the SectionThe section configures either a channel that references a channel template or a new channel. Here is the syntax for declaring a new channel. Here is the syntax for declaring a channel that references a channel template. The properties for both these declaration methods are listed in Table 6-9.
Table 6-9: properties Property
Description
ref
This property specifies the ID of the template that this channel will be using. If this property is specified, the type property does not need to be specified.
displayName
This property specifies the name by which the .NET Framework Configuration Tool will refer to this channel. This property is not used for any other purpose.
type
This property specifies the full type name of the channel and the assembly name where the channel 114
Table 6-9: properties Property
Description implementation is located.
port
This property specifies a port for the channel to use. Some channel templates include a port specification, but others need one to be specified.
customChannelProperty
This property specifies a custom channel property. Any number of these properties can be specified for a single channel.
The sub-sections that can be used when declaring your channel are and <serverProviders>. These are the same as the sections used in the sub-section of the <system.runtime.remoting> sections. For more information about these sections, see “Working with the Section,” later in this chapter.
Using the Section The section can specify the objects that this application consumes. Here is the syntax for declaring an object. The properties for the section are listed in Table 6-10.
Table 6-10: properties Property
Description
url
This property specifies the URL for this object. It is required for client-activated objects, but it is not necessary for serveractivated objects.
displayName
This property is used by the .NET Framework Configuration Tool to provide a list of clients. It is not used for any other purpose.
The section also contains two elements called <wellknown> and . Using the <wellknown> ElementThe <wellknown> section can specify information about server-activated or “wellknown” objects. Here is the syntax for the <wellknown> section. <wellknown url="URL" displayName="Name" type="Type, Assembly" /> The properties for the <wellknown> section are listed in Table 6-11.
115
Table 6-11: <wellknown> properties Property
Description
url
This property specifies the full URL for the type, including the URI for the object.
displayName
This property specifies the name that will be used when listing the clients in the .NET Framework Configuration Tool.
type
This property specifies the full type name of the object and the assembly name.
Using the ElementThe element specifies information about client-activated objects. If the element is used, the element must contain a URL property. Here is the syntax for using the element. The type property points to the full type name and assembly that contains the type implementation.
Using the Section The section specifies the lifetime of remote objects. All values in this section are defined using a number followed by one of these time unit designations: D for days, H for hours, M for minutes, S for seconds, and MS for milliseconds. The default time unit is seconds. Here is the syntax for the section. Table 6-12 lists the properties for the section.
Table 6-12: properties Property
Description
leaseTime
This property specifies the lease time for the application.
sponsorshipTimeout
This property specifies the amount of time that the lease manager waits for the sponsor to respond when notified that the lease has expired. If there is no response, the garbage collector disposes of the remote object. The default time is two minutes.
renewOnCallTime
This property specifies the amount of time that the lease is extended each time that the object is used. The default is two minutes. 116
Table 6-12: properties Property
Description
leaseManagerPollTime
This property specifies the amount of time that the lease manager sleeps after each expiration check. The default is ten seconds.
Here is an example of the section. Changing the times set here can optimize how long your application keeps an object alive based on how the objects are used.
Using the <service> Section This section can specify the objects that this application exposes. This section includes two elements named <wellknown> and . Although these elements have the same name as the elements of the section, they are not the same. Using the <wellknown> ElementThe <wellknown> element defines information about server-activated objects that are exposed through this application. The syntax for the <wellknown> element is as follows. <service> <wellknown mode="Singleton | SingleCall" displayName="name" type="Type, Assembly" objectUri="objectUri" /> The properties for the <wellknown> element are listed in Table 6-13.
Table 6-13: <wellknown> properties Property
Description
displayname
This property specifies the name by which the NET Framework Configuration Tool will refer to this channel.
mode
This property specifies if this object is a Singleton or SingleCall object.
type
This property specifies the full type name and assembly name of the object.
objectUri
This property specifies the endpoint of the object’s URI.
Using the ElementThe element specifies information about client-activated objects that are exposed to the client by the application. Here is the syntax for the element. 117
<service> The type property specifies the full type name and assembly for this object.
Using the <soapInterop> Section The <soapInterop> section contains a number of sub-sections that declare type mappings used with SOAP. Here are the sub-sections contained in this section.
<preLoad> This sub-section specifies the type of common language runtime to load for the mappings that extend the SoapAttribute class. This sub-section can be used multiple times in the section. This sub-section specifies a bi-directional map between a CLR type and an XML element and namespace. This sub-section specifies a bi-directional map between a CLR type and an XML element and namespace. This section is used when the element name annot be changed.
Using the <preLoad> Element The <preLoad> element is used to map types that extend the SoapAttribute class. Here is the syntax for this element. <soapInterop> <preLoad type="type to load" assembly="assembly to load" /> The properties for this element are listed in Table 6-14.
Table 6-14: <preLoad> properties Property
Description
type
This property specifies the type to load for deserialization. This should include the complete assembly location information.
assembly
This property specifies that all the types in this assembly should be preloaded.
Using the Element The element can create a bi-directional map between a CLR type and an XML element and namespace. Here is the syntax for the element. <soapInterop> 118
The properties for this element are listed in Table 6-15.
Table 6-15: properties Property
Description
clr
This property specifies the type and assembly that you want to map to the XML element and namespace.
xml
This property specifies the XML element and namespace to which you want to map the type and assembly.
Using the ElementThis element can map a type and assembly to an XML type and namespace. Here is the syntax for this element. <soapInterop> Table 6-16 lists the properties for this element.
Table 6-16: properties Property
Description
clr
This property specifies the full type and assembly names that you want to map to the XML type and namespace.
xml
This property specifies the XML type name and namespace to which you want to map the type and assembly specified above.
Working with the Section The section declares channel templates that are referenced when declaring channels in the section. The only section contained in this section is the section. Each section is an individual channel template.
Using the Section Here is the syntax for the section. Table 6-17 lists the properties for the section. 119
Table 6-17: properties Property
Description
id
This property specifies the string that is used to reference this template when declaring the channel.
type
This property specifies the full type and assembly name for this object.
displayName
This property specifies the name that is used by the .NET Framework Configuration Tool.
customChannelProperty
This property specifies a custom property for the channel.
delayLoadAsClientChannel
This property specifies whether this channel should be loaded if the client does not register a channel. true The channel will be loaded at runtime. false The channel will not be loaded.
The two sub-sections for this section are named <serverProviders> and . Here is a description of these sections.
This section contains the providers for channel sinks that are used with the default client-side channel sink call chain. <serverProviders> This section contains the providers for channel sinks that are used with the default server-side channel sink call chain.
Both of these sections use elements named and <provider>. Using the ElementThe element specifies the channel sink provider for a formatter sink that will be inserted into the channel sink chain. Here is the syntax of the element.
Table 6-18 lists the properties for this section.
Table 6-18: properties Property
Description
ref
This property specifies the ID of the formatter sink provider template to use.
type
This property specifies the full type name and assembly name containing the provider implementation.
customFormatterProperty
This property specifies a custom formatter property. 120
Table 6-18: properties Property
Description
includeVersions
This property specifies whether the sending formatter includes complete type and assembly version information. true The complete type and assembly information is included. false The complete type and assembly information is not included.
strictBinding
This property specifies whether the receiving formatter will use the full version information or rely on the type name and assembly. true The receiving formatter will use the full version information. false The receiving formatter will not use the full version information.
typeFilterLevel
This property specifies the level deserialization a formatter attempts.
of
automatic
Using the <provider> Element The <provider> element specifies the channel sink provider for a channel sink that will be inserted into the channel sink chain. Here is the syntax of the <provider> element. <provider ref="Provider Template ID" type="Provider Type, Provider Assembly" customChannelSinkProperty="customProperty" /> Table 6-19 lists the <provider> properties.
Table 6-19: <provider> properties Property
Description
ref
This property specifies the ID of the provider template.
type
This property specifies the full type name and assembly name of the provider implementation.
customChannelSinkProperty
This property specifies a custom channel sink property.
Working with the Section The section creates client and server channel sink provider templates. These templates can be referenced from any of the sections that register a channel sink provider. Here is the syntax of the section. <serverProviders /> 121
Here are the two sections included in the section.
This section contains channel sink templates that will be used with the default client-side channel sink call chain. <serverProviders> This section contains channel sink templates that will be used with the default server-side channel sink call chain.
The <serverProviders> and sections can both use the and <provider> elements. These elements declare channel sink templates as opposed to channel sink instances.
Using the Element The element declares a new formatter template that can be used in the other sections. Here is the syntax of the element. Table 6-20 lists the properties of the element.
Table 6-20: properties Property
Description
id
This property specifies a string that identifies this template.
type
This property specifies the full type name and assembly name that contains the provider implementation.
customFormatterProperty
This property specifies a custom channel sink property.
includeVersions
This property specifies that a sending formatter includes complete type and assembly version information.
strictBinding
This property specifies whether the receiving formatter will identify the type using the complete type version information.
typeFilterLevel
This property specifies the level of automatic deserialization for the channel template.
Using the <provider> Element The <provider> element declares a new provider template that can be used in the other <provider> sections. Here is the syntax of the <provider> element. <provider id="Provider ID" type="Provider Type, Provider Assembly" customChannelSinkProperty="custom property" /> 122
Table 6-21 lists the properties for the <provider> element. Table 6-21: <provider> properties Property
Description
id
This property specifies the string that can be used to reference this template.
type
This property specifies the full type name and assembly name.
customChannelSinkProperty
This property specifies a custom channel property.
Working with the <debug> Section The <debug> section only contains one property. The loadTypes property determines whether all the types specified in the configuration files should be loaded when the application starts. This is very useful because it enables you to quickly see whether each of these types can be loaded. A spelling error will not cause trouble down the road because it would be caught when the application starts. Here is the syntax for setting this property. <system.runtime.remoting> <debug loadTypes="true | false" /> By setting this property to true, all the types will be loaded when the application starts. Although this is very useful when debugging or developing an application, be sure this property is set to false before you deploy your application. This property can be set only in the machine.config or application configuration file. <system.runtime.remoting> Key Points The section enables you to create and configure channel templates to be used in other sections. The section enables you to create and configure channel sink provider templates. The section enables you to configure various remoting options for your application, including adding channels and channel sink providers. The <debug> section is used to require all remoting types to be loaded at the start of the application.
Examining the <system.windows.forms> Group The <system.windows.forms> group contains one property. This property can be set in the machine.config or the application configuration file for your application. This property applies only to Windows forms applications. The property, jitDebugging, enables or disables JIT debugging. JIT debugging allows an installed debugger to respond to any exceptions that have not been handled. By default, when jitDebugging is set to false, the Windows forms will display a window with Continue, Quit, or Details options. By enabling jitDebugging, the exception is handled by the installed debugger. Here is the syntax for setting the jitDebugging value. <system.windows.forms jitDebugging="true | false" /> This property can be set in either the machine.config or the application configuration file for an individual application. 123
Key Points
The <system.diagnostics> section group provides you with a number of different settings that can be used to configure tracing and debugging. The <system.net> section group contains a number of settings that you can use to configure how Web requests are authenticated and the proxy server is used for the request. The <system.runtime.remoting> section group enables you to configure the remoting settings for your application. You can also modify these settings using the .NET Framework Configuration Tool. The <system.windows.forms> section group contains a single setting that enables JIT debugging.
124
Chapter 7: CLR Configuration Settings Overview The three sections covered in this chapter configure settings for the common language runtime. These settings configure which version of the runtime to use, how garbage collection is run, and various cryptography settings. Caution
These settings should be set only in the machine.config file of the server or the application configuration file of your application.
Here are the sections that will be covered in this chapter.
<mscorlib> This section configures mappings between friendly names and cryptography classes. This section specifies which versions of assemblies should be run, and how garbage collection should be run. <startup> This section specifies the common language runtime that should be used when running an application.
Working with the <mscorlib> Section The <mscorlib> section contains settings that configure some of Microsoft .NET Framework’s cryptography capabilities. The elements you will be using are located in this section’s one sub-section, .
Using the Section This sub-section contains two elements that create cryptography mappings and OID mappings. These sections are called and .
Using the Element The element maps security classes to friendly names. This element contains two elements, and . Using the Element The element lists the cryptography classes that will be mapped to the friendly name declared using the element. The element used to create the cryptography class reference is called . Here is the syntax for using the element. Here is an example of a element being used to declare a new class. You can use the element to complete the name mapping. Using the Element The element maps a friendly name to the class you declared in the section. Here is the syntax for the element. Table 7-1 lists the properties for the element.
Table 7-1: properties Property
Description
name
This property is the friendly name used to create an instance of this class.
class
This property is the class name specified in the element.
Here is an example of using the element with the related element. With this mapping in place, you can access the cryptography class by using the System.Security.CryptoConfig.CreateFromName method. Simply pass the name of the class as listed in the to the CreateFromName method. To create an instance of the class declared in the preceding example, use System.Security.CryptoConfig.CreateFromName(“RSA”).
Using the Element The element creates OID or ASN.1 object identifier mappings to classes. ASN.1 object identifiers identify the algorithm for some cryptographic formats. This element has one sub-element named . 126
Using the Element The element maps the OID number to the name of the class specified in the element. Here is the syntax for this element. Table 7-2 lists the properties for the element.
Table 7-2: properties Property
Description
OID
This property specifies the ASN.1 OID for the algorithm implemented by your class.
name
This property specifies the name of the class as specified in the element.
Here is an example of this element being used to map an OID to the class declared in the element. This OID will now map to the class you declared in the example.
Working with the Section The section contains a number of elements and settings that configure how the common language runtime runs. This includes settings for garbage collection and determining which version of an assembly should run. Although you will not use this section a lot in your ASP.NET code, it is still good to be familiar with the options.
127
Using the <developmentMode> Element The <developmentMode> element tells the runtime to search for assemblies in directories specified in the DEVPATH environment variable. Here is the syntax for this element. <developmentMode developerInstallation="true | false" /> Table 7-3 lists the property for this element.
Table 7-3: <developmentMode> property Property
Description
developerInstallation
This property specifies whether the runtime will search for assemblies in the DEVPATH environment variable. true The runtime will search using the path. false The runtime will not search using the path.
Here is an example of this element. <developmentMode developerInstallation="true" /> This example sets the runtime to search for assemblies in the directories specified in the DEVPATH environment variable. The runtime does not look for version information; it uses the first assembly it finds.
Using the Section The section contains a number of sub-sections and attributes. You can use this section to specify assembly version redirections and the locations of different assemblies. First I will cover the attributes you can use with the section, and then I will go over the sub-elements. Here is the syntax for this section. Table 7-4 lists the properties for this section.
Table 7-4: properties Property
Description
xmlns
This property specifies the XML namespace that is required for assembly binding.
appliesTo
This property specifies the version of the .NET Framework to which this assembly redirection applies. This attribute was added with version 1.1 and is ignored by version 1.0.
Here is an example of how to use the properties of this section. 128
This example limits the assembly redirection to only applications that are running on version 1.0 of the .NET Framework. The element also contains a number of sub-elements, which I explain next.
Using the <dependentAssembly> Section The <dependentAssembly> element contains all the specifications for each assembly you want to redirect. This includes information about identification, codebase, which versions to redirect, and more. This element has no attributes, but it does contain a number of subelements. Using the Element The element contains information about the assembly including the name of the assembly, the public key token, and the culture. Every <dependentAssembly> element must contain an element. Here is the syntax for this element. <dependentAssembly> Table 7-5 lists the properties for this element.
Table 7-5: properties Property
Description
name
This property specifies the name of the assembly. This property is required.
publicKeyToken
This property specifies the public key token that is the strong name of the assembly.
culture
This property specifies the country or region of the assembly (usually neutral).
Here is an example of this element. <dependentAssembly> Using the Element The element tells the common language runtime where to find an assembly. Here is the syntax for this element. <dependentAssembly> Table 7-6 contains a list of the properties for the element. 129
Table 7-6: properties Property
Description
version
This property specifies the version of the assembly to which this element applies.
href
This property specifies the location of the assembly.
Here is an example of this element. <dependentAssembly> Using the Element The element redirects one version of an assembly to another. Here is the syntax for this element. <dependentAssembly> Table 7-7 lists the properties for the <dependentAssembly> element.
Table 7-7: <dependentAssembly> properties Property
Description
oldVersion
This property specifies the version of the assembly that will be redirected. You can also enter a range of version numbers (1.0.0.0 – 2.0.0.1).
newVersion
This property specifies the version of the assembly to which the request will be redirected.
Here is an example of this element. <dependentAssembly>
When this assembly is accessed by your application, instead of using version 1.0.0.0 of the application, it will use version 2.0.0.0. Using the Element The element can be used inside either the <dependentAssembly> element or the element. The author of that assembly supplies a publisher policy file that provides information for the transition from one assembly to another. Here is the syntax of this element. 130
lists the property for this element. Table 7-8: property Property
Description
apply
This property specifies whether the publisher policy is applied. yes The publisher policy is applied. no The publisher policy is not applied.
Here is an example of how to use this element. <dependentAssembly> This example would not apply the publisher policy for the “netMail” assembly. You can also use this element under the element. This example would not apply the publisher policy to all the applications.
Using the <probing> Element The <probing> element is a sub-element of the element. You can specify a number of sub-directories in the <probing> element that the runtime will search when loading assemblies. Here is the syntax of this element. <probing privatePath="sub directories" /> The <probing> element’s property is listed in Table 7-9.
Table 7-9: <probing> property Property
Description
privatePath
This property specifies a list of directories separated by semicolons that the runtime will search.
Here is an example <probing> element. <probing privatePath="bin;bin\netmail;bin2" /> 131
In this example, the runtime will include the bin, bin\netmail, and bin2 directories in the search when searching for assemblies.
Using the Element In addition to using the element under the <dependentAssembly> element, you can use the element as a sub-element of . When used as a sub-element of the element, the element will apply to all assemblies, not just a single application. The syntax and attributes of the element are exactly the same when used as a sub-element of the <dependentAssembly> element.
Using the Element The element matches partial assembly names to the full name of the assembly. Here is the syntax for this element. The properties for this element are listed in Table 7-10.
Table 7-10: properties Property
Description
partialName
This property specifies the partial name of the assembly.
fullName
This property specifies the full name of the assembly from the global assembly cache.
Here is an example of this element. Now when you access the netmail assembly from the application, your application will be routed to the global assembly cache listing of this assembly.
132
Using the Element The element specifies whether the common language runtime will run garbage collection in the current thread or in a separate thread. Here is the syntax for this element. Table 7-11 lists the property for this element.
Table 7-11: property Property
Description
enabled
This property specifies whether the garbage collector will run concurrently with the application thread. true The garbage collection will run concurrently with the thread of the application. false The garbage collection will run in a separate thread.
Here is an example of this element. This sets garbage collection to run in a separate thread for your application.
Working with the <startup> Section This section of the configuration file specifies the version of the common language runtime to use when running this application.
Using the <requiredRuntime> Element The <requiredRuntime> element specifies which version of the .NET Framework must be used to run this application. This element is used only by applications that are built using version 1.0 of the .NET Framework. Here is the syntax for this element. <startup> <requiredRuntime version="framework version" safemode="true | false" /> The properties for the <requiredRuntime> element are listed in table 7-12.
Table 7-12: <requiredRuntime> properties Properties
Description
version
This property specifies the version of the .NET Framework that is 133
Table 7-12: <requiredRuntime> properties Properties
Description required by the application. This value must match the directory name under the .NET Framework exactly.
safemode
This property specifies whether the application runs in safe mode. When the application runs in safe mode, it does not look in the registry for the runtime version. true The application will run in safe mode. false the application will not run in safe mode.
Here is an example of this element. <startup> <requiredRuntime version="v1.0.3705" safemode="false" /> This example sets the application to use only version 1.0 of the .NET Framework. It also sets the application to not run in safe mode, enabling it to access the registry for version information.
Using the <supportedRuntime> Element The <supportedRuntime> element specifies the version of the .NET Framework that the application will support. This element should be used by applications built with version 1.1 of the .NET Framework. Here is the syntax of this element. <startup> <supportedRuntime version="version number" /> Table 7-13 lists the property for the <supportedRuntime> element.
Table 7-13: <supportedRuntime> property Property
Description
version
This property specifies the version of the .NET Framework that is supported by this application. This value must match the name of the directory in the .NET Framework directory exactly.
Here is an example of this element. <startup> <supportedRuntime version="v1.0.3705" /> <supportedRuntime version="v1.1.4122" /> In this example, you specify that the application supports both available versions of the .NET Framework, version 1.0 and version 1.1.
134
Key Points
The <mscorlib> section provides sections and elements that map friendly names and OIDs to cryptography classes. The section provides settings that configure which assemblies are used with an application. The element determines whether garbage collection is run concurrently with the application or in a separate thread. The <startup> section specifies what version of the .NET Framework should be used when running your application.
135
Chapter 8: IIS Settings Although you work with the majority of settings for ASP.NET in the configuration files, there are a number of settings that you must configure in the IIS admin tool. This includes additional settings for Microsoft Windows Server 2003 because you configure the ASP.NET process in the IIS admin tool instead of in the <processModel> section of the machine.config file, which is where you configured the ASP.NET process in Microsoft Windows 2000. In this section, I will cover settings and situations for users of both Windows 2000 Server and Windows Server 2003, but I will focus on Windows Server 2003. This chapter doesn’t cover all the settings and configuration options in IIS—entire books could be written on the subject—instead, it focuses on the settings specific to working with ASP.NET.
Enabling ASP.NET Support With Windows 2000 Server, you needed to install the Microsoft .NET Framework on your server to have access to ASP.NET. Because the .NET Framework is included with Windows Server 2003, you need only to enable ASP.NET support for your server. The easiest way to do this is to use the Configure Your Server Wizard to add the application server role. Adding this role will install IIS, ASP.NET, ASP, and COM+ among others. Here’s how to add this role. 1. Open the Configure Your Server Wizard. 2. Click Next on the introduction page. 3. In the Server Role list, select Application Server, and click Next, as shown in Figure 8-1.
Figure 8-1: Select the application server role. 136
4. Select the Enable ASP.NET check box, and the FrontPage Server Extensions check box if desired, and then click Next, as shown in Figure 8-2.
Figure 8-2: Select the Enable ASP.NET check box. 5. Click Next on the summary screen. 6. Click Finish to install IIS with ASP.NET activated. If IIS is already enabled on your server but ASP.NET is not activated, here is a simple way to enable ASP.NET without using the Configure Your Server Wizard. 1. Open the IIS admin tool. 2. Click the Web Services Extensions folder icon. 3. Click ASP.NET in the Web Service Extension list, as shown in Figure 8-3.
137
Figure 8-3: Select the ASP.NET extension in the list. 4.Click the Allow button. ASP.NET will now be installed and ready to use.
ASP.NET IIS Install Utility There is a small utility that can install ASP.NET with IIS in both Windows 2000 Server and Windows Server 2003. To use this utility, navigate to the following location. C:\%winndir%\Microsoft.NET\Framework\v1.1.4322 Then type aspnet_regiis –i. This will install the ASP.NET ISAPI filter and mappings into IIS. There are also a number of other switches that can be used with the aspnet_regiis utility. To see a list of all the switches, type aspnet_regiis-?.
Working with Application Pools Application pools are a new feature in Windows Server 2003 that isolate a group of applications under a common set of worker processes and settings. By isolating applications into application pools, you can restart worker processes without disturbing other application pools on the server. Application pools also provide application isolation so that if an application locks the worker process, it will only affect the applications in the same pool and not all the applications on the server. Instead of configuring settings in the <processModel> section of your machine.config file, you will configure them in each application pool of your server. First I’ll show you how to manage application pools, and then I will cover the configuration settings that can be configured in each application pool. 138
Managing Application Pools You can use the IIS admin tool to easily create and remove application pools from your server. Here is the procedure for adding a new application pool to your server. 1. Right-click the Application Pool directory. 2. Click New and then Application Pool. 3. Name your application pool, and select an option to either create it with the default settings or use another application pool as a template, as shown in Figure 8-4.
Figure 8-4: Enter the name of your application pool, and choose the default settings. 4.Click OK. A new application pool will be created, and you can configure it and add new applications.
Configuring Application Pools Application pools have a large number of settings that configure how the worker processes for the pool behave. To access the configuration settings for your new application pool, right-click the application pool, and click Properties. The Default AppPool Properties dialog box is displayed, as shown in Figure 8-5.
139
Figure 8-5: The Recycling tab of the Default AppPool Properties dialog box. This tab contains settings that control when worker processes are recycled. Table 8-1 lists the settings that are configured on this tab.
Table 8-1: Recycling tab settings Setting
Description
Recycle worker processes (in minutes)
This setting specifies that the worker processes will automatically recycle every X minutes, where X is the amount specified in the selection box.
Recycle worker process (number of requests)
This setting specifies that each worker process will be automatically recycled after it has handled X number of requests, where X is the number of requests specified in the selection box.
Recycle worker processes at the following times
This setting specifies that the worker processes will be automatically recycled at the times specified in the selection box. This is very useful if you know when to expect down time for your application so the worker process can be recycled without any inconvenience to users.
Maximum virtual memory (in megabytes)
This setting specifies that any worker process that consumes more virtual memory than the amount specified in the selection box will be automatically recycled.
Maximum used memory (in megabytes)
This setting specifies that any worker process that consumes more physical memory than the amount 140
Table 8-1: Recycling tab settings Setting
Description specified in the selection box will be automatically recycled.
These settings ensure that no one process will hog the memory resources on the server. They can also be used to periodically recycle processes that might be causing memory leaks or using too much memory. The Performance tab of the Default AppPool Properties dialog box contains settings that monitor the performance of the application pool and the worker processes running in it. Figure 8-6 shows the Performance tab.
Figure 8-6: The Performance tab of the Default AppPool Properties dialog box. Table 8-2 lists the settings on the Performance tab.
Table 8-2: Performance tab settings Setting
Description
Shutdown worker processes after being idle for (time in minutes)
This setting limits the number of minutes that a worker process can remain idle before it will be shut down by the system.
Limit the kernel request queue (number of requests)
This setting limits the number of requests that can be queued for this application pool before 503 HTTP error messages are returned to users.
Enable CPU monitoring
This setting activates CPU monitoring and 141
Table 8-2: Performance tab settings Setting
Description enables the next three settings to be used.
Maximum CPU use (percentage)
This setting specifies the maximum CPU usage allowed before an action is taken.
Refresh CPU usage numbers (in minutes)
This setting specifies the intervals at which the CPU usage should be checked.
Action performed when CPU usage exceeds maximum CPU use
This setting specifies the action performed when the CPU usage is found to have exceeded the maximum CPU use. Currently the only options available are No Action and Shutdown. When Shutdown is selected, the process will be shut down when the CPU use is exceeded.
Maximum processes
This setting specifies the maximum number of worker processes that will be created to handle this application pool.
number
of
worker
Perhaps the most important setting here is the Web garden setting, which enables you to allow multiple worker processes to be created and utilized for this application pool. The Health tab on the Default AppPool Properties dialog box contains worker process health-related settings. Figure 8-7 shows the Health tab.
Figure 8-7: The Health tab of the Default AppPool Properties dialog box. Table 8-3 lists the settings for the Health tab. 142
Table 8-3: Health tab settings Setting
Description
Enable pinging – Ping worker process every (frequency in seconds)
This setting specifies that each worker process will be pinged every X seconds, where X is the number specified in the selection box. This process is used to determine if a worker process is running correctly, or if it has deadlocked.
Enable rapid-fail protection Disable the application pool there are a certain number worker process failures within specified time period
– if of a
This setting shuts down the application pool if X number of worker processes fail in the specified amount of time. X is the value specified in the Failures setting, and the amount of time is specified in the Time Period setting. When a number of worker processes fail in succession it is reasonable to assume that there is a major problem on the server or with an application.
Startup time limit – Worker process must startup within (time in seconds)
This setting specifies the amount of time a worker process is given to start up before the process is terminated and another one is started.
Shutdown time limit – Worker process must shutdown within (time in seconds)
This setting specifies the amount of time a worker process is given to shut down on its own before the process is terminated.
The health settings manage worker processes and ensure that deadlocked or nonresponsive worker processes are shut down. The Identity tab configures the identity used to run the worker process. Figure 8-8 shows the Identity tab.
143
Figure 8-8: The Identity tab of the Default AppPool Properties dialog box. You can use a predefined account or specify a custom account. There are a number of predefined accounts available to use as the identity; these accounts are listed in Table 8-4.
Table 8-4: Identity accounts Identity
Description
Network Service
This identity is the default account. This account has limited access rights to both the local system and the network resources.
Local Service
This identity is the lowest-level account of the built-in accounts. This account has user rights for only the local system, unlike the Network Service account.
Local System
This identity is the highest-level account of the built-in accounts. This account has full access to the entire system.
You can also still use the IUSR_computername, IWAM_computername, and ASPNET accounts by specifying them in the Configurable area of the Identity tab.
Creating a New Application To create new Web applications, you still need to use the IIS admin tool. If you use Microsoft Visual Studio .NET when you create a new Web project, this step is automated, but if you use a tool other than VS.NET, you must manually create the applications. Here is the procedure for adding a new Web application to the server. 144
1. In the left pane of IIS manager, click the Web site or Web site subfolder where you want to host the application. 2. On the Action menu, click New and then Virtual Directory. Then click Next. 3. Enter an alias to use for the virtual directory, and click Next. 4. Point to the physical directory for this application. 5. Select the operations you would like to allow for this application, and then click Next. The default selections are sufficient for an ASP.NET application. 6. Click Finish. The virtual directory is created, marked as an application, and added to the default application pool. To change the application pool that this application is a part of, you need to access the properties of the application. To do so, right-click the application, and click Properties. Then select the application pool for the application. The App 1 Properties dialog box is shown in Figure 8-9.
Figure 8-9: The App 1 Properties dialog box.
Using Windows Authentication In Chapter 4, I covered a number of authentication methods, but Windows authentication was not covered in its entirety. Let’s look at the changes that need to be made in IIS and the code that is used to authenticate users based on Windows authentication. The first step to enabling Windows authentication for your application is setting the authentication mode to Windows in the web.config file of your server. To do this, configure your section as follows. This is the only change needed in the web.config file of your application. Here are the steps for enabling Windows authentication. 145
• • • • •
In IIS Manager, right-click the application, and click Properties. Click the Directory Security tab. In the Authentication And Access Control area, click the Edit button. Clear the Enable Anonymous Access check box. This will specify that users must be authenticated before they can access the application. Select the check box for the method of authentication you want to use, as shown in Figure 8-10.
Figure 8-10: Windows authentication options. You do not need to add any code to your application for this authentication because it is performed by IIS. Accessing the User Identity You can determine the identity of a user who was authenticated with IIS by using a WindowsPrincipal object. A WindowsPrincipal object is attached to each request that is authenticated using Windows authentication. This object can be used to retrieve the user name and determines whether the user is part of a particular role. Here is an example of code that retrieves the user name and checks if the user is part of the Administrators group. C# WindowsPrincipal wpMain = new WindowsPrincipal(WindowsIdentity.GetCurrent()); string sUserName = wpMain.Identity.Name; bool bAdmin = wpMain.IsInRole("Administrators"); 146
VB.NET Dim wpMain As New WindowsPrincipal(WindowsIdentity.GetCurrent()) Dim sUserName As String = wpMain.Identity.Name Dim bAdmin As Boolean = wpMain.IsInRole("Administrators")
The first line of this code creates a new instance of the WindowsPrincipal class based on the user who is currently logged in. The second line pulls the name of the user using the Identity object and the nameproperty. The last line pulls a Boolean value using the IsInRole method that represents whether the user is part of the Administrator Windows group.
Key Points • • • • • • •
You can enable ASP.NET support in Windows Server 2003 by either adding the Application Server role or enabling the ASP.NET Web service extension. You can use the aspnet_regiis utility to install and register ASP.NET with IIS if ASP.NET has not been registered with IIS in either Windows Server 2003 or Windows 2000 Server. Application pools can isolate a group of applications that use the same worker processes and process settings. Application pools contain a number of settings that configure the worker processes that handle the applications in the application pool. Applications must be created using the IIS admin tool unless you are using VS.NET. You can use the IIS admin tool and the section of the web.config file to configure your application to use Windows authentication. You can use the WindowsPrincipal object to determine the user name and role of user accessing your application.
147
Part III: Creating Custom Settings Chapter List Chapter 9: Creating and Using Custom Sections
Part Overview Part III of this book covers how to build and use custom configuration sections and custom configuration section handlers. Custom configuration sections can be used in many ways and are extremely useful when deploying applications or controls.
148
Chapter 9: Creating and Using Custom Sections So far, I have focused on how to use the configuration sections that are installed with the Microsoft .NET Framework. In this chapter, I am going to cover how to create and use custom configuration sections in your applications. Custom configuration sections can solve many business problems. The main advantage of custom configuration sections is that they enable you to modify the configuration settings without having to recompile the application.
Examining the .NET Handlers Configuration section handlers interpret and utilize the configuration sections. (Handlers are covered extensively in Chapter 2.) There are a number of configuration section handlers that are included in the System.Configuration namespace and used by the default configuration sections. Here are the configuration section handlers included in the System.Configuration namespace.
System.Configuration.IgnoreSectionHandler This section handler will not perform any operations on the settings. This handler is used for the <startup>, <mscorlib>, and sections. Use this handler only if you plan on manually reading the settings without using a configuration section handler. System.Configuration.NameValueFileSectionHandler This section handler interprets the section. It is discussed in detail in Chapter 2. System.Configuration.DictionarySectionHandler This section handler reads through the settings and assembles a Hashtable object that holds a variety of keys and values. System.Configuration.SingleTagSectionHandler This section handler reads from a custom section that has multiple values.
These are the only configuration section handlers supplied by default in the System.Configuration namespace. There are a plethora of other handlers available in other namespaces but they are built specifically for those sections and will not help create custom sections. The sections included in the System.Configuration namespace are very useful when building custom configuration sections because you can use these handlers instead of building your own custom section handler.
Creating a Custom Section with the Available Handlers The first type of custom configuration section I will discuss is one that works with the section handlers included in the System.Configuration namespace. The four included handlers make it possible to quickly create custom configuration sections without having to write any code to handle the section; you’ll only need to write code to read the values.
Creating a Section Using NameValueFileSectionHandler The NameValueFileSectionHandler section handler makes it easy to create a custom section similar to the section. This section stores a number of key/value pairs that can then be accessed through a NameValueCollection object. The first step is to declare the section, including the section name and the section handler used to interpret this section, in the section of either the machine.config file of the server or the web.config file of the application. <section name="myAppSettings" 149
type="System.Configuration.NameValueFileSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> This declaration makes it possible for you to create a section named <myAppSettings> in your configuration file that will be handled by the NameValueFileSectionHandler section handler. The next step is to add this section to the configuration file. <myAppSettings> This section will be interpreted by the NameValueFileSectionHandler and made available to your applications through the ConfigurationSettings object. Here is the code to access the keys added to this section. C# NameValueCollection nvcMyAppSettings = ConfigurationSettings.GetConfig("myAppSettings"); Response.Write(nvcMyAppSettings["Key1"].ToString()); Response.Write(nvcMyAppSettings["Key2"].ToString());
VB.NET Dim nvcMyAppSettings As NameValueCollection = _ ConfigurationSettings.GetConfig("myAppSettings") Response.Write(nvcMyAppSettings("Key1").ToString()) Response.Write(nvcMyAppSettings("Key2").ToString())
The GetConfig method of the ConfigurationSettings object creates a NameValueCollection containing all the key/ value pairs that are added to your section. You must pass the name of the section to the GetConfig method. If your section is a subsection or part of a section group, you should specify the section group or parent section before the section name. For example, if your section is in the section group Microsoft, you would specify “Microsoft/MyAppSettings” when calling the GetConfig method.
Creating a Section Using DictionarySectionHandler One of the other default section handlers that can be used to create key/value pair-based sections is the DictionarySectionHandler. This handler works much like the NameValueFileSectionHandler except that it returns a Hashtable object instead of a key/value collection. The procedure is similar to creating a custom section using the NameValueFileSectionHandler. The first step is to declare the section in the section. 150
<section name="myAppSettingsHash" type="System.Configuration.DictionarySectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> After you add this element to the section, you can create a section named <myAppSettingsHash> in the configuration file that will be handled by the DictionarySectionHandler. Here is the section added to the configuration file. <myAppSettingsHash> This section will be interpreted by the DictionarySectionHandler. The values can be read with the same GetConfig method used with the DictionarySectionHandler. Here is the code to access these values from the configuration file. C# HashTable htMyAppSettings = (HashTable) ConfigurationSettings.GetConfig("myAppSettingsHash"); Response.Write(htMyAppSettings["Key1"].ToString()); Response.Write(htMyAppSettings["Key2"].ToString());
VB.NET Dim htMyAppSettings As HashTable = _ CType(ConfigurationSettings.GetConfig("myAppSettingsHash"), _ HashTable) Response.Write(htMyAppSettings("Key1").ToString()) Response.Write(htMyAppSettings("Key2").ToString()) Just like when working with the NameFileValueSectionHandler, you use the GetConfig method and the name of the section to create a Hashtable filled with the key/value pairs added to the section.
Creating a Section Using SingleTagSectionHandler The SingleTagSectionHandler section handler is used in much the same fashion as the last two section handlers except that all the key/value pairs are stored in a single section element instead of in elements. The first step is to declare the section in the section. 151
<section name="myAppSettingsSingle" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> The <myAppSettingsSingle> section will be handled by the SingleTagSectionHandler. You can then add a section that contains multiple key/value pairs in the section element to your configuration file. <myAppSettingsSingle Key1="Our first value" Key2="Our Second value" /> You can access these key/value pairs from your application with a method similar to one that accesses a section that is handled by the DictionarySectionHandler. Here is the code to access these values from your application. C# HashTable htMyAppSettings = (HashTable) ConfigurationSettings.GetConfig("myAppSettingsSingle"); Response.Write(htMyAppSettings["Key1"].ToString()); Response.Write(htMyAppSettings["Key2"].ToString());
VB.NET Dim htMyAppSettings As HashTable = _ CType(ConfigurationSettings.GetConfig("myAppSettingsSingle"), _ HashTable) Response.Write(htMyAppSettings("Key1").ToString()) Response.Write(htMyAppSettings("Key2").ToString())
This handler is similar to the other handlers but you do not have to use the element to add values. This makes the configuration section smaller and easier to read.
Nesting Configuration Sections Custom configuration sections can also be nested inside section groups. This can be very useful when you are organizing multiple collection groups. The first step is to declare the section inside the desired section groups in the section. <sectionGroup name="Microsoft" > <sectionGroup name="Settings" > <section name="myAppSettingsSingle" type="System.Configuration.SingleTagSectionHandler, 152
System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> The section should then be added to the configuration file contained in these section groups. <Microsoft> <Settings> <myAppSettingsSingle Key1="Our first value" Key2="Our Second value" /> In this example, the configuration section is handled by the SingleTagSectionHandler. Here is the code for retrieving these values in your application. C# HashTable htMyAppSettings = (HashTable) ConfigurationSettings. GetConfig("Microsoft/Settings/myAppSettingsSingle"); Response.Write(htMyAppSettings["Key1"].ToString()); Response.Write(htMyAppSettings["Key2"].ToString());
VB.NET Dim htMyAppSettings As HashTable = _ CType(ConfigurationSettings.GetConfig("Microsoft/Settings/" _ & "myAppSettingsSingle"), HashTable) Response.Write(htMyAppSettings("Key1").ToString()) Response.Write(htMyAppSettings("Key2").ToString())
Nesting configuration sections can be a very effective way of grouping various sections into easily recognizable and manageable groups.
Creating a Custom Section with a Custom Section Handler The default section handlers are very useful when creating sections that will hold a number of key/value pairs, but to get more functionality you have to write a custom section handler. In this section, I cover how to create and apply custom configuration sections and section handlers.
153
Examining the IConfigurationSectionHandler Interface I’ve mentioned this interface throughout the book, but now I will cover it in depth. The IConfigurationSectionHandler interface can be used to create a configuration section handler that is used by the .NET configuration architecture. The IConfigurationSectionHandler interface requires that the class include a method called Create, which returns an object. Here is a sample class that implements the IConfigurationSectionHandler interface. C# using System; using System.Data; using System.Data.SqlClient; using System.XML; using System.Configuration; namespace MicrosoftConfig { public class CustomHandlerExample : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) { //Handler Code Here } } }
VB.NET Imports System Imports System.Data Imports System.Data.SqlClient Imports System.XML Imports System.Configuration
Namespace MicrosoftConfig Public Class CustomHandlerExample Implements IConfigurationSectionHandler Public Function Create(parent As Object, configContext As _ Object, section As XmlNode) As Object Implements _ 154
IConfigurationSectionHandler.Create 'Handler Code Here End Function End Class End Namespace
The class implements the IConfigurationSectionHandler and includes a single method called Create. You will implement the code that will interpret the configuration section inside this method. The Create method accepts three different parameters. Table 9-1 lists these parameters.
Table 9-1 : Create method parameters Parameter
Description
parent – object
The first object passed to the method contains configuration settings from any parent configuration sections.
configContext – object
The second object passed to this method is the HttpConfigurationContext object. This object can determine the virtual path used to access this resource.
section – XmlNode
The XmlNode contains the XML of the configuration section that this handler is interpreting.
The Create method returns a plain object that will have to be cast when read by the application. The Create method is the only method required by the interface.
Creating a Simple Custom Section Handler Let’s create a simple custom section handler that reads a single value from the configuration section and returns it to your application. Before building the section handler code, enter your configuration section and section handler declaration into either the machine.config or web.config file of your application. Here is the simple section you will be using for this example. <MicrosoftConfig MyHomePage="http://www.microsoft.com" /> This section includes a single setting that will be read by the handler. You need to add the section to where you declare the configuration section handler for this configuration section. Here is the entry in the section. <section name="MicrosoftConfig" type="MicrosoftConfig.CustomHandlerExample, MicrosoftConfig, Version=1.0.0.0, Culture=neutral, PublicKeyToken= a1690a5ea44bab32" /> The <MicrosoftConfig> section will now be handled by the MicrosoftConfig.CustomHandlerExample section handler. The section handler still does not 155
do anything, though; you need to write the code that examines the XML of the configuration section and returns the values to your application. Using the XmlNode object that is passed to the Create method, you can read the value of the single property in the configuration section.
C# using System; using System.Data; using System.Data.SqlClient; using System.XML; using System.Configuration; namespace MicrosoftConfig { public class CustomHandlerExample : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) { string sHomePage; sHomePage = section.Attributes.Item[0].Value; return sHomePage; } } }
VB.NET Imports System Imports System.Data Imports System.Data.SqlClient Imports System.XML Imports System.Configuration
Namespace MicrosoftConfig Public Class CustomHandlerExample Implements IConfigurationSectionHandler Public Function Create(parent As Object, configContext As _ 156
Object, section As XmlNode) As Object Implements _ IConfigurationSectionHandler.Create Dim sHomePage As String sHomePage = section.Attributes.Item(0).Value Return sHomePage End Function End Class End Namespace
The first line of this handler creates a new string object to store the value. The second line pulls the value from the section object, which is passed to the method. The third line returns this value. Now that the section handler is complete, you can access this value from your application using the following code. C# string sHomePage; sHomePage = (string) ConfigurationSettings.GetConfig("MicrosoftConfig"); Response.Write("MyHomePageIs:" + sHomePage;
VB.NET Dim sHomePage As String sHomePage CStr(ConfigurationSettings.GetConfig("MicrosoftConfig"))
=
Response.Write(("MyHomePageIs:" + sHomePage))
By using the GetConfig method, the configuration section will be interpreted by the configuration section handler and a string will be returned. In the next section, you will build a more complex and robust configuration section and section handler.
Creating a Complex Custom Section Handler A simple section handler can be very useful, but there are times when you want to store a lot more than a single value. Using custom section handlers, you can store a large number of settings in collection objects or you can return a completely different object type. In this section, I’ll show you how to use a single section to store a number of settings groups as well as how to use these settings to provide objects to other classes. In the following examples, you build a configuration section for a fictitious Web application. The application is called DNetReporting and it creates reports from various data sources and then either prints or e-mails these reports. You will use configuration sections as well as section handlers and other classes to store a number of configuration settings for this 157
application. The first step is to create a configuration section that includes some sample settings. <Emails> <Email name="James Avery" address="
[email protected]" /> <Email name="Accountants" address="
[email protected]" /> This configuration section will store the license key for the application, each of the data sources, the e-mail addresses, and the printers. The next step is to create an entry for this configuration section in the section. <section name="DNetReporting" type="DNetReporting.ConfigHandler, DNetReporting /> Now you will build the section handler that reads these settings from the configuration file. Here is the code for the base of the section handler, which is very similar to the section handler built earlier. C# using System; using System.Data; using System.Data.SqlClient; using System.XML; using System.Configuration; namespace DNetReporting { public class ConfigHandler : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) 158
{ string sHomePage; sHomePage = section.Attributes.Item[0].Value; return sHomePage; } } }
VB.NET Imports System Imports System.Data Imports System.Data.SqlClient Imports System.XML Imports System.Configuration
Namespace DNetReporting Public Class ConfigHandler Implements IConfigurationSectionHandler Public Function Create(parent As Object, configContext As _ Object, section As XmlNode) As Object Implements _ IConfigurationSectionHandler.Create Dim sHomePage As String sHomePage = section.Attributes.Item(0).Value Return sHomePage End Function End Class End Namespace
The configuration section handler must be able to inherit any parent configuration settings. The first object parameter, which you named parent, contains settings that the handler should inherit. You will store your settings in a Hashtable object, so this is the object that will be passed through the parent object. Here is the code you add to the Create method to ensure that this data is inherited. C# Hashtable parentConfig = (Hashtable) parent; Hashtable config; if (parentConfig != null) 159
{ config = (Hashtable) parentConfig.Clone(); } else { config = new Hashtable(); }
VB.NET Dim parentConfig As Hashtable = CType(parent, Hashtable) Dim config As Hashtable If Not (parentConfig Is Nothing) Then config = CType(parentConfig.Clone(), Hashtable) Else config = New Hashtable() End If
The first line of this code casts the parent object to a Hashtable. The second line creates the Hashtable in which you will store your settings. The If statement that starts on the third line tests whether the parentConfig Hashtable is not null. If the Hashtable exists, there are settings from which the new settings should be inherited. If a parent Hashtable exists, the new Hashtable will be a clone of the parent Hashtable; if a parent Hashtable does not exist, the Hashtable will be new. The next step in your custom section handler is to step through the XML elements and determine what should be done with the different sub-sections and elements. Here is the code to step through the XML elements of the section. C# foreach (XmlNode child in section.ChildNodes) { if(child.NodeType != XmlNodeType.Comment && child.NodeType != XmlNodeType.Whitespace) { switch (child.Name) { case "License": config["License"] = child.Attributes.Item(0).Value; break;
160
case "DataSources": config["DataSources"] = ReadSection( config["DataSources"], child, "connstring"); break; case "Emails": config["Emails"] = ReadSection(config["Emails"], child, "address"); break; case "Printers": config["Printers"] = ReadSection(config["Printers"], child, "localname"); break; } } }
VB.NET Dim child As XmlNode For Each child In section.ChildNodes If child.NodeType XmlNodeType.Comment And child.NodeType _ XmlNodeType.Whitespace Then Select Case child.Name Case "License" config("License") = child.Attributes.Item(0).Value Case "DataSources" config("DataSources") = ReadSection(_ config("DataSources"), child, "connstring") Case "Emails" config("Emails") = ReadSection(config("Emails"), _ child, "address") Case "Printers" config("Printers") = ReadSection(config("Printers "), _ child, "localname") End Select 161
End If Next child
This code uses a For statement to step through each of the XML nodes found in the configuration section. Use the following code to check that each XML node in the section is not a comment or white space. If child.NodeType XmlNodeType.Comment And child.NodeType XmlNodeType.Whitespace Then If the node is not a comment or white space, a case statement checks the name of the node and performs a certain action based on the name of that node. For example, if the node is named “License,” the value of the node is added to Hashtable under the “License” key. For the other three node types (printers, emails, and datasources), the case statement calls an outside method because multiple values are possible for each of these nodes. To handle this, the outside method creates a Hashtable for each of these settings that is added to the config Hashtable. Here is the ReadSection method that creates a Hashtable containing all the values for each section. To accommodate the different value names for each section, the third parameter specifies the value attribute string that should be used for each section. C# private string
Hashtable
ReadSection(object
parent,
XmlNode
section,
sValueAttribute) { Hashtable parentConfig = (Hashtable) parent; Hashtable config; if (parentConfig != null) { config = (Hashtable) parentConfig.Clone(); } else { config = new Hashtable(); } foreach (XmlNode child in section.ChildNodes) { if(child.NodeType != XmlNodeType.Comment && child.NodeType != XmlNodeType.Whitespace) { config[child.Attributes.GetNamedItem("name").Value] = child.Attributes.GetNamedItem(sValueAttribute).Va lue; 162
} } return config; }
VB.NET Private Function ReadSection(parent As Object, section As XmlNode, _ sValueAttribute as string) As Hashtable Dim parentConfig As Hashtable = CType(parent, Hashtable) Dim config As Hashtable If Not (parentConfig Is Nothing) Then config = CType(parentConfig.Clone(), Hashtable) Else config = New Hashtable() End If Dim child As XmlNode For Each child In section.ChildNodes If child.NodeType XmlNodeType.Comment And _ child.NodeType XmlNodeType.Whitespace Then config(child.Attributes.GetNamedItem("name").Value) = _ child.Attributes.GetNamedItem(sValueAttribute).Value End If Next child Return config End Function
The first portion of this method is exactly the same as the code in the Create method. It is used to inherit any settings that were set in an earlier configuration section. Then a For statement steps through all the child nodes in the section and adds the values to a Hashtable. This Hashtable is then returned and added to the Hashtable created by the Create method. This completes the actual section handler, but it would be nice to also provide a class that can access these various collections. Here is the code for a simple class that provides access to these collections without calling the GetConfig method. C# using System; using System.Collections; 163
using System.Configuration; namespace DNetReporting { public class ConfigSettings { public static Hashtable Printers() { Hashtable config = GetConfig(); return (Hashtable) config["Printers"]; } public static Hashtable Emails() { Hashtable config = GetConfig(); return (Hashtable) config["Emails"]; } public static Hashtable DataSources() { Hashtable config = GetConfig(); return (Hashtable) config["DataSources"]; } public static string License() { Hashtable config = GetConfig(); string sLicense = config["License"].ToString(); return sLicense; }
private static Hashtable GetConfig() { Hashtable configTable = (Hashtable) ConfigurationSettings.GetConfig("DNetReporting"); return configTable; } } } 164
VB.NET Imports System Imports System.Collections Imports System.Configuration Namespace DNetReporting Public Class ConfigSettings Public Shared Function Printers() As Hashtable Dim config As Hashtable = GetConfig() Return CType(config("Printers"), Hashtable) End Function Public Shared Function Emails() As Hashtable Dim config As Hashtable = GetConfig() Return CType(config("Emails"), Hashtable) End Function Public Shared Function DataSources() As Hashtable Dim config As Hashtable = GetConfig() Return CType(config("DataSources"), Hashtable) End Function Public Shared Function License() As String Dim config As Hashtable = GetConfig() Dim sLicense As String = config("License").ToString( ) Return sLicense End Function Private Shared Function GetConfig() As Hashtable Dim configTable As Hashtable = _ CType(ConfigurationSettings.GetConfig("DNetReport ing"),_ Hashtable) Return configTable End Function End Class End Namespace 165
This class makes a number of methods available to access these Hashtables without having to work directly with the configuration section handler. For instance, if you wanted to fill a drop-down list with the values from the Emails Hashtable, you could use the following code. C# Hashtable htEmail = ConfigSettings.Emails(); DropDownList2.DataTextField = "Key"; DropDownList2.DataValueField = "Value"; DropDownList2.DataSource = htEmail; DropDownList2.DataBind();
VB.NET Dim htEmail As Hashtable = ConfigSettings.Emails() DropDownList2.DataTextField = "Key" DropDownList2.DataValueField = "Value" DropDownList2.DataSource = htEmail DropDownList2.DataBind()
This code creates an instance of the Emails Hashtable and then binds it to the drop-down list. This more complex section handler shows how to store multiple sections and settings in the configuration file and then access them through your application. This enables you to avoid using a database for just a couple of settings, and make changes to these settings without recompiling the application.
Key Points • • • •
You can use a number of default configuration section handlers to create simple collection-based custom sections, including SingleTagSectionHandler, NameValueFileSectionHandler, and DictionarySectionHandler. You can use the IConfigurationSectionHandler interface to create a custom configuration section handler. You can create a complex configuration section handler that uses multiple sections and multiple collection objects. You can use custom configuration sections to avoid using databases for small amounts of information.
166
• Part IV: Appendix and Glossary Chapter List Appendix: Microsoft .NET Framework Configuration Tool Glossary
167
Appendix: Microsoft .NET Framework Configuration Tool The .NET Framework Configuration tool is a MMC snap-in that performs a number of .NET configuration procedures. Although these procedures are not directly related to ASP.NET, they can be used with ASP.NET applications. Here are the areas I cover in this appendix.
Managing the Global Assembly Cache Configuring remoting services Adjusting .NET Framework security settings and levels Configuring and repairing local .NET applications
To access the .NET Framework Configuration tool, navigate to the administrative tools folder in the control panel of your system, and double-click the .NET Framework Configuration tool icon. The tool is shown in Figure A-1.
Figure A-1: The .NET Framework Configuration tool. Each of the items on the left includes a help topic page that appears the first time you click an item. This page contains information about the settings and includes links to common procedures. If you want to access the help topic page after the first time you select the item, right-click the item, click View, and then click Help Topic.
Managing the Global Assembly Cache The global assembly cache (GAC) is a central location where assembly references can be stored and accessed by applications anywhere on your machine. Multiple versions of the same assembly can be stored in the GAC, which makes it possible for two different applications to use two different versions of the same assembly. The .NET Framework Configuration tool provides a number of functions related to the GAC, including the ability to view, add, and edit cache entries. 168
Viewing All the Assemblies in the GAC The first link in the help topic page for the Assembly Cache item is View List of the Assemblies in the Assembly Cache. Clicking this link, or right-clicking the Assembly Cache item, clicking View, and then clicking Assemblies displays a complete list of all the assemblies currently in the global assembly cache. Figure A-2 shows the list of assemblies in the assembly cache.
Figure A-2: A list of all the assemblies that are currently in the assembly cache. To view the properties for an assembly in the cache, right-click the assembly, and click Properties, or double-click the assembly. This will display the assembly name, culture, version, public key token, codebase, and cache type. The assembly name, culture, version, and public key token are used to access the assembly from your applications. The codebase property specifies a URL path to the assembly. The cache type property specifies how the assembly should be stored in the assembly cache. The most common value is gac, which specifies that the assembly should be stored as a normal assembly in the cache. The other possible value is zap, which specifies that the assembly was created using the native image generator and the assembly will be stored in native image cache. You can also use the assembly list to delete an assembly from the cache by pressing the Delete key, or right-clicking the assembly and clicking Delete.
Adding a New Assembly to the GAC You can use the .NET Framework Configuration tool to add new assemblies to the global assembly cache. To add a new assembly, either right-click the Assembly Cache item and click Add, or click the second link on the Assembly Cache help topic page. After starting the add process, you will be prompted to select the assembly to add to the cache. After you select the file, it will be added to the assembly cache.
169
Configuring Assemblies You can use the .NET Framework Configuration tool to configure the assemblies that are included in the global assembly cache. There are two policy settings that are configured with this tool: the codebase setting and assembly version binding. The codebase setting specifies the location of a particular version of the assembly. This can be either a location local to the system, or a URI pointing to an Internet resource. This can be extremely valuable when the needed assembly does not exist on the system. The assembly bindings settings can also specify the version that should be used when a particular version is requested. Assembly binding routes a particular assembly request to a different version of the assembly. The configured assemblies item provides you with another help topic page. This page has two links: one to view the assemblies that have already been configured, and another to configure a new assembly.
Configuring a New Assembly To configure a new assembly, either click the second link on the help topic page, or rightclick the Configured Assemblies item, and click Add. This will open a dialog box in which you can choose the assembly you want to configure. Figure A-3 shows this dialog box. When configuring assemblies, it does not matter what version you select; the configuration settings are set based on the assembly name and public key token.
Figure A-3: The Configure An Assembly dialog box. You can use this dialog box to select the assembly you want to configure by either manually specifying the assembly name and the public key token of the assembly, or by selecting the Choose Assembly From The Assembly Cache option. When you select the Choose Assembly From The Assembly Cache option, you then choose the assembly you want to 170
configure from any of the assemblies in the global assembly cache. After you specify the assembly, click the Finish button, and the Properties dialog box for the assembly will appear. This dialog box is shown in Figure A-4.
Figure A-4: The Properties dialog box for a configured assembly. You can use the Properties dialog box to configure both assembly bindings and the codebase property.
Configuring Assembly Bindings for an Assembly You can use assembly binding to route a GAC request from one version number to another. For example, you might have an assembly that is version 1.0.1.2, and a number of applications that reference this assembly from the GAC. Perhaps you fixed a couple of minor bugs, and the new version of the assembly is 1.0.1.4. You would need to recompile each of these applications to use the new assembly version because when referencing an assembly from the GAC, you specify the assembly name, public key token, and version number. Instead of doing this, you can simply specify a new assembly bindings redirect, and any references to the 1.0.1.2 version of the assembly will be redirected to the 1.0.1.4 version of the assembly. On the Binding Policy tab of the assembly’s Properties dialog box, enter the first version number in the Requested Version box and the new version number in the New Version box. Figure A-5 shows the Binding Policy tab with the binding redirection in place.
171
Figure A-5: The Binding Policy tab with binding redirection. You can also specify a range of version numbers that should be redirected to the new version. Specify the first and last version numbers with a dash between them, for example: 1.0.1.0 – 1.0.1.4.
Configuring the Codebase Settings for an Assembly The codebase setting specifies the location of one version of the assembly. This location can be on the Web or the local system. You can configure the codebase setting for the application on the Codebases tab of the assembly’s Properties dialog box. First enter the version number in the Requested Version box, and then enter the location of the assembly including the protocol. For example, http: //www.microsoft.com/MyAssembly.dll Figure A-6 shows the Codebases tab of the Properties dialog box with a codebase setting specified.
172
Figure A-6: The Codebases tab of the Properties dialog box. When this version of the assembly is requested, if the assembly is not already loaded on the system, the assembly will be retrieved from the location specified here.
Modifying a Configured Assembly To modify the configuration settings of an assembly that has already been configured, select the first option on the help topic page, or right-click the Configured Assemblies item, click View and then Assemblies. Either of these methods will display a list of assemblies that have already been configured. You then right-click the assembly that you want to edit, and click Properties to display the assembly’s Properties dialog box.
Configuring Remoting You can use the .NET Framework Configuration tool to configure settings for the remoting channels on your system. To access these settings, either click the link on the Remoting Services help topic page, or right-click the Remoting Services item, and click Properties. Figure A-7 shows the Remoting Services Properties dialog box.
173
Figure A-7: The Remoting Services Properties dialog box. The Select Channel To Configure drop-down list contains all the available remoting channels on this system. Selecting a channel will display all the configurable settings for that channel. By default, there are two channels available: http client and tcp client. Both of these channels have a single property called DelayLoadAsClientChannel, which is used to determine whether the channel should be loaded even if the client does not register a channel. I covered this property in Chapter 6, in the section that discussed remoting.
Adjusting .NET Security Settings You can also use the .NET Framework Configuration tool to configure the runtime security policy. There are a number of links on the Runtime Security Policy help topic page; each of these links enables you to perform a security operation that affects the runtime security policy. Clicking a link launches a wizard that can be used to adjust the runtime security policy at a particular level. The runtime security policy can be set at three levels: enterprise, machine, and user. Table A-1 lists the security policy levels.
Table A-1: Security policy levels Policy level
Description
Enterprise
This security policy applies to the entire enterprise.
Machine
This security policy applies to the local machine.
User
This security policy applies only to the user currently logged into the machine. 174
A security policy is made up of a number of security settings that can be configured at each level.
Increasing an Assembly’s Trust The first link on the runtime security policy help topic page is the Increase Assembly Trust link. To start the Trust An Assembly Wizard, either click this link, or right-click the Runtime Security Policy item, and click Trust Assembly. The Trust An Assembly Wizard can be used to increase the amount of trust that is given to a particular assembly. The first option in the Trust An Assembly Wizard is shown in Figure A-8.
Figure A-8: The first page of the Trust An Assembly Wizard. On the first page of this wizard, you choose whether this trust increase should apply to the local system or only to the currently logged-in user. This determines whether the change will be made to the machine or user level of settings. After choosing the level, click Next. On the next page of the wizard, you choose the assembly whose trust you want to increase. After selecting the assembly, click Next to display the next page of the wizard, shown in Figure A-9.
175
Figure A-9: The third page of the Trust An Assembly Wizard. T
T
HT
You have a number of choices on this page. The first is to adjust the trust for only the single assembly that you chose. The second is to configure the trust for all assemblies made by the publisher of this assembly. The third is to trust all assemblies with the same public key token. After selecting an option, click Next to display the next page of the wizard, shown in Figure A-10. TH
176
Figure A-10: Select the trust level to assign to the assembly. T
T
On this page, you use a slide bar to change the level of trust for this assembly. Make your change, and click Next to display the wizard’s last page and complete the wizard.
Adjust Zone Security The second link on the Runtime Security Policy help topic page enables you to adjust the level of trust that is given to an assembly based on the zone from which that assembly comes. To start the Adjust Zone Security Wizard, either click the second link on the help topic page, or right-click the Runtime Security Policy item, and click Adjust Security. On the wizard’s first page, choose whether these changes will apply to the entire system or to only the currently logged-in user. After choosing the level to which these changes will apply, click Next to display the wizard’s second page, shown in Figure A-11. HT
177
TH
Figure A-11: The second page of the Security Adjustment Wizard. T
T
On this page, you set the default trust level for assemblies coming from a zone by selecting the zone and then setting the trust level using the sliding bar. After making the changes, click Next to display the wizard’s last page, and then click Finish to complete the changes.
Evaluating an Assembly You can use the Security Adjustment Wizard to evaluate the security settings that are applied to a particular assembly, including the level at which these settings are applied and the code groups that grant these security rights. To display the Evaluate An Assembly Wizard, click the Evaluate Assembly link on the help topic page, or right-click the Runtime Security item and click Evaluate Assembly. The Evaluate An Assembly Wizard is shown in Figure A-12. HT
TH
178
Figure A-12: Choose the assembly that you want to evaluate. T
T
After selecting the assembly that you want to evaluate, choose which security setting you want to see. You can choose whether you want to see the settings granted to the assembly or the code groups that grant these settings. You can also choose the level to use when evaluating these settings; you can choose user, machine, enterprise, or all levels. After selecting the level at which you want to evaluate the assembly, click Next to display the permissions that are assigned to this assembly.
Creating a Deployment Package After you have customized your security policy, you will need to deploy it to any other systems that should have identical policies. The easiest way to do this is to create a deployment package, which is an .msi file that is used on a client system to install the security policy. To start the process, either click the Create A Deployment Package link on the help topic page, or right-click the Runtime Security Policy item, and click Create Deployment Package. This will display the Deployment Package Wizard, shown in Figure A-13. HT
TH
Figure A-13: The Deployment Package Wizard. T
T
In the Deployment Package Wizard, you can choose the security policy level to include in the package and specify the file name and location where the package will be saved. This package can then deploy the security policy through a logon script, SMS, or another deployment method.
179
Resetting All Policy Levels To reset all the security settings to the default settings, click the last link on the Runtime Security Policy help topic page, or right-click the Remote Security Policy item, and click Reset All. This will remove all custom configurations and return the settings to the defaults.
Configuring and Repairing .NET Applications You can use the .NET Framework Configuration tool to configure and repair individual applications. The settings configured in this section apply only to each individual application, not the entire system.
Configuring an Application If you don’t already have an application to configure, the first step is to add one. To do this, either click the Add An Application To Configure link on the Application’s help topic page, or right-click the Applications topic, and click Add. You then either choose the application from a list, or click Other, and select the .exe file from your hard disk. Click OK to add the application to the tool.
Viewing Application Properties You can view the properties of the application by selecting the first link on the application’s help topic page. This will display the application’s Properties dialog box, shown in Figure A14. HT
TH
Figure A-14: The application’s Properties dialog box. T
T
In the first setting, you specify whether garbage collection is run in the background (concurrently) or in the foreground (separately). The Enable Publisher Policy check box is 180
selected by default, which means that a policy file included by the publisher will be used to set the security settings for this application. The last setting on this page sets a commadelimitated list of directories for the application to use when searching for assemblies.
Viewing Assembly Dependencies To view the application’s assembly dependencies, click the Assembly Dependencies item, and then click the link on the help topic page. Clicking this link will display a list of all the assemblies on which this application depends.
Configuring Assemblies Just as you can configure assemblies for the entire system, you can configure assemblies for each application. You can configure assembly bindings and codebase settings for each assembly at the application level.
Configuring Application Remoting Services You can use the Remoting Services item to configure a number of remoting settings related to your application. On the Remoting Services Properties dialog box, you can configure the location of the remote applications that this application uses, as well as the types that are exposed by this application.
Fixing an Application To fix an application, first either right-click the configured application item, and click Fix, or right-click the Applications item, click Fix An Application, and then choose the application you want to fix. The .NET Framework Configuration tool will examine the application, look for any broken dependencies, and then correct the application’s configuration file.
181