This book is a collection of ASP.NET recipes that aims to help you quickly and efficiently solve many of the day-to-day problems you face developing web applications with the .NET platform.
Chapter 1. Tabular Data
Introduction
Recipe 1.1. Selecting the Right Tabular Control
Recipe 1.2. Generating a Quick-and-Dirty Tabular Display
Recipe 1.3. Enhancing the Output of a Tabular Display
Recipe 1.4. Displaying Data from an XML File
Recipe 1.5. Displaying an Array as a Group of Checkboxes
Recipe 1.6. Displaying Data from a Hashtable
Recipe 1.7. Adding Next/Previous Navigation to a DataGrid
Recipe 1.8. Adding First/Last Navigation to a DataGrid
Recipe 1.9. Adding Direct Page Navigation to a DataGrid
Recipe 1.10. Paging Through a Record-Heavy DataGrid
Recipe 1.11. Sorting Data Within a DataGrid
Recipe 1.12. Sorting Data in Ascending/Descending Order Within a DataGrid
Recipe 1.13. Combining Sorting and Paging in a DataGrid
Recipe 1.14. Editing Data Within a DataGrid
Recipe 1.15. Formatting Columnar Data in a DataGrid
Recipe 1.16. Allowing Selection Anywhere Within a DataGrid Row
Recipe 1.17. Adding a Delete Confirmation Pop Up
Recipe 1.18. Displaying a Pop-Up Details Window
Recipe 1.19. Adding a Totals Row to a DataGrid
Chapter 2. Validation
Introduction
Recipe 2.1. Requiring that Data be Entered in a Field
Recipe 2.2. Requiring Data to Be In a Range
Recipe 2.3. Requiring that Two Data Input Fields Match
Recipe 2.4. Requiring that Data Matches a Predefined Pattern
Recipe 2.5. Requiring that a Drop-Down List Selection Be Made
Recipe 2.6. Requiring Data to Match a Database Entry
Chapter 3. Forms
Introduction
Recipe 3.1. Using the Enter Key to Submit a Form
Recipe 3.2. Using the Enter Key to Submit a Form After Validation
Recipe 3.3. Submitting a Form to a Different Page
Recipe 3.4. Simulating Multipage Forms
Recipe 3.5. Setting the Initial Focus to a Specific Control
Recipe 3.6. Setting the Focus to a Control with a Validation Error
Chapter 4. User Controls
Introduction
Recipe 4.1. Sharing a Page Header on Multiple Pages
Recipe 4.2. Creating a Customizable Navigation Bar
Recipe 4.3. Reusing Code-Behind Classes
Recipe 4.4. Communicating Between User Controls
Recipe 4.5. Adding User Controls Dynamically
Chapter 5. Custom Controls
Introduction
Recipe 5.1. Combining HTML Controls in a Single Custom Control
Recipe 5.2. Creating a Custom Control with Attributes
Recipe 5.3. Creating a Custom Control with State
Recipe 5.4. Customizing an ASP.NET TextBox Server Control
Chapter 6. Maintaining State
Introduction
Recipe 6.1. Maintaining Information Needed by All Users of an Application
Recipe 6.2. Maintaining Information about a User Throughout a Session
Recipe 6.3. Preserving Information Between Postbacks
Recipe 6.4. Preserving Information Across Multiple Requests for a Page
Chapter 7. Error Handling
Introduction
Recipe 7.1. Handling Errors at the Method Level
Recipe 7.2. Handling Errors at the Page Level
Recipe 7.3. Handling Errors at the Application Level
Recipe 7.4. Displaying User-Friendly Error Messages
Chapter 8. Security
Introduction
Recipe 8.1. Restricting Access to All Application Pages
Recipe 8.2. Restricting Access to Selected Application Pages
Recipe 8.3. Restricting Access to Application Pages by Role
Recipe 8.4. Using Windows Authentication
Chapter 9. Configuration
Introduction
Recipe 9.1. Overriding Default HTTP Runtime Parameters in web.config
Recipe 9.2. Adding Custom Application Settings in web.config
Recipe 9.3. Displaying Custom Error Messages
Recipe 9.4. Maintaining Session State Across Multiple Web Servers
Recipe 9.5. Accessing Other web.config Configuration Elements
Recipe 9.6. Adding Your Own Configuration Elements to web.config
Chapter 10. Tracing and Debugging
Introduction
Recipe 10.1. Uncovering Page-Level Problems
Recipe 10.2. Uncovering Problems Application Wide
Recipe 10.3. Pinpointing the Cause of an Exception
Recipe 10.4. Uncovering Problems Within Web Application Components
Recipe 10.5. Uncovering Problems Within Dual-Use Components
Recipe 10.6. Writing Trace Data to the Event Log with Controllable Levels
Recipe 10.7. Using a Breakpoint to Stop Execution of an Application When a Condition Is Met
Recipe 10.8. Stress Testing a Web Application or Service
Chapter 11. Web Services
Introduction
Recipe 11.1. Creating a Web Service
Recipe 11.2. Consuming a Web Service
Recipe 11.3. Creating a Web Service That Returns a Custom Object
Recipe 11.4. Setting the URL of a Web Service at Runtime
Chapter 12. Dynamic Images
Introduction
Recipe 12.1. Drawing Button Images on the Fly
Recipe 12.2. Creating Bar Charts on the Fly
Recipe 12.3. Displaying Images Stored in a Database
Recipe 12.4. Displaying Thumbnail Images
Chapter 13. Caching
Introduction
Recipe 13.1. Caching Pages
Recipe 13.2. Caching Pages Based on Query String Parameter Values
Recipe 13.3. Caching Pages Based on Browser Type and Version
Recipe 13.4. Caching Pages Based on Developer-Defined Custom Strings
Recipe 13.5. Caching User Controls
Recipe 13.6. Caching Application Data
Chapter 14. Internationalization
Introduction
Recipe 14.1. Localizing Request/Response Encoding
Recipe 14.2. Providing Multiple Language Support
Recipe 14.3. Overriding Currency Formatting
Chapter 15. File Operations
Introduction
Recipe 15.1. Downloading a File from the Web Server
Recipe 15.2. Uploading a File to the Web Server
Recipe 15.3. Processing an Uploaded File Without Storing It on the Filesystem
Recipe 15.4. Storing the Contents of an Uploaded File in a Database
Chapter 16. Performance
Introduction
Recipe 16.1. Reducing Page Size by Selectively Disabling the ViewState
Recipe 16.2. Speeding up String Concatenation with a StringBuilder
Recipe 16.3. Speeding Up Read-Only Data Access
Recipe 16.4. Speeding Up Data Access to a SQL Server Database Using the SQL Provider
Chapter 17. HTTP Handlers
Introduction
Recipe 17.1. Creating a Reusable Image Handler
Recipe 17.2. Creating a File Download Handler
Chapter 18. Assorted Tips
Introduction
Recipe 18.1. Accessing HTTP-Specific Information from Within a Class
Recipe 18.2. Executing External Applications
Recipe 18.3. Transforming XML to HTML
Recipe 18.4. Determining the User's Browser Type
Recipe 18.5. Dynamically Creating Browser-Specific Stylesheets
Recipe 18.6. Saving and Reusing HTML Output
Recipe 18.7. Sending Mail
Recipe 18.8. Creating and Using Page Templates
This book is organized into 18 chapters, each of which focuses on a distinct ASP.NET topic area.
Chapter 1
In its simplest form, displaying tabular data is easy in ASP.NET. Drop in an ASP.NET grid control, connect to the database, and bind it to the control—simple enough. But it doesn't take long before you realize that the default appearance and behavior of the control is lacking. Indeed, you may even find that the control you've chosen is too bulky, too slow, or just plain confusing when it comes to adding to or modifying its behavior. This chapter will help you make a well-informed decision about which control to use, and then provides you with some recipes to solve common development problems as you adapt it to your liking.
Chapter 2
This chapter provides recipes that perform a number of data validation tasks, such as ensuring that the data a user enters is within a defined range or conforms to a specific data type. Other validation recipes show how to ensure that the data entered by the user matches a specific pattern or an entry in a database. You'll also learn how to ensure that the user selects an entry in a drop-down list.
Chapter 3
The solutions in this chapter provide a series of non-obvious solutions for working with forms. For example, rather than requiring that the user always click a Submit button in order to send the information on a form to the server, you'll learn how to support the Enter key as well. Another recipe shows how to submit a form to a page that is different than the current page, which is handy when you want to, for example, have one page that collects form data and a second page that processes it. Still another shows how to create what appears from the users' perspective as a multipage form but which is actually a series of panels that simulate "virtual" pages, a useful technique when you want to keep all of your code in one cohesive unit. Finally, you'll learn how to set the focus to a specific control when a page is first loaded, an easy solution for JavaScript but one that is slightly more complicated (and ultimately more useful) when you focus on code reuse.
Chapter 4
User controls are a way of encapsulating other controls and code into reusable packages. This chapter shows some ways to use these extraordinary time- and work-savers to share the same header across multiple pages, display a navigation bar that appears "customized" on each page simply by setting properties, and reuse identical code-behind classes within different pages while changing the user presentation in the process. Still another recipe shows how to communicate between user controls using event delegates, a technique that is handy, for example, when you want an action taken with one control to affect multiple other controls. The final recipe in this chapter shows how to programmatically load a user control at runtime, which allows you to customize web page content based on a user's selection.
Chapter 5
The recipes in this chapter center on custom controls, for which you can build your own user interface and add your own backend functionality through the methods, properties, and events that you implement for the controls. For instance, one recipe shows how to combine two or more controls into a single custom control. Another recipe shows how to create a custom control that has HTML-style attributes, which can be handy for customizing the control when it is used in a page. There's also a recipe for creating a custom control that maintains state between postbacks, like the server controls in ASP.NET. Still another recipe shows how to customize an ASP.NET TextBox server control to allow only numeric input.
Chapter 6
The recipes in this chapter are all about maintaining state at the application, session, and page levels, all for the purpose of improving the user's experience. For instance, one recipe shows you how to maintain information needed by all users of an application by placing it in the Application object. Another shows how to maintain information about a user throughout a session, the advantage here being that you avoid accessing the database each time the data is needed. Another recipe shows how to preserve small amounts of information on a page between postbacks, which is useful when a page has multiple states and it needs to remember the current state value between postbacks to display properly. Still another recipe shows you how to persist complex object information between requests for a page, a useful technique when the page itself is complex and you don't want to use a database to preserve the information.
Chapter 7
This chapter covers error handling at different levels of granularity. For example, one recipe shows how to provide robust error handling in methods by taking best advantage of .NET structured exception handling for dealing with errors. A page-level error-handling recipe shows you how to trap any error that occurs on a page and then, using a page-level event handler, redirect the user to another page that displays information about the problem. Yet another recipe shows how to handle errors at the application level to log the error information and perform a redirect to a common error page. The final recipe shows how to log detailed messages for debugging but display friendly messages to the user.
Chapter 8
Security can be handled in many different ways and at many different levels in ASP.NET, and this chapter provides recipes that delve into some of the most common solutions. For instance, the first two recipes show you how to use Forms authentication to restrict access to all or only some pages of an application. Another recipe shows you how to restrict access to pages by the user's role. There is also a recipe that shows you how to use Windows authentication, which is useful when all users have accounts on your LAN.
Chapter 9
The recipes in this chapter deal with how to configure your applications. For instance, one recipe shows you how to change the default HTTP runtime settings in web.config as a way to familiarize yourself with this file, its contents, and its purpose. Another recipe shows you how to add your own custom application settings to web.config (by adding an
Chapter 10
The recipes in this chapter will help you make sure that your applications work as anticipated in their first release. For example, one recipe shows you how to identify the source of page-level problems, such as a slowly performing page. Another shows you how to use tracing to identify problems application-wide without having to modify every page or disrupt output. Still another shows you how to dynamically turn on page tracing to pinpoint the cause of an exception error. Identifying problems within web application components is addressed by another recipe. A follow-on recipe shows you how to identify problems within dual use (non-web-specific) components, which requires a slightly different approach to avoid breaking the component when it is used outside ASP.NET applications. The final few recipes deal with writing trace data to the event log, using a breakpoint to peer into an application when a condition is met, and stress testing a web application.
Chapter 11
XML web services are the marquee feature of .NET, and the recipes in this chapter will help you create and consume them. You will also find a recipe for creating a web service that returns a custom object, a handy approach when none of the .NET data types meets your needs. Still another recipe shows you how to control the URL of a web service at runtime.
Chapter 12
When working with a creative design team, you may run into the situation where a design uses images for buttons but the button labels need to be dynamic. A recipe in this chapter will show you how to deal with this situation with aplomb by drawing button images on the fly. Another recipe shows you how to create bar charts on the fly from dynamic data. Displaying images stored in a database is the focus of another recipe; it shows you how to read an image from the database, and then stream it to the browser. The final recipe in the chapter shows you how to display a page of images in thumbnail format.
Chapter 13
ASP.NET provides the ability to cache the output of pages or portions of pages in memory, to reduce latency and make your applications more responsive. If pages are completely static, it's a simple decision to cache them. But if the pages change as a function of query string values or are dynamically created from a database, the decision to cache is not so straightforward. The recipes in this chapter will help you sort through these issues. An additional recipe delves into caching pages based on the browser type and version. A follow-on recipe discusses how to cache pages based on your own custom strings, which gives you, for example, the ability to cache a page based on the browser type, the major version (integer portion of the version number), and the minor version (the decimal portion of the version number). The last two recipes show you how to cache user controls and application data.
Chapter 14
The recipes in this chapter show you the basics of how to internationalize your applications. For instance, the first recipe shows you the necessary web.config settings to inform the browser of the character set to use when rendering the application's pages. Another recipe shows you how to support multiple languages in an application without having to develop multiple versions of pages. The final recipe shows you how to override currency formatting, which can be handy, for example, when you want all the text displayed in the user's language but currency values displayed in a specific format, such as U.S. dollars.
Chapter 15
The recipes in this chapter focus on how to download files from and upload files to the web server. There's also a recipe that shows you how to immediately process an uploaded file without storing it on the filesystem, which is handy when you want to avoid the potential pitfalls of uploaded files having the same name or filling the hard drive, or when dealing with the security aspects of allowing ASP.NET write privileges on the local filesystem. The final recipe in the chapter shows you how to store the contents of an uploaded file in a database, which is a useful approach when you want to upload a file to the web server but process it later.
Chapter 16
You will find that performance is a running theme throughout the course of this book. Nevertheless, there are a handful of topics in ASP.NET for which performance bears explicit mention. For instance, as discussed in one recipe, you can often reduce a page's size (and improve a page's performance) by disabling the ViewState for the page or for a set of controls on the page. Another recipe deals with the oft-mentioned topic of using a StringBuilder object instead of the classic string concatenation operators ("&" or "+") to speed up string concatenation. The difference in this recipe is that we give you some tangible measures that will help you understand just how important this approach is and when you can do without it. Another recipe illustrates how to get the best performance out of your application when you are using read-only data access. Still another recipe shows you how to use SQL Server Managed Provider to get the best performance when accessing SQL Server data. Here, again, we give you some tangible measures, and the results are eye-opening.
Chapter 17
An HTTP handler is a class that handles requests for a given resource or resource type. For instance, ASP.NET has built-in HTTP handlers that process requests for .aspx, .asmx, .ascx, .cs, .vb, and other file types. This chapter provides recipes for creating your own custom HTTP handler, which is a useful approach any time you want to handle an HTTP request for a resource on your own. For example, there's a recipe that retrieves image data from a database and sends the image data to a browser. A second recipe shows how to create a file download handler.
Chapter 18
This chapter contains a handful of assorted recipes that do not fit conveniently into other chapters of the book. There are, for instance, recipes for accessing HTTP-specific information in classes, executing external applications, transforming XML to HTML, determining the user's browser type, dynamically creating browser-specific stylesheets, capturing rendered HTML output, sending mail, and using page templates.