An Exciting Time
June 28, 2001
It's 10:15 A.M. on Saturday, June 16th, and I'm somewhere between Seattle and Chicago on my way to Tech-Ed Atlanta. I'm riveted by the events that will unfold: the public release of Beta 2 and the celebration of the 10th anniversary of Visual Basic®.
Before the week is out, thousands of people will have Beta 2. The momentum is breathtaking with nearly 200 books planned and/or underway, and there are conferences or user events planned for every month!
In the last several months, the industry has awakened to the promise of Web Services. Did I mention that XML Web Services represents the underpinning of Microsoft's .NET strategy, and is a core feature of ASP.NET?
It's an exciting time.
From Beta 1 to Beta 2
Beta 1 of .NET was focused on demonstrating that the technologies were real. Beta 2 is the call to action. Between Beta 1 and Beta 2 we made changes to the product as well as many bug fixes.
Beta 2 is the platform that customers will begin to use for their production applications. Web Sites such as http://uddi.microsoft.com and http://music.msn.com are already running the Beta 2 of ASP.NET—and that's just the beginning. If you're interested in using ASP.NET Beta 2 for your application, see our ASP.NET Go Live License.
In this month's column, we'll focus on the major changes in ASP.NET between Beta 1 and Beta 2. This is important information, both in terms of updating your code, or if you simply want to start using ASP.NET.
There are many changes you will no doubt run into when moving code from Beta 1 to Beta 2. We obviously can't cover each one, but it does make sense to cover the changes that will affect us the most:
- Server Controls
- Data Access
- Web Services
- Output Caching
The configuration file, config.web, is renamed to web.config. Furthermore, the server or root configuration file (also named config.web in Beta 1) is changed to machine.config. This file, machine.config, is found in: [WinNT]\Microsoft.NET\Framework\v1.0.2914\CONFIG
Application configuration files (web.config) are still located in their respective Web Application directories.
In addition to renaming the configuration file, we also made several formatting changes. This is most evident by opening machine.config and examining the new syntax. Below is a list of the most applicable changes:
- Case Sensitive—camelCasing is used on all element or attribute names; for example, sessionState.
- <system.web>—The concept of configuration groups is introduced as a way to group common configuration settings together. ASP.NET configuration settings all use <system.web>.
- Lock-down—Sections of configuration can now be "locked down" to prevent sub-applications from changing settings. This is done though the <location path="[Web Site name]" \"[Application name]" allowOverride="false"> element, which wraps the settings to be locked.
In addition to these macro changes, there are several new configuration sections added for ASP.NET, as well as some new or changed attributes for these settings.
Although not nearly as dramatic a change as configuration, we also made a few modifications to server controls.
Thanks to customer feedback—in large part due to Charles Carroll's ASPNG discussion lists—we've changed the behavior of several server control properties:
- CausesValidation property—A new property that can be set on buttons to cancel the validation behavior.
- DataMember property—An optional property on data-bound lists to indicate which table within a DataSet to bind to.
- ReadOnly property—TextBox controls now support a ReadOnly property that affects whether or not a client can change the value on the rendered HTML TextBox.
Although not previously discussed in this column, you may also be familiar with server-control template support. Templates give us the ability to redefine the look and feel when the server control is rendered. Template syntax has changed for Beta 2.
Changes to templates
Several server controls allow us to use templates to control the look and feel of the rendered mark-up. For example, we could use templates to control the HTML rendered by a DataList server control.
The syntax for using a template in Beta 1 was:
<asp:datalist id="MyList" repeatcolumns="2" borderwidth="0" runat="server"> <template name="itemtemplate"> <table> <tr> <td> <!-- add data binding syntax here --> </td> </tr> </table> </template> </asp:datalist>
The new syntax for using templates is:
<asp:datalist id="MyList" repeatcolumns="2" borderwidth="0" runat="server"> <itemtemplate> <table> <tr> <td> <!-- add data binding syntax here --> </td> </tr> </table> </itemtemplate> </asp:datalist>
The above changes to server controls are slight, and the changes to templates should be relatively easy to fix as you move code forward.
Accessing data is probably one of the more common tasks accomplished in an application. Data access has changed quite a bit between Beta 1 and Beta 2.
Data Access in Beta 2 has changed considerably from Beta 1 to Beta 2. Not only have the required namespaces changed, but we've also changed many of the class names and some of the behaviors.
Here are the new namespaces containing classes used for accessing data in Beta 2:
- System.Data—Contains common classes used for manipulating data.
- System.Data.SqlClient—Contains common classes used for connecting and manipulating SQL Server specific data.
Note It is recommended that you use the SQL-specific classes whenever using SQL Server as your database, as these are native drivers and are very fast.
The two namespaces above contain the classes that we'll use when we need to connect to a data resource. The two most common classes we'll use are the DataReader and the DataSet classes. Let's look at each of these.
A DataReader is a forward, read-only cursor into a database. Similar to an ADO RecordSet, it must be opened, read, and closed. Note, this is unlike a DataSet (discussed momentarily), which is a disconnected snapshot of the data.
Note DataReaders can now be used as return values from procedures, and additionally can now also be bound to server controls.
Below is an example of using a DataReader:
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> Public Sub Page_Load(sender as Object, e as EventArgs) Dim Conn as New SqlConnection(connectionString) Dim Cmd as New SqlCommand("select * from products", Conn) Conn.Open() Grid1.DataSource = Cmd.ExecuteReader(CommandBehavior.CloseConnection) Grid1.DataBind() End Sub <asp:DataGrid id="Grid1" runat="server"/>
Above we used the DataReader implicitly (returned from the call to Cmd.ExecuteReader) to bind to Grid1. Note the use of CommandBehavior.CloseConnection. This option closes the connection automatically, rather than us writing Conn.Close().
Next, let's look at an example that uses the DataSet:
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.Data.SqlClient" %> Public Sub Page_Load(sender as Object, e as EventArgs) Dim Conn as New SqlConnection(connectionString) Dim Cmd as New SqlDataAdapter("select * from products", Conn) Dim ds As DataSet Cmd.Fill(ds, "products") Grid1.DataSource = ds Grid1.DataBind() End Sub <asp:DataGrid id="Grid1" runat="server"/>
The above sample demonstrates the use of a DataSet. If you're familiar with data binding from Beta 1, you'll also notice that when we bind the DataSet instance (ds) to the server control, we no longer need to name the table in the DataSet to which we bind it.
DataReader or DataSet?
When data cannot be cached, it is suggested that you use the DataReader. A DataSet should be used when the data can be cached and re-used—under the covers, DataSet uses a DataReader to populate itself.
XML Web Services is one of the keystones for Microsoft's .NET strategy. ASP.NET has incredible support for building XML Web Services, as was evident in Beta 1. With Beta 2, we've made some updates for the support of standards-based technologies.
ASP.NET Web Services have changed somewhat dramatically since Beta 1—mainly updating technologies supported to be standards compliant. Included in these changes are support for XML Schema Definition (XSD) 2001 and Web Service Description Language (WSDL)—Service Description Language (SDL) is no longer supported.
Note The bad news for migration from Beta 1 Web Services to Beta 2 Web Services is that the proxy class that the client uses needs to be recompiled.
In addition to the support of XSD 2001 and WSDL, we've also made some other changes and additions to Web Services:
- Command line tool WebServiceUtil.exe is split into WSDL.exe and DISCO.exe—WSDL.exe is the primary tool used to create proxy classes from WSDL documents.
- CachDuration property of the WebMethod attribute—Supports output caching of Web Services.
- BufferedResponse property of the WebMethod attribute—By default set to true, the response sent back to the client can optionally be unbuffered.
- Support for Client Certificates—A client certificate can now be presented and accepted by the Web Service; useful for identifying and authenticating the requestor.
There are several other changes to ASP.NET Web Services that we'll call out in a later Advanced ASP.NET Web Services column, continuing the discussion that Keith started on SOAP Extensions.
Above, we mentioned the CacheDuration feature now supported by Web Services. This allows for the SOAP response, eventually to be sent to the caller, to be cached and reused on the server, thus improving the performance of the Web Service. This OutputCaching feature was available in Beta 1 only for ASP.NET pages. For Beta 2 we've expanded OutputCaching for ASP.NET pages, as well as supported a new concept: Partial Page Caching.
The Output Caching feature found in Beta 1 stored the response for a request in the ASP.NET Cache. On subsequent requests, rather than re-executing the page, the content could be served directly from the Cache, improving performance from 2-3X, depending upon what the page did. For example, a page that hit a database on each request could improve performance significantly.
Using Output Caching is simple, and both high-level and low-level APIs are supported. If you worked with Beta 1, you're most likely more familiar with the high-level API (added to the top of a page):
<%@ OutputCache Duration="60" %>
This directive would cache the results for 60 seconds. For Beta 2 we are now required to also define a second parameter, VaryByParam. For similar functionality to the statement above, we would now code:
<%@ OutputCache Duration="60" VaryByParam="none" %>
The VaryByParam attribute allows us to cache different variations of the page based on HTTP GET (querystring) or POST data sent to the server. For example, if our page displayed different output for default.aspx, default.aspx?state=wa, and default.aspx?state=tx, we would code:
<%@ OutputCache Duration="60" VaryByParam="state" %>
This specifies that we want to vary the Cache entries for this page based on the state parameter presented by the requestor.
In addition to the VaryByParam option, we have several other new Beta 2 properties:
- VaryByHeader—Varies the Cache entries based on the headers presented by the client.
- VaryByCustom—The default setting is browser, which varies the Cache entries based on the browser type (Netscape, for example), and major version (version 4, for example). VaryByCustom is also an extensibility feature—allowing us to vary by any custom string we create—this we'll cover in more detail in a later column.
The concept of Output Caching a page is definitely a great way to save work and thus increase performance. However, caching the entire page isn't always feasible. What of the situations where we use personalization, serve ads, or have some other type of content that can't be cached? With Beta 2, we also introduce Partial Page Caching.
Partial Page Caching
Partial Page Caching allows us to define regions of the page that are to be cached. For example, if we build Amazon.com, we might want regions of the page to run code for personalization, while the HTML table (retrieved from a database) listing the top 100 books could be cached. Therefore, a single page will get executed once, and portions of that page are added to and served from the Cache.
Let's quickly look at how this is coded. We use User Controls to define the regions of the page that are to be cached. Note how a user control is referenced at the top, and that no OutputCache directive is present:
<%@ Register TagPrefix="Fragment" TagName="Simple" Src="fragment_vb.ascx" %> <Font size=6>Fragment Cache Simple example <P> <HR size=1> <Fragment:simple id="UserCon1" runat=server /> <hr size=1> This page was created at <Font color=red><B><%=Now()%></B> </Font>
Here is the source for fragment_vb.ascx, which will be executed on the first request, but served from the Cache on subsequent requests:
<%@ OutputCache VaryByParam="none" Duration="10" %> Fragment Cache created: <Font color=red><B><%=Now()%></B>
The result is that the code in the page and the User Control are run on the first request, and the result of the User Control is cached. On subsequent requests, the page is executed, and the cached result of the User Control is added to the page's output.
ASP.NET Beta 2 (available at http://www.ASP.NET) is a rock-solid platform ready for building Web Applications. Although there were some major changes between Beta 1 and Beta 2, we think these are changes that, in the long run, will make the product better. Our goal for the final release is to minimize the changes and focus on bug fixes and performance improvement.
At Microsoft, we've been investing a lot of time and effort with customers, publishers, and the growing .NET developer communities. For ASP.NET, this translates to roughly 15 books coming out in the Beta 2 timeframe, and a number of customers going live in the next several months. But far and away the most important group (and growing daily) is the ASP.NET community (thanks to community leaders like Charles Carroll and all the other ASP.NET ACEs and Authors!)—check out the ASP.NET discussion lists at http://www.ASP.NET and http://www.aspng.com for more details.
Download and install ASP.NET Beta 2—it's ready!