Maximize Productivity With ASP.NET
Web development is about to take another great leap forward. Powerful features in the new version of ASP.NET will save you time and reduce your code-writing requirements.
Technology Toolbox: C#, SQL Server 2000, ASP.NET, XML
Microsoft's release of the .NET Framework and ASP.NET in 2002 sparked a revolution in Web development, making it possible to create event-driven, compiled, and object-oriented Web applications rapidly. If you use ASP.NET, you no doubt appreciate its power and are eager to know what the future holds for the platform.
ASP.NET 2 maximizes your productivity by simplifying tasks you perform frequently. Adding user personalization, logging users in and out, paging/sorting data, and creating templated Web sites are much simpler and require minimal coding, compared to ASP.NET 1.1. C# and VB.NET also have new capabilities, such as generics and partial classes, that help your Web applications be more flexible and maintainable. p>
The learning curve associated with moving from version 1.0 to version 2.0 of ASP.NET is by no means as steep as the curve you might have encountered when migrating from ASP to ASP.NET, but version 2 is packed with new features (see the sidebar, "Harness ASP.NET Version 2's Power"). I'll use a fictitious Web site called GolfClubShack to introduce you to several of them and show you code that puts these features to use (see Figure 1 and download the sample code). Keep in mind that the code samples are based on the alpha bits and might need changes between now and version 2's final release, scheduled for 2004.
Let's begin by showing how to fit an entire Web site almost effortlessly with a consistent look and feel. When you use ASP.NET 1.1, you give a site its look and feel by placing user controls on each page, or by creating custom template solutions. Version 2 lets you design a single page, called a master page, where you define consistent elementssuch as headers, footers, and menusin one place. Master pages have a file extension of MASTER and contain a "master" directive at the top of the page:
<%@ master language="C#" %>
You specify where to place a page's actual content in the master page by adding a new server control named ContentPlaceholder (see Listing 1).
You can associate the master page with ASP.NET Web forms and inherit everything defined in it automatically. You reference the master page by adding the masterPage attribute to the Page directive of an ASP.NET Web form (referred to as the content page):
You must place content (HTML, server controls, and so on) within a content page in another server control, named Content. Place additional controls within the Content control's start and end tags to add them dynamically to the master template's content placeholder region:
Page content goes here
The preceding code causes the Label to be inserted in the appropriate spot in the master template when the page executes.
Manage Data With Minimal Code
Data source controls are another improvement in version 2. You typically spend a great deal of time writing code to hook ASP.NET 1.1 applications up to databases to modify and retrieve data. This is especially true if the database calls involve passing parameters into stored procedures. Microsoft's release of Data Access Application Blocks has reduced the amount of code you must write, but a fair amount is still necessary.
Data source controls reduce significantly the amount of code you need to hook up to databases and retrieve data. Several types of data source controls are available, including SqlDataSource, AccessDataSource, XmlDataSource, and my personal favorite, ObjectDataSource. You use the controls by simply dragging them onto the VS.NET design surface or typing their syntax into the HTML editor. You configure them by using the supplied VS.NET Whidbey wizards to create the connection string; generate insert, update, select, or delete queries; and even create query parameters.
You can use the SqlDataSource control wizard to construct a query and assign parameter values dynamically (see Figure 2). Parameter data can come from several sources, including cookies, control values, posted form values, the QueryString, and sessions. You can associate the control with data-display controls, such as a DataGrid or the new GridView control (which I'll discuss later), by referencing the data source control's ID (see Listing 2).
You might wonder how the SqlDataSource control fits into an n-tier architecture. After all, you hook up ASP.NET pages directly to the database by using SqlDataSource or AccessDataSource controls and bypass business or data-access layers. The ASP.NET team took this into account by creating the ObjectDataSource control, which allows you to call business or data-object methods dynamically without writing any C# or VB.NET code. Designer support for this control wasn't available in the alpha bits I used, but I got it working easily by using the HTML code editor. For example, you can use the ObjectDataSource control to call the ProductsDB class's GetProducts() method (see Listings 3 and 4). Notice that the parameter value passed to the method is extracted from the QueryString parameter collection automatically.
Although I don't have the space to discuss it further in this article, the sample code also demonstrates how to use the new XmlDataSource control to bind XML data to a DataList control (see Default.aspx). You can now use XPath statements when binding XML to controls:
<a href='<%# XPath("document_url") %>'
<%# XPath("headline_text") %>
Along with data source controls, ASP.NET 2 also includes built-in support for invalidating ASP.NET caches when a database table is modified. A few minutes of setup work is necessary to enable database table cache dependencies and cache invalidation.
You must run an executable named aspnet_regsqlcache.exe at the command line to enable SQL Server cache dependencies. This utility is in the [Windows Install]>\Microsoft.NET\Framework\[Alpha Version] folder. You run the utility to enable cache dependencies in specific SQL Server database tables. These command-line calls enable the database for caching and add a trigger to the table that the cache dependency will be based on:
aspnet_regsqlcache -S localhost -U sa
-P password -d GolfClubShack -ed
aspnet_regsqlcache -S localhost -U sa
-P password -d GolfClubShack
-t GolfClubShack_Categories -et
Once the database and desired tables are "cache-enabled," you can add this code at the top of an ASP.NET page or user control to cache it:
<%@ outputcache duration="60"
Notice the addition of the new sqldependency attribute, which you use to define the database and table the cache should be based on. The cache is invalidated automatically any time the GolfClubShack database's GolfClubShack_Categories table changes. Otherwise, the page grabs a fresh copy of the data every 60 seconds.
Manage Membership and Security
New membership-management controls in version 2 make it easy to add security checks to ASP.NET applications. Logging users in and out, changing passwords, resetting passwords, and updating user account information isn't much fun with ASP.NET 1.1. These tasks generally require writing fairly redundant user membership code, passing parameters to stored procedures, and letting the user know the operation's status.
You can perform these tasks with ASP.NET 2 by dragging and dropping server controls onto the design surface in VS.NET and setting a few properties. The controls available in the alpha version include Login, LoginView, PasswordRecovery, LoginStatus, and LoginName. CreateUser and ChangePassword controls are due for release in the beta version. Each control has properties you can set to control the look and feel of the HTML that the ASP.NET controls generate.
You must do some minor setup work to use these server controls. A folder named Data is created for you when you start up VS.NET Whidbey and create a new Web site. A Microsoft Access database named ASPNetDB.mdb is placed in this folder automatically when you use a control. The database contains several tables that can handle personalization and user-membership management.
The Access database helps you get things working, but you should upsize to a database such as SQL Server to avoid potential database connectivity issues. You do this by running several supplied SQL scripts you'll find in the [Windows Install]>\Microsoft.NET\Framework\[Alpha Version] folder. The files to execute are named InstallCommon.sql, InstallMembership.sql, and InstallPersonalization.sql. The scripts create a new database, named aspnetdb, that contains several tables and stored procedures for storing membership and personalization data.
You can use the membership controls once the database is set up. Each control is straightforward to use. For example, this code uses the Login server control to authenticate a user (and remember the user on return visits if desired):
<asp:login id="ctlLogin" runat="server"
When the user enters a username and password and then clicks on the Submit button, an Authenticate event is raised that you can use to validate the user (see Listing 5). You must configure a membership "provider" properly in the web.config file in order to use the Membership class (see Listing 6).
You can read more about the Membership class (located in the System.Web.Security namespace) in the version 2 SDK. You'll see that you can implement an interface named IMembershipProvider to create custom membership provider classes to tie into other user-credential stores. Interfaces present versioning problems, so the beta version will allow you to derive from a base class instead, enabling you to implement versioning properly by using the Global Assembly Cache. The Configure Personalization
ASP.NET 1.1 contains the building blocks to personalize Web sites for end users, but simple tasks such as storing and accessing user preferences in some type of data store (aside from cookies) require several lines of code. Version 2 simplifies personalization by using web.config configuration sections and a supplied database that stores user preferences.
ASP.NET detects the personalization configuration sections automatically and uses them to generate a Profile class. This means you can get IntelliSense for new user preferences immediately after you add them to the web.config file, rather than needing to use a string or index position to refer to them. For example, suppose you'd like to capture the user's name, Web site color preference, golf club manufacturer preference, and whether he or she would like to receive a GolfClubShack newsletter. First, you must run the database scripts I mentioned previously (or use the default Microsoft Access database). Once the database is in place, you must add the necessary personalization configuration into the web.config file (see Listing 7).
This configuration code defines the default personalization provider and the user preferences to capture. The <profile> tag defines these preferences as properties. Once you configure and save the user profile, you can access the properties through a new framework object named Profile. This object compiles dynamically each time the web.config file's profile section changes, which means you get IntelliSense for the properties (see Figure 3).
Saving and selecting user preferences is as simple as calling the appropriate properties on the Profile object. You'll find code demonstrating how to use the Profile object in the sample code.
Leverage Improved Server Controls
Server controlsone of the more important technologies in ASP.NET 1.1are equally important in version 2. Controls available in version 1.1 have been updated to support mobile control functionality along with the Web functionality you're accustomed to. You can now use the same control base to build both Web and mobile applications, which reduces the number of classes you must learn.
Specific controls, such as the ImageButton control, also have been modified to support new functionality. The ImageButton control has a new propertyPostTargetUrlthat allows you to direct form posts to other pages (cross-posting):
The page receiving the post can then access controls in the previous page (the page that posted the form initially) through a new object named PreviousPage:
string searchText =
If you run a trace on the page receiving the post data, you see a new hidden ViewState field named __PreviousPage. See the SearchResults.aspx page in the sample code for more details.
ASP.NET 2 also adds several new server controls that provide a variety of features. I've shown you a few of them, such as the Login control, already. Others include the TreeView, HiddenField, Wizard, ImageMap, BulletedList, FileUpload, and GridView. A slew of personalization controls, such as WebPartManager, WebPartZone, and EditorZone, are also available. These controls expose the same object model found in other server controls you've worked with in the past.
You'll find an example of the TreeView control in action in the GolfClubShack sample code (see SiteMap.aspx). It binds to a SiteMapDataSource control to create a site map for the GolfClubShack Web site automatically. The new GridView control is a type of enhanced DataGrid that allows you to build in paging, sorting, editing, and selecting functionality without writing a single line of code. You can configure controls such as GridView solely by using the VS.NET editor. The GUI-averse can write the code directly in the HTML code editor.
It would take a book (and I'm sure hundreds of them will be written) to cover all the new ASP.NET version 2 features and explain how to use them. This article has given you a look at a few of the platform's more powerful features and some code that makes them work. You can be sure the official production release of ASP.NET 2 will save you development time and reduce the amount of code you need to write.