There is also a set of new ASP+ controls that can be defined within the page, and which are prefixed with the namespace ‘asp’. These controls expose properties that correspond to the standard attributes that are available for the equivalent HTML element. As with all server controls, you can set these properties during the server-side Load events of the page, or add them as attributes in the usual way, but using the special property names. When rendered to the client, the properties are converted into the equivalent HTML syntax.
For example, to create an instance of a ListBox control, we can use:
<asp:ListBox visibleItems="3" runat="server"> <asp:ListItem>Windows 98</asp:ListItem> <asp:ListItem>Windows NT4</asp:ListItem> <asp:ListItem>Windows 2000</asp:ListItem> </asp:ListBox>
At runtime (in the preview version) the ASP+ code above creates the following HTML, and sends it to the client:
<SELECT name="ListBox0" size="3"> <OPTION value="Windows 98">Windows 98</OPTION> <OPTION value="Windows NT4">Windows NT4</OPTION> <OPTION value="Windows 2000">Windows 2000</OPTION> </SELECT>
A summary of the ‘asp’-prefixed intrinsic controls looks like this:
These controls provide more standardized property sets than the HTML controls, and make it easier to implement tools that can be used for designing and building ASP+ pages and applications.
The ASP+ List Controls
Many day-to-day tasks involve the listing of data in a Web page. In general, this data will be drawn from a data store of some type, perhaps a relational database. The aim of the ASP+ List Controls is to make building these kinds of pages easier. This involves encapsulating the functionality required within a single control or set of controls, saving development time and making the task easier.
The server-side ASP+ controls that generate the user interface can also manage tasks such as paging the list, sorting the contents, filtering the list, and selecting individual items. Finally, they can use the new server-side data binding features in ASP+ to automatically populate the lists with data. The three standard controls that are used to create lists are the Repeater, DataList, and DataGrid controls.
The Repeater control is the simplest, and is used simply to render the output a repeated number of times. The developer defines templates that are used to apply styling information to the header, item, footer and separator parts of the output that is created by the control. To create a table, for example, the header and footer information is used (as you would expect) for the header and footer of the table (the <thead> and <tfoot> parts in HTML terms). The item template content is applied to every row of the table that is generated from the repeated values – probably the records from a data store of some type. There is also the facility to use an alternatingItem template to apply different styles to alternate rows. The separator information defines the HTML output that will be generated after each row and before the next one.
The DataList control differs from the Repeater control in that it provides some intrinsic formatting of the repeated data as well as accepting the same kinds of template values as the Repeater control. The DataList control renders additional HTML (outside of that defined in its templates) to better control the layout and format of the rendered list, providing features such as vertical/horizontal flow and style support. However, unlike the Repeater control, it can also be used to edit the values in the elements on demand, and detect changes made by the user.
The richest of the list controls is the DataGrid control. The output is an HTML table, and the developer can define templates that are used to apply styling information to the various parts of the table. As well as being able to edit the values in the table, the user can also sort and filter the contents, and the appearance is similar to that of using a spreadsheet. However, as the output from the control is simply HTML, it will work in all the popular browsers.
There are two other more specialized types of list control included with ASP+. These are the RadioButtonList and CheckboxList controls. In effect, they simply render on the client a list of HTML radio button or checkbox elements, with captions applied using span elements. However, you can easily specify the layout, i.e. if the items should appear listed horizontally across the page or vertically down it, or within an HTML table. You can also control the alignment of the text labels, and arrange for the list to automatically post back the selected values.
The ASP+ Rich Controls
The preview version of ASP+ ships with three Rich Controls that provide specific functions not usually available in plain HTML. Examples of these are the Calendar and AdRotator controls. Also due in later releases are TreeView, ImageGenerator, and other controls.
To give you some idea of what these custom controls can do, take a look at the screenshot below:
This was generated using this simple code:
<form runat="server"> <asp:Calendar runat="server" /> </form>
The ASP+ Validation Controls
One common task when working with HTML forms in a Web application is the validation of values that the user enters. They may have to fall within a prescribed range, be non-empty, or even have the values from several controls cross-referenced to check that the inputs are valid.
Traditionally, this has been done using either client-side or server-side scripts, often specially written for each form page. In ASP+, a range of Validation Controls is included. These make it easy to perform validation checks – both client-side and server-side.
Three types of validation control are provided. The RequiredFieldValidator control, CompareValidator control, RangeValidator control, and RegularExpressionValidator control perform various types of checks to ensure that that a control contains a specific value, or matches the value in another control. The CustomValidator control passes the value that a user enters into a control to a specified client-side or server-side function for custom validation. The ValidationSummary control collects all the validation errors and places them in a list within the page.
Each one of these controls (except the ValidationSummary control) is linked to one or more HTML controls through the attributes you set for the validation control. They can automatically output the text or character string you specify when the validation fails. You can also use the IsValid method of the Page object to see if any of the validation controls detected an error, and provide custom error messages.
Some of the controls also detect the browser type, and can output code that performs validation client-side without requiring a round-trip to the server. If this is not possible, code to do the validation during the submission of the values to the server is output instead. We look in detail at how we can use these controls in Chapter 4.
You’ll see most of the controls we’ve discussed described in more detail in Chapter 2. The more complex topics associated with them, such as templates, server-side data binding and ADO+ are covered in Chapter 3. Chapter 4 looks at the validation controls, and other advanced techniques in ASP+ pages. We also look at how you can build your own custom server-side controls in Chapter 7.
ASP+ Web Services
As the march of XML through traditional computing territory continues unabated, more and more of the ways that we are used to doing things are changing. One area is the provision of programmatic services that can be consumed by remote clients, especially where the server and client are running on different operating system platforms. The Simple Object Access Protocol (SOAP) is an XML grammar that allows clients to take advantage of the services provided by a remote server or application, by providing the requests in a standard format.
ASP+ includes support for the creation of suitable server or application objects that accept SOAP requests, and return the results in SOAP format. The technology is called Web Services, and allows developers to create these objects quickly and easily within the .NET framework.
These objects are also automatically discoverable and described to clients using the XML-based Service Description Language (SDL).
You simply create the object using normal server-side code as a public class, in any of the supported languages, and include one or more methods that the client can access marked with the special [ Web Method ] indicator. These are known as custom attributes. Other methods that are not marked as such are private, and cannot be accessed by clients. No knowledge of COM+ or HTTP itself is required, and the source for these service objects is just text files.
Web Services allows custom business service objects to be created quickly and easily by ASP+ developers. The client can access them synchronously or asynchronously, using the HTTP-GET, HTTP-POST or HTTP-SOAP methods that provide extra flexibility. As with other objects in ASP+, the source is compiled, cached and executed under the runtime. We explore the whole concept of Web Services in Chapter 5.
ASP+ Configuration and Deployment
In earlier versions of ASP, a file named global.asa could exist in the root directory of a virtual application. This file defined global variables and event handlers for the application. However, all other configuration details for the entire Web site were made in the Internet Services Manager snap-in to the MMC. The settings made in Internet Services Manager are stored in the IIS metabase, which is a server-based machine-readable file that specifies the whole structure of the Web services for that machine.
This has at least one major disadvantage. It requires the administrator or developer to access the metabase using either Internet Services Manager (it can be used remotely to access another machine on the LAN), the equivalent HTML pages, or custom pages that access the metabase through the Active Directory Services Interface (ADSI).
The Global Configuration File – config.web
In ASP+, all the configuration details for all Web applications are kept in human-readable files named config.web. The default config.web file is in the Program FilesCOM20SDK directory and this specifies the settings that apply to any applications or directories that do not over-ride the defaults. The standard format for the configuration files is XML, and each application inherits the settings in the default config.web file.
The config.web file specifies a whole range of settings for the application, including the HTTP Modules and Request Handlers that are to be used to handle each request. This provides a completely extensible and flexible architecture, allowing non-standard HTTP protocol handling to be carried out if required. We examine configuration files and their use in Chapter 6.
The Application Definition File – global.asax
As in ASP 2.0 and 3.0, it is also possible to use a definition file that specifies the actions to take when an application starts and ends, and when individual user sessions start and end. This file is named global.asax (note the .asax file extension), and is stored in the root directory for each application.
The existing ASP event handlers Application_OnStart, Application_OnEnd, Session_OnStart, and Session_OnEnd are supported in global.asax, as well as several new events such as Application_BeginRequest, Security_OnAuthenticate, and others. And, as before, the global.asax file can be used to set the values of global or session-level variables and instantiate objects. We look at the use of global.asax files in Chapter 6.
ASP+ Application and Session State
One of the useful features in previous versions of ASP that developers were quick to take advantage of was the provision of global and user-level scope for storing values and object instances. This uses the Application and Session objects in ASP, and these objects are still present in ASP+. Although backwards compatible, however, the new Application and Session objects offer a host of extra features.
Using Application State
As in previous versions, each ASP application running on a machine has a single instance of the Application object, which can be accessed by any pages within that application. Any values or object references remain valid as long as the application is ‘alive’. However, when the global.asax file is edited, or when the last client Session object is destroyed, the Application object is also destroyed.
Using the Application object for storing simple values is useful, and there are the usual Lock and Unlock methods available to prevent users from corrupting values within it through concurrent updates to these values. This can, however, cause blocking to occur while one page waits to access the Application object while it is locked by another page.
Note that when a page finishes executing or times out, or when an un-handled error occurs, the Application object is automatically unlocked for that page.
Bear in mind the impact of storing large volumes of data in an Application object, as this can absorb resources that are required elsewhere. You also need to ensure that any objects you instantiate at Application-level scope are thread safe and can handle multiple concurrent accesses. Another limitation in the use of the Application object is that it is not maintained across a Web farm where multiple servers handle user requests for the same application, or in a ‘Web garden’ where the same application runs in multiple processes within a single, multi-processor machine.
Using Session State
While the Application object is little changed from earlier versions of ASP, the Session object in ASP+ has undergone some quite dramatic updating. It is still compatible with code from earlier versions of ASP, but has several new features that make it even more useful.
The biggest change is that the contents of the Session object can now (optionally) be stored externally from the ASP+ process, in a new object called a Session State Store. It is managed by a new Windows service called the State Server Process, and this persists the content of all users Session objects – even if the ASP+ process they are running under fails. It also removes the content of sessions that have terminated through a time-out or after an error.
Alternatively, the Session content can be serialized out into a temporary SQL Server database table, where ASP+ talks directly to SQL Server. This means that it can be reloaded after an application or machine failure, providing a far more robust implementation of Session object storage than previous versions. It’s therefore ideal for applications that require a session-level state management feature, for example a shopping cart.
This new state storage system also has another direct advantage. When using a Web farm to support a large-scale application or Web site it has always been a problem managing sessions, as they are not available across the machines in the Web farm.
The new ASP+ Session State Store can be partitioned across multiple servers, so that each client’s state can be maintained irrespective of which server in the Web farm they hit first.
At last, ASP+ also allows session state to be maintained for clients that don’t support cookies. This was proposed in earlier versions of ASP, but never materialized. Now, by using a special configuration setting, you can force ASP+ to ‘munge’ the session ID into the URL. This avoids all of the previously encountered problems of losing state information, for example when the URLs in hyperlinks do not use the same character case as the page names.
Finally, the State Server Process will also be able to expose information about the contents of the Session State Store, which will be useful for performance monitoring and administrative tasks such as setting maximum limits for each client’s state. We examine the way that sessions can be managed in Chapter 6.
ASP+ Error Handling, Debugging, and Tracing
Error handling and debugging has long been an area where ASP trailed behind other development environments like Visual Basic and C++. In ASP+, there are several new features that help to alleviate this situation. It’s now possible to specify individual error pages for each ASP+ page, using the new ErrorPage directive at the start of an ASP+ page:
If a ‘Not Found’, ‘Access Forbidden’ response is generated, or an ‘Internal Server Error’ (caused by an ASP code or object error) occurs while loading, parsing, compiling or processing the page, the custom error page you specify is loaded instead. In this page, you can access the error code, the page URL, and the error message. The custom error page, or other error handler, can alternatively be specified in the config.web file for an application.
If no error page is specified then ASP+ will load its own error page, which contains far more detail than before about the error and how to rectify it. Settings in the config.web file also allow you to specify that this information should only be presented to a browser running on the Web server, and in this case remote users will just receive a simple error indication. Alternatively, you can create a procedure in the ASP+ page that captures the HandleError event, and doing so also prevents the default error page from being displayed.
Another welcome new feature is that Visual Basic now supports the try…catch…finally error handling technique that has long been the mainstay in languages like C++, and more recently in JScript. More details of this can be found in Appendix B. ASP+ also improves debugging techniques by including a new Debugger tool. This is the same debugger that is supplied with Visual Studio, allowing local and remote debugging.
Finally, ASP+ now includes comprehensive tracing facilities, so you no longer need to fill your pages with Response.Write statements to figure out what’s going on inside the code. Instead, by turning on tracing at the top of the page with the new Trace directive, you can write information to the Trace object and have it rendered automatically as an HTML table at the end of the page. Tracing can also be enabled for ASP+ applications by adding instructions to the config.web file. The trace information automatically includes statistics that show the response time and other useful internal parameters:
On top of this, a Web-based viewer is provided that allows you to examine the contents of the TraceContext object’s log file. We look at the whole topic of error handling, debugging and tracing in Chapter 4.
Other ASP+ Features
To finish of this brief tour of the new features in ASP+, we’ll look at some other topics that fall under the ‘general’ heading. These include security management, sending e-mail from ASP+ pages, and server-side caching.
New Security Management Features
In Chapters 4 and 6, you’ll see how ASP+ implements several new ways to manage security in your pages and applications. As in ASP 3.0, the Basic, Digest and NTLM (Windows NT) authentication methods can be used. These are implemented in ASP+, using the services provided by IIS in earlier versions of ASP. There is also a new authentication technique called Passport Authentication, which uses the new Managed Passport Profile API. It’s also possible to assign users to roles, and then check that each user has the relevant permission to access resources using the IsCallerinRole method.
An alternative method is to use custom form-based authentication. This technique uses tokens stored in cookies to track users, and allows custom login pages to be used instead of the client seeing the standard Windows Login dialog. This provides a similar user experience to that on amazon.com and yahoo.com. Without this feature, you need to write an ISAPI Filter to do this – with ASP+ it becomes trivially simple.
ASP+ uses server-side caching to improve performance in a range of ways. As well as caching the intermediate code for ASP pages and various other objects, ASP has an output cache that allows the entire content of a page to be cached and then reused for other clients (if it is suitable).
There is also access to a custom server-side cache, which can be used to hold objects, values, or other content that is required within the application. Your pages and applications can use this cache to improve performance by storing items that are regularly used or which will be required again. The cache is implemented in memory only (it is not durable in the case of a machine failure), and scavenging and management is performed automatically by the operating system.