MCAD/MCSD: Implementing Navigation for the User Interface
Date: Mar 14, 2003
Objectives
This chapter covers the following Microsoft-specified objectives for the "Creating User Services" section of Exam 70-315, "Developing and Implementing Web Applications with Microsoft Visual C# .NET and Microsoft Visual Studio .NET":
Implement navigation for the user interface.
-
Manage the view state.
-
Manage data during postback events.
-
Use session state to manage data across pages.
The underlying protocol for communication between the Web browser and Web server is Hypertext Transfer Protocol (HTTP). Because of the stateless nature of the HTTP, Web applications are stateless. Traditionally, this has been one of the major challenges for developing rich and interactive Web applications.
ASP.NET provides several features that help you easily maintain the state of a page across a page postback or between page navigations. This exam objective requires you to know the various ways in which you can manage state using ASP.NET. In addition to this, you should also know the various ways in which you can navigate from one page to another in a Web application.
Use and edit intrinsic objects. Intrinsic objects include response, request, session, server, and application.
-
Retrieve values from the properties of intrinsic objects.
-
Set values on the properties of intrinsic objects.
-
Use intrinsic objects to perform operations.
ASP.NET provides several classes such as HttpResponse, HttpRequest, HttpSessionState, HttpServerUtility, and HttpApplicationState that give you methods and properties for accessing the underlying Web application's framework. You can easily access the objects of these classes for the current HTTP request using the properties of the Page class such as Response, Request, Session, Server, and Application. This exam objective requires you to know about various important properties and methods of these objects.
Outline
- Introduction
- Roundtrip and Postback
- The IsPostBack Property
- The SmartNavigation Property
- ASP.NET Intrinsic Objects
- The HttpRequest Object
- The HttpResponse Object
- The HttpServerUtility Object
- ASP.NET Application
- The global.asax File
- Global Event Handlers
- Application and Session Level Events
- Per-Request Events
- State Management
- Client-Side Techniques for State Management
- Query Strings
- Cookies
- Hidden Fields
- View State
- View State for Page-Level Values
- Choosing a Client-Side State Management Technique
- Server-Side Techniques for State Management
- Session State
- Application State
- Client-Side Techniques for State Management
- Navigation Between Pages
- The Response.Redirect() Method
- The Server.Transfer() Method
- The Server.Execute() Method
- Chapter Summary
- Apply Your Knowledge
Study Strategies
-
Experiment with different techniques for state management. You should understand their differences, advantages, and disadvantages so that you know which technique to use in a given scenario.
-
Use new features of ASP.NET such as view state and smart navigation that enhance the user experience for a Web page.
-
Use Response.Redirect(), Server.Transfer(), and Server.Execute() methods in your programs and understand their differences. Be prepared to choose an appropriate navigation method for a given scenario.
-
Know how to access and use various intrinsic objects from your Web form. Use various properties and methods of these objects to understand how they can help you in various Web development tasks.
Introduction
Development of Web applications is a different game compared to developing Windows applications. One of the major challenges that a Web developer faces while developing a Web application is the disconnected nature of Web application. Traditionally, programmers had to write a lot of additional code to maintain state between page postback and navigation. ASP.NET provides a better model of programming by incorporating the tasks related to state management as part of the programming framework itself so that developers spend less time in plumbing work and more on developing the actual business logic.
In this chapter, I'll present various state management features provided by ASP.NET. I'll discuss both client-side techniques as well as server-side techniques for state management.
I'll also discuss the ASP.NET intrinsic objects that are available to you via the Page class. You'll see how these objects can help you fulfill various common Web development requirements.
Finally, I'll use the intrinsic objects to demonstrate various methods you can use to navigate from one page to another. I'll also compare various navigation techniques so that you can choose the appropriate technique for a given scenario.
Roundtrip and Postback
Implement navigation for the user interface: Manage data during postback events.
Web applications have a distributed execution model. When a user interacts with a Web form, the browser might respond to some of the user actions by executing client-side scripts while some other actions that require server resources must be sent to the Web server for processing. When server-side processing is involved, a typical interactive user session with a Web form consists of the following steps:
User requests a Web form from the Web server.
Web Server responds back with the requested Web form.
User enters the data and submits the form to the Web server.
Web Server processes the form and sends the result back to the user.
Step 3 is also referred to as a page postback, whereas steps 3 and 4 are collectively referred to as a roundtrip. A roundtrip involves making a complete trip over the network to the Web server and getting the response back.
The Web applications use HTTP to establish communication between the Web browser and the Web server. HTTP is disconnected in nature, which means that the life cycle of a Web page is just a single roundtrip. Every time a Web server responds to a page request, it freshly creates the resources required to create the page, sends the page to the requesting client and destroys the page resources from the server. Between two page requests, Web server and the clients are disconnected with each other, and values of page variables and controls are not preserved across the page requests.
This model of execution allows a Web server to support a large number of clients because each client request occupies the server resources only for a short duration. However, the disconnected nature of HTTP provides a major challenge to the Web developers to implement the following functionality in their applications:
Maintain values of controls and variables across page postbacks.
Distinguish the initial request of a page from the page postback.
Provide smart navigation features similar to that of desktop applications.
ASP.NET provides solutions to these problems built right in to its framework. As an ASP.NET developer, you only need to write a minimum amount of code to achieve these functionalities in your application. From my discussion about server controls in Chapter 2, "Controls," you already know that ASP.NET provides a set of server controls that automatically retain their value across page postbacks. You'll learn how ASP.NET actually retains the state for server controls later in this chapter in a section titled "State Management." For now, I'll talk about two properties of the Page classIsPostBack and SmartNavigationthat provide the other two functionalities from the previous list.
The IsPostBack Property
The IsPostBack property of the Page class returns true when a page is being loaded in response to a client postback. If the page is being requested for the first time, the value of the IsPostBack property is false.
A typical case in which you would like to make use of this distinction is when you do not want the server to execute some costly initialization operations for each page postback. Instead, you would like the initializations to be performed only with the first request to the page.
Step by Step 3.1 helps you understand roundtrip and postback operations and demonstrates the use of the IsPostBack property.
STEP BY STEP
3.1 Using the IsPostBack Property
-
Create a new Visual C# ASP.NET Web application project. Name the project 315C03.
-
Add a new Web form to the project. Name the Web form StepByStep3_1.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a DropDownList Web server control (ddlCategories) to the form. Set its AutoPostBack to true and TabIndex to 1 (see Figure 3.1).
-
Add a Label control (lblQuestion) to the Web form.
-
Add a TextBox control (txtTitle) and set its AutoPostBack to true and TabIndex to 2. Add another TextBox (txtMessage) and set its TabIndex to 3 and TextMode to MultiLine (see Figure 3.1).
-
Add a Button control (btnPost) and set its Text to Post a message. Place a Label control (lblWeblog) at the end of the form as shown in Figure 3.1.
-
Switch to the code view of the Web form and add the following code to the Page_Load() event handler:
-
Attach the following event handler to the Click event of the Post button:
-
Set StepByStep3_1.aspx as the start page in the project.
-
Run the project. Use the Tab key to navigate between various fields and publish a few entries to the Weblog as shown in Figure 3.2.
Figure 3.1 The design of a form that allows you to post messages to a Weblog.
private void Page_Load( object sender, System.EventArgs e) { if (!Page.IsPostBack) { // If page is requested for the first time ddlCategories.Items.Add("Web development"); ddlCategories.Items.Add( "Programming Languages"); ddlCategories.Items.Add("Certifications"); } else { // On postback, change the case of // the textbox's text txtTitle.Text = txtTitle.Text.ToUpper(); } // Set the text of the label control // on each page load lblQuestion.Text = "What do you want to write about " + ddlCategories.SelectedItem.Text + " today?"; }
private void btnPost_Click( object sender, System.EventArgs e) { // Format the data entered by the user and // append it to the existing contents of lblWeblog lblWeblog.Text = "<b>" + ddlCategories.SelectedItem.Text + " :: " + txtTitle.Text + "</b> (" + DateTime.Now.ToString() + ")<hr>" + txtMessage.Text + "<p>" + lblWeblog.Text + "</p>"; }
Figure 3.2 The Web form retains state for both postback as well as non-postback controls.
In Step by Step 3.1, I am using the event handler for the Load event of the Page class to check if the page is loaded by a postback operation. If that is the case, I skip executing the code for adding items to the drop-down list.
You also note that the navigation between controls is not smooth. When the form returns after a postback, it does not remember the active control. However, you have a solution to this problem with the help of the SmartNavigation property.
The SmartNavigation Property
ASP.NET has a feature called smart navigation that can greatly enhance the user experience of a Web page for users of Internet Explorer 5.0 or higher browsers. The following list summarizes the enhancements provided by smart navigation:
Persists element focus between postbacksWhen a postback occurs, the active control on the Web page loses its focus. Anyone using a keyboard for navigation will have to press the Tab key several times to return to their original position of data entry. However, when smart navigation is enabled, the information about the active control is persisted between postbacks to the server.
Persists scroll position between postbacksWhen a postback occurs, the browser loses the record of the scroll position of the page. This can be especially annoying in the case of large data entry forms because after postback, the form will be positioned at the beginning and user has to scroll down to find her last data entry position. However, when smart navigation is enabled, the information about the scroll position persists between postbacks to the server.
Eliminates page flash caused by page postbackWhen users navigate from one page to another, the old page is destroyed and the new one is created on a blank screen. Depending on the user's video card and display setting, this operation can cause a small flash to occur. This flash is especially noticeable during page postback operations in which the visual contents of the page do not change significantly between the two page requests. When smart navigation is enabled, ASP.NET uses a technique called double buffering to eliminate this flash.
Prevents each postback from being saved in the browser historyNormally, every postback to an ASP.NET page causes an entry to be created in the browser's history. This defeats the purpose of the browser's back button because instead of going back to the previous page, users are taken to the previous state of the current page. Smart navigation prevents this from happening by saving only the latest state of the current page in the browser's history.
Smart navigation is specified by the SmartNavigation property of the Page class. The default value of this property is false, which disables smart navigation for the Web form.
Smart Navigation
Smart navigation is only supported in Internet Explorer 5.0 or later browsers. Therefore, when you are targeting an application for a generic browser, this feature won't be very helpful.
In most cases, you should not set the SmartNavigation property directly in the code. Instead, you should use the SmartNavigation attribute of the Page directive. Using the SmartNavigation attribute of the Page directive automatically generates the correct code for setting the SmartNavigation property of the Page class, when the Web form is compiled to create a Page derived class.
Step by Step 3.2 enhances the Web form created in Step by Step 3.1 to use the smart navigation feature.
STEP BY STEP
3.2 Using the Smart Navigation Feature of ASP.NET
-
Make a copy of StepByStep3_1 and save it as StepByStep3_2. Make sure that you change all references of StepByStep3_1 to StepByStep3_2 in both the ASPX as well as the CS file.
-
Switch to the HTML view of the StepByStep3_2.aspx file and modify the Page directive to the following:
-
Set StepByStep3_2.aspx as the start page. Build the project and Browse to StepByStep3_2.aspx using Internet Explorer 5.0 or higher.
-
Use the Tab key to navigate between various fields, publish a few messages, and observe the enhancements because of the smart navigation feature.
<%@ Page language="c#" Codebehind="StepByStep3_2.aspx.cs" AutoEventWireup="false" Inherits="_315C03.StepByStep3_2" SmartNavigation="true" %>
In a corporate scenario in which you are sure about the browsers used by the users, you might want to turn on smart navigation for the complete Web application instead of individual files. In that case, you can make the following changes to the web.config file:
<configuration> <system.web> <pages SmartNavigation="true"/> </system.web> </configuration>
ASP.NET Intrinsic Objects
Use and edit intrinsic objects. Intrinsic objects include response, request, session, server, and application.
-
Retrieve values from the properties of intrinsic objects.
-
Set values on the properties of intrinsic objects.
-
Use intrinsic objects to perform operations.
ASP.NET provides intrinsic objects to enable low-level access to the Web application framework. With the help of these intrinsic objects, you can work directly with the underlying HTTP streams, server, session, and application objects. The intrinsic objects can be accessed in a Web form through the properties of the Page class. Table 3.1 lists the important intrinsic objects and the properties of the Page class to which they are mapped.
Table 3.1 Intrinsic Objects and Their Mappings to the Page Class Properties
Intrinsic Object |
Property of the Page Class |
HttpRequest |
Request |
HttpResponse |
Response |
HttpServerUtility |
Server |
HttpApplicationState |
Application |
HttpSessionState |
Session |
I'll discuss the HttpRequest, HttpResponse, and HttpServerUtility objects in the following section. The other two objects, HttpApplicationState and HttpSessionState, are discussed later in this chapter in the section "State Management."
The HttpRequest Object
The HttpRequest object . represents the incoming request from the client to the Web server. The request from the client can come in two waysGET or POST. GET attaches the data with the URL, whereas POST embeds the data within the HTTP request body.
The requested page and its details are encapsulated in an HttpRequest object. The HttpRequest intrinsic object can be accessed by the Request property of the Page class. Tables 3.2 and 3.3 list the properties and methods of the HttpRequest class, respectively. Because the HttpRequest class provides information about the request sent by the client, all the properties are read-only except the Filter property.
Table 3.2 Properties of the HttpRequest Class
Property |
Description |
AcceptTypes |
Specifies the MIME types that the client browser accepts. |
ApplicationPath |
Represents the application's virtual application root path on the server. |
Browser |
Provides access to the capabilities and characteristics of the requesting browser. |
ClientCertificate |
Represents the certificate, if any, sent by the client for secure communications. |
ContentEncoding |
Represents the character encoding (such as UTF7, ASCII, and so on) for the entity body. |
ContentLength |
Specifies the length in bytes of the request. |
ContentType |
Specifies the MIME type of the incoming request. |
Cookies |
Represents the cookies collection that is sent by the client to the server. |
CurrentExecutionFilePath |
Specifies the virtual path of the current executing page on the Web server. |
FilePath |
Specifies the virtual path of the file on the Web server. |
Files |
Represents the file collection that is posted by the client to the Web server. |
Filter |
Represents a stream that is applied as a filter on the incoming request. |
Form |
Specifies the contents of a form posted to the server. |
Headers |
Represents the HTTP headers passed in with the incoming request. |
HttpMethod |
Represents the method of the HTTP request (for example, GET, POST, or HEAD). |
InputStream |
Represents the stream that contains the incoming HTTP request body. |
IsAuthenticated |
Indicates whether the client has been authenticated to the Web site. |
IsSecureConnection |
Indicates whether the client connection is over a secure HTTPS connection. |
Params |
Represents the form, query string, cookies, and server variables collection of the current request. |
Path |
Specifies the virtual path of the current request, along with additional path information. |
PathInfo |
Specifies the additional path information of the current request. |
PhysicalApplicationPath |
Specifies the physical file system path of the application's root directory. |
PhysicalPath |
Specifies the physical file system path of the current request on the Web server. |
QueryString |
Represents the query string collection sent by the client to the Web server through the URL. |
RawUrl |
Specifies the URL portion of the current request, excluding the domain information. |
RequestType |
Represents the type of request (GET or POST) made by the client. |
ServerVariables |
Represents the collection of Web server variables. |
TotalBytes |
Represents the total number of bytes posted to the server in the current request. |
Url |
Specifies information about the current URL request. |
UrlReferrer |
Specifies the URL of the client's previous request that linked to the current URL request. |
UserAgent |
Represents the browser being used by the client. |
UserHostAddress |
Represents the IP address of the requesting client's machine. |
UserHostName |
Represents the Domain Name System (DNS) name of the requesting client's machine. |
UserLanguages |
Specifies the languages preferred by the client's browser. |
Table 3.3 Methods of the HttpRequest Class
Method |
Description |
BinaryRead() |
Reads the specified number of bytes from the request stream. This method is provided for backward compatibility; you should use InputStream property instead. |
MapImageCoordinates() |
Returns the coordinates of a form image that is sent to the server in the current request. |
MapPath() |
Returns the physical file system path of the file for a specified virtual path of a Web server. |
SaveAs() |
Saves the current HTTP request into a disk file, with an option to include or exclude headers. |
CurrentExecutionFilePath
This property of the HttpRequest class returns the file path of the currently executing page. When using the server-side redirection methods such as Server.Execute() and Server.Transfer(), the FilePath property returns the path to the original page, whereas CurrentExecutionFilePath returns the path to the currently executing page.
Step by Step 3.3 displays some of the path-related properties of the HttpRequest object and calls the MapPath() method to get the physical file system path for a specified virtual path. It also displays the header information sent by the client to the server when the StepByStep3_3.aspx page is requested from the server.
STEP BY STEP
3.3 Using the HttpRequest Intrinsic Object
-
Add a new Web form to the project. Name the Web form StepByStep3_3.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Label control (lblInfo) to the Web form.
-
Switch to the code view of the form. Add the following using directive at the top of the code-behind file:
-
Add the following code to the Page_Load() event handler:
-
Set StepByStep3_3.aspx as the start page in the project.
-
Run the project. You should see the Web form displaying the properties for the current request, as shown in Figure 3.3.
using System.Text;
private void Page_Load( object sender, System.EventArgs e) { StringBuilder sbInfo = new StringBuilder(); // Display some of the path related properties // of the HttpRequest object sbInfo.Append("The Url of the ASPX page: " + Request.Url + "<br>"); sbInfo.Append("The Virtual File Path: " + Request.FilePath + "<br>"); sbInfo.Append("The Physical File Path: " + Request.PhysicalPath + "<br>"); sbInfo.Append("The Application Path: " + Request.ApplicationPath + "<br>"); sbInfo.Append("The Physical Application Path: " + Request.PhysicalApplicationPath + "<br>"); // Display the request header sbInfo.Append("Request Header:"); sbInfo.Append("<br>"); NameValueCollection nvcHeaders = Request.Headers; String[] astrKeys = nvcHeaders.AllKeys; // Iterate through all header keys // and display their values foreach (String strKey in astrKeys) { sbInfo.Append(strKey + ": " + nvcHeaders[strKey].ToString()); sbInfo.Append("<br>"); } // Call MapPath() method to find the physical path // of StepByStep3_2.aspx sbInfo.Append( "The physical path of StepByStep3_2.aspx: "); sbInfo.Append( Request.MapPath("StepByStep3_2.aspx")); lblInfo.Text = sbInfo.ToString(); }
Figure 3.3 The Request property of the Page class returns an HttpRequest object that gives access to the HTTP values sent by a client during a Web request.
Some properties of the HttpRequest objectsuch as Form, QueryString, Headers, and so onreturn a NameValueCollection containing a collection of key-value pairs of their contents. Step by Step 3.3 shows how to iterate through this collection by iterating through the keys of the Headers collection and displaying the key and value of each header sent by the client.
The HttpResponse Object
The HttpResponse object represents the response sent back to the client from the Web server. It contains properties and methods that provide direct access to the response stream and allow you to set its behavior and operations. The Response property of the Page class provides access to the HttpResponse object. Tables 3.4 and 3.5 list the properties and methods of the HttpResponse class, respectively.
Table 3.4 Properties of the HttpResponse Class
Property |
Description |
Buffer |
Indicates whether output to the response stream needs to be buffered and sent to the client after the entire page is processed. This property is provided for backward compatibility; the BufferOutput property should be used instead. |
BufferOutput |
Indicates whether the output to the response stream needs to be buffered and then sent to the client after the entire page is processed. The default is true. |
Cache |
Represents the caching policy of the page. The policy controls where caching can be done, the expiration time, and so on. |
CacheControl |
Specifies where the caching should be done. The possible values are Public and Private. |
Charset |
Represents the character set of the output stream. If set to null, the content-type header will be suppressed. |
ContentEncoding |
Represents the character set of the response output stream. |
ContentType |
Represents the MIME type for the outgoing response stream like text/html, text/xml, and so on. |
Cookies |
Represents the cookies collection that is sent by the server to the client. |
Expires |
Indicates the number of minutes until the page is cached by the client browser. |
ExpiresAbsolute |
Indicates the specific date and time until the page is cached by the client browser. |
Filter |
Represents a stream that is applied as a filter to the outgoing response. |
IsClientConnected |
Indicates whether the client is connected to the server. This property is very helpful when running a lengthy request. |
Output |
Allows writing text output to the outgoing response. |
OutputStream |
Allows writing binary output to the outgoing response. |
Status |
Specifies the status of the HTTP output that is sent to the client. This property returns both the status code and the text description of the status (for example, 200 OK). |
StatusCode |
Specifies the numeric representation of the status of the HTTP output sent to the client (for example, 200, 302, and so on). |
StatusDescription |
Specifies the text representation of the status of the HTTP output sent to the client. (for example, OK, Redirect, and so on). |
SupressContent |
Indicates whether the content in the page should be suppressed and not sent to the client. |
Caching Policy
The properties CacheControl, Expires, and ExpiresAbsolute are provided for backward compatibility. You should instead use the HttpCachePolicy object's methods to set the caching policy. This object is returned by the Cache property. Setting caching policy is discussed in Chapter 15, "Configuring a Web Application."
Table 3.5 Methods of the HttpResponse Class
Method |
Description |
AddCacheItemDependencies() |
Makes the validity of the cache item dependent on the other items in the cache. |
AddCacheItemDependency() |
Makes the validity of the cache item dependent on another item in the cache. |
AddFileDependencies() |
Adds a group of files to the collection on which the current response depends. |
AddFileDependency() |
Adds a file to the collection on which the current response depends. |
AddHeader() |
Adds an HTTP header to the outgoing response stream. This method is provided for backward compatibility with ASP. |
AppendHeader() |
Adds an HTTP header to the outgoing response stream. |
AppendToLog() |
Adds information to the IIS Web log file. |
BinaryWrite() |
Allows writing binary data such as an image file or PDF file to the response stream. |
Clear() |
Clears the entire response stream buffer, including ts contents and headers. |
ClearContent() |
Clears the entire content portion of the response stream buffer. |
ClearHeaders() |
Clears the headers portion of the response stream buffer. |
Close() |
Closes the response object and the socket connection to the client. |
End() |
Stops the execution of the page after flushing the output buffer to the client. |
Flush() |
Flushes the currently buffered content out to the client. |
Pics() |
Adds a PICS-label HTTP header to the outgoing response. |
Redirect() |
Redirects the client browser to any URL. This method requires an additional roundtrip to the browser. |
RemoveOutputCacheItem() |
Removes all cache items for the path specified. |
Write() |
Writes output to the outgoing response. |
WriteFile() |
Writes a file to the outgoing response. |
Step by Step 3.4 shows the use of HttpResponse object methods and properties to create a response that displays the File Download dialog box and allows the user to download a text file from the Web server to the client's machine.
STEP BY STEP
3.4 Using the HttpResponse Intrinsic Object
-
Add a new Web form to the project. Name the Web form StepByStep3_4.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a text file to the project that contains some data that needs to be downloaded. Name it Summary.txt.
-
Add a LinkButton control (lbtnDownload) to the Web form with its Text property set to Download Summary.txt.
-
Double-click the lbtnDownload control and add the following code to the Click event handler:
-
Set StepByStep3_4.aspx as the start page in the project.
-
Run the project. Click the link button. You should see a File Download dialog box, as shown in Figure 3.4. After the download, open the file to verify that the file has been successfully downloaded.
private void lbtnDownload_Click(object sender, System.EventArgs e) { // Append a Header to the response to force a // Download of Summary.txt as an attachment Response.AppendHeader("Content-Disposition", "Attachment;FileName=" + "Summary.txt"); // Set the Content type to text/plain // As the download file is a TXT file Response.ContentType = "text/plain"; // Write the file to the Response Response.WriteFile("Summary.txt"); // Stop further execution of the page Response.End(); }
Figure 3.4 The File Download dialog box provides the interface to download a file from the Web server.
The HttpServerUtility Object
The HttpServerUtility object contains utility methods and properties to work with the Web server. It contains methods to enable HTML/URL encoding and decoding, execute or transfer to an ASPX page, create COM components, and so on. The Server property of the Page class provides access to the HttpServerUtility object. Tables 3.6 and 3.7 list the properties and methods of the HttpServerUtility class, respectively.
Table 3.6 Properties of the HttpServerUtility Class
Property |
Description |
MachineName |
Returns the name of the server that hosts the Web application. |
ScriptTimeout |
Indicates the number of seconds that are allowed to elapse when processing the request before a timeout error is sent to the client. |
Table 3.7 Methods of the HttpServerUtility Class
Method |
Description |
ClearError() |
Clears the last exception from memory. This method is discussed in Chapter 4, "Error Handling for the User Interface." |
CreateObject() |
Creates a COM object on the server. This method is discussed in Chapter 10, "Working with Legacy Code." |
CreateObjectFromClsid() |
Creates a COM object on the server identified by a specified class identifier (CLSID). |
Execute() |
Executes an ASPX page within the current requested page. |
GetLastError() |
Returns the last exception that occurred on the Web server. This method is discussed in Chapter 4. |
HtmlDecode() |
Decodes a string that has been previously encoded to eliminate invalid HTML characters. |
HtmlEncode() |
Encodes a string converting any characters that are illegal in HTML for transmission over HTTP. |
MapPath() |
Returns the physical path for a specified virtual path on a Web server. |
Transfer() |
Allows the transfer of ASPX page execution from the current page to another ASPX page on the same Web server. |
UrlDecode() |
Decodes a string that has been previously encoded to eliminate invalid characters for transmission over HTTP in a URL. |
UrlEncode() |
Encodes a string converting any characters that are illegal in URL for HTTP transmission. |
UrlPathEncode() |
Encodes the path portion of the URL string for safe transmission over HTTP. |
STEP BY STEP
3.5 Using the HttpServerUtility Intrinsic Object
-
Add a new Web form to the project. Name the Web form StepByStep3_5.aspx. Change the pageLayout property of DOCUMENT element to FlowLayout.
-
Add the following code to the Page_Load() event handler:
-
Set StepByStep3_5.aspx as the Start page in the project.
-
Run the project. You should see that the browser does not parse the HTML <title> elements written to the response, as shown in Figure 3.5, because of the use of the HtmlEncode() method of the HttpServerUtility class.
private void Page_Load( object sender, System.EventArgs e) { // Write to the response // using the Server.HtmlEncode() method // so that the browser does not parse // the text into HTML elements Response.Write(Server.HtmlEncode( "To include a title in the title bar, " + "enclose your chosen title between the " + "pairs of the <title>...</title> element " + "in the HTML <head> element. ")); Response.Write(Server.HtmlEncode( "For example, <title> " + "Using the HtmlEncode() method </title>.")); }
Figure 3.5 The HtmlEncode() method of the HttpServerUtility object. HTML encodes a string to be displayed in the browser.
I will discuss various other methods of the HttpServerUtility object throughout the course of this book.
Guided Practice Exercise 3.1
Several Web sites collect statistics about the browsers, operating system, and other settings on their users' computers. This data helps the Web sites customize their contents to target a large number of users. A common requirement for Web applications is to find out the browser versions of their users and then serve them files that are optimized for that particular browser version.
In this exercise, you are required to create a Web form that displays the following information about the client browser: the browser name, version, platform of the client's computer, the CLR version installed, JavaScript support, ECMA version, MS DOM version, and the W3C XML DOM version supported by the browser.
You can use the Request.Browser property to get access to the HttpBrowserCapabilities object that provides various properties that contain information on the capabilities of the client's browser.
How would you create a Web form that allows the Web page to get information about the browser?
You should try working through this problem on your own first. If you are stuck, or if you'd like to see one possible solution, follow these steps:
-
Open the project 315C03. Add a new Web form GuidedPracticeExercise3_1.aspx to the project. Change the pageLayout property of DOCUMENT element to FlowLayout.
-
Add a Label control (lblInfo) to the Web form.
-
Switch to the code view of the form. Add the following using directive at the top of the code-behind file:
-
Add the following code to the Page_Load() event handler:
-
Set GuidedPracticeExercise3_1.aspx as the start page in the project.
-
Run the project. You should see the Web form displaying the properties of the browser as shown in Figure 3.6.
using System.Text;
private void Page_Load( object sender, System.EventArgs e) { StringBuilder sbText = new StringBuilder(); // Get the reference to the // HttpBrowserCapabilities object HttpBrowserCapabilities browser = Request.Browser; // Display the properties of the // HttpBrowserCapabilities Class sbText.AppendFormat("Browser : " + browser.Browser + "<br>"); sbText.AppendFormat("Browser Version: " + browser.Version + "<br>"); sbText.AppendFormat("Client's Platform: " + browser.Platform + "<br>"); sbText.AppendFormat(".NET CLR Version: " + browser.ClrVersion + "<br>"); sbText.AppendFormat("ECMA Script Version: " + browser.EcmaScriptVersion + "<br>"); sbText.AppendFormat("JavaScript Support: " + browser.JavaScript + "<br>"); sbText.AppendFormat( "Microsoft HTML Document Object Model Version: " + browser.MSDomVersion + "<br>"); sbText.AppendFormat( "World Wide Web (W3C) XML Document " + " Object Model Version: " + browser.W3CDomVersion + "<br>"); lblInfo.Text=sbText.ToString(); }
Figure 3.6 The HttpBrowserCapabilities object provides access to the capabilities of the client's browser.
If you have difficulty following this exercise, review the section "The HttpRequest Object" earlier in this chapter and perform Step by Step 3.3. Also, look at the .NET Framework documentation for the System.Web.HttpBrowserCapabilities class. After doing this review, try this exercise again.
REVIEW BREAK
Web applications are disconnected in nature. Values of page variables and controls are not preserved across the page requests.
You can use the Page.IsPostBack property to determine whether a page is being loaded for the first time or in response to a postback operation.
ASP.NET has a feature called smart navigation that can greatly enhance the user experience of a Web page for the users of Internet Explorer 5.0 or higher browsers.
ASP.NET provides intrinsic objects to enable low-level access to the Web application framework. With the help of these intrinsic objects, you can work directly with the underlying HTTP request, HTTP response, server, session, and application objects.
ASP.NET Application
An ASP.NET application is made up of the Web forms, assemblies, and other files stored within a virtual Web directory marked as an IIS application.
When ASP.NET receives a request for a resource in an ASP.NET application, it instantiates an HttpApplication object. The HttpApplication object then takes over the processing of incoming request. An HttpApplication object can only handle one request at a time. To process multiple simultaneous requests, ASP.NET needs to create multiple HttpApplication objects.
For the sake of optimization, instead of destroying the HttpApplication object, ASP.NET maintains a pool of HttpApplication objects. When a new HTTP request arrives, ASP.NET reuses one of the objects from this pool rather than creating a new HttpApplication object from scratch.
The HttpApplication class defines the methods, properties, and events common to all application objects within an ASP.NET application. If you want to customize the behavior of an HttpApplication object, you can derive a class from the HttpApplication class and override the event handlers of the base class for various application level events. An easy way to do this is by using the global.asax file.
The global.asax File
ASP.NET provides an easy way to customize your applications by using the global.asax file. This optional file resides in the root directory of an ASP.NET application. The global.asax file defines a class named Global that derives from the HttpApplication class. When ASP.NET notices that the global.asax file is present for an application, rather than using the implicitly created HttpApplication object, ASP.NET creates instances of the class defined in the global.asax file to handle requests for your application.
Visual Studio .NET automatically creates a global.asax file when you create an ASP.NET Web application project. As with Web forms, Visual Studio .NET creates a code-behind version of the global.asax file. When you make any changes to the code-behind file for global.asax, you must precompile the file before the server can detect those changes. However, it is also possible to create a single file implementation of the global.asax file. In that case, instead of being precompiled, the global.asax file will be dynamically compiled at runtime by ASP.NET.
The global.asax File Is Protected
You use the global.asax file to provide event handlers for various application level events. For security reasons, ASP.NET restricts users of your application from downloading any file with the extension .asax.
Global Event Handlers
The global.asax file is an appropriate place to handle events that are not specific to a Web form, but rather apply to an application as a whole. I'll call these events global events and classify them in two categoriesApplication and session level events and Per-Request events.
Application and Session Level Events
Application and session level events are fired to signal the start and end of the application or a user session. These events can be handled using the predefined event handlers in the global.asax file shown in Table 3.8.
Table 3.8 Application and Session Level Event Handlers in the global.asax File
Event Handler |
Purpose |
Application_Start() |
Called when an application receives its first request. Generally used to initialize data that is shared among all users of an application. |
Application_End() |
Called when an application shuts down. Here you can write code to persist the information stored in memory that you want to have reloaded when the application restarts. |
Session_Start() |
Called when an ASP.NET application creates a new session for a user of the application. |
Session_End() |
Called when the user's session expires. By default, this happens 20 minutes after the last request of a page from a user. |
Per-Request Events
The event handlers shown in Table 3.9 are invoked for each individual page request processed by the HttpApplication object.
Table 3.9 Per-Request Event Handlers
Event Handler |
Purpose |
Application_BeginRequest() |
Called at the beginning of each request. |
Application_AuthenticateRequest() |
Called when a security module has established the identity of the user. |
Application_AuthorizeRequest() |
Called when a security module has verified user authorization. |
Application_ResolveRequestCache() |
Called to resolve the current request by providing content from a cache. |
Application_AcquireRequestState() |
Called to associate the current request with the session state. |
Application_PreRequestHandlerExecute() |
Called when ASP.NET begins executing a page. |
Application_PostRequestHandlerExecute() |
Called when ASP.NET finishes executing a page. |
Application_ReleaseRequestState() |
Called to save the current state data. |
Application_UpdateRequestCache() |
Called to update a cache with the responses. |
Application_EndRequest() |
Called at the end of each request. |
As you can see from Table 3.9, you have complete control over how a request is processed. You can write code in any of these event handlers to modify the default behavior of ASP.NET. Step by Step 3.6 uses the Application_BeginRequest() and Application_EndRequest() methods to determine the time it took for each request to process and append this information with every response.
STEP BY STEP
3.6 Handling Global Events Using the global.asax File
-
Open the global.asax file from the Solution Explorer. Click on the Click Here to Switch to Code View hyperlink to switch to code view.
-
Add the following code to the Application_BeginRequest() event handler:
-
Add the following code to the Application_EndRequest() event handler:
-
Run the project. You should see that the page shows a message at the bottom indicating the processing time of the request, as shown in Figure 3.7.
protected void Application_BeginRequest(Object sender, EventArgs e) { // Store the begin time of the // request in the HttpContext object this.Context.Items.Add("BeginTime", DateTime.Now); }
protected void Application_EndRequest(Object sender, EventArgs e) { // Get the begin time from the HttpContext object DateTime dtBeginTime = (DateTime) this.Context.Items["BeginTime"]; // Calculate the time span between // the start and end of request TimeSpan tsProcessingTime = DateTime.Now-dtBeginTime; // Display the processing time taken // by the response this.Context.Response.Output.Write("<hr>"); this.Context.Response.Output.Write( "{0} took {1} milliseconds to execute.", this.Request.Url, tsProcessingTime.TotalMilliseconds); }
Figure 3.7 The global.asax file gives you access to application-level events that affect all the pages in an application.
In Step by Step 3.6, the Context object is used to store the begin time. The Context object exposes a key-value collection via the Items property in which you can add values that will be available for the life of the current request. The Context object gives access to the current HTTP request and response.
The modification of the global.asax file in Step by Step 3.6 will affect all other Web forms in the Web application 315C03. If at a later stage, you would like to disable the output generated by the global events, just comment the corresponding lines in the global.asax file.
REVIEW BREAK
ASP.NET maintains a pool of HttpApplication objects. When a new HTTP request arrives, ASP.NET uses one of the objects from this pool rather than creating an HttpApplication object from scratch.
The global.asax file can be used to define a customized HttpApplication class. When the global.asax file is defined in the Web application's root directory, ASP.NET uses the HttpApplication-derived class defined in the global.asax file to serve the Web application.
The global.asax file is an appropriate place for handling global events that are not specific to a Web form, but rather apply to an application as a whole.
State Management
Implement navigation for the user interface.
-
Manage the view state.
-
Use session state to manage data across pages.
The value of the variables and controls collectively make up the state of a Web page. State management is the process of maintaining state for a Web page across roundtrips.
State management is ubiquitous with desktop-based applications, and programmers need not even care about it while developing these applications. However, because of the disconnected nature of the HTTP, state management is a big issue for Web applications.
ASP.NET provides several techniques for preserving state information across page postbacks. I'll broadly categorize these techniques as either client-side or server-side, depending on where the resources are consumed for state management.
Client-Side Techniques for State Management
Client-side techniques use the HTML code and the capabilities of the Web browser to store state-related information. ASP.NET supports the following techniques for storing state information at the client side:
Query strings
Cookies
Hidden Fields
View State
Query Strings
Query strings are used to maintain state by appending the state information to a page's URL. The state data is separated from the actual URL with a question mark (?). The data attached to the URL is usually a set of key-value pairs, where each key-value pair is separated by an ampersand (&). For example, look at this URL that embeds two key-value pairs, name and city:
http://www.buddy.com/find.aspx?name=Bill+Gates&city=redmond
Because of its simplicity, query strings are widely used for passing a small amount of information to Web pages. However, query strings suffer the following limitations:
Most browsers restrict the length of the query string; this reduces the amount of data that you can embed in a URL.
Query strings do not provide any support for structured data types.
The information stored in a query string is not secure because it is directly visible to users in the browser's address field.
Reading information from query string in an ASP.NET program is easy using the QueryString property of the current HttpRequest object. QueryString returns a NameValueCollection object representing the key-value pairs stored in the query string. Step by Step 3.7 shows you how query strings can be used for client-side state management.
STEP BY STEP
3.7 Using Query Strings in a Web Application
-
Add a new Web form to the project. Name the Web form StepByStep3_7.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add two Label controls, two TextBox controls (txtName, txtEmail), and a Button control (btnSubmit) on the Web form.
-
Double-click the button control and add the following code in the Click event handler:
-
Add a new Web form to the project. Name the Web form StepByStep3_7a.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Label control (lblInfo) to the Web form.
-
Add the following code in the Page_Load() event handler:
-
Set StepByStep3_7.aspx as the start page in the project.
-
Run the project. Enter a name and an email in the text boxes and click the Submit button. You should see that the button redirects the response to the StepByStep3_7a.aspx with the name and email address data in the query string. The new form then displays a message along with the name and email address fetched from the query string as shown in Figure 3.8.
private void btnSubmit_Click(object sender, System.EventArgs e) { // Redirect to StepByStep3_7a.aspx page, // with a query string containing name and // email appended to the URL Response.Redirect("StepByStep3_7a.aspx?Name=" + txtName.Text + "&Email=" + txtEmail.Text); }
private void Page_Load( object sender, System.EventArgs e) { // If the query string collection contains Name if(Request.QueryString["Name"] != null) { // Display a message by getting Name and Email // from the query string collection lblInfo.Text = Request.QueryString["Name"] + ", thanks for registering with us! "; lblInfo.Text += "You are subscribed at " + Request.QueryString["Email"]; } }
Figure 3.8 The query string is used to maintain state by appending the state information to a page's URL.
If you observe the URL in Figure 3.8, you'll note that the name and email addresses are embedded in the URL itself. Query string is a very effective way to pass small non-sensitive pieces of information.
Cookies
Cookies are small packets of informationeach storing a key-value pair at the client side. These packets are associated with a specific domain and are sent along with each request to the associated Web server.
A cookie can be set to expire when a user session ends, or you can request that the browser persist the cookie on the user's computer for a specified period. Cookies are commonly used to store users' preferences and provide them with a personalized browsing experience on their subsequent visits to a Web page.
Use of cookies suffers from the following limitations:
Most browsers limit the size of information that you can store in a cookie. The typical size is 4,096 bytes with older browser versions and 8,192 bytes with the newer browser versions.
Some users configure their browsers to refuse cookies.
When you request that the browser persist a cookie on a user's computer for a specified period, the browser might override that request by using its own rules for cookie expiration.
Because cookies are stored at the client, they might be tampered with. You cannot trust data that you receive from a cookie.
You can use the Cookies property of the HttpRequest object to get an HttpCookieCollection object that represents the cookies sent by the client for the current HTTP request.
Step by Step 3.8 shows you how cookies can be used for client-side state management.
STEP BY STEP
3.8 Using Cookies to Maintain Client-Side State
-
Make a copy of the Web form StepByStep3_1.aspx and change its name to StepByStep3_8.aspx. Open the ASPX file and the CS file and replace all occurrences of StepByStep3_1 with StepByStep3_8.
-
Switch to the code view and add the following code above the existing code in the Page_Load() event handler:
-
Double-click the Post button control and add the following code in the Click event handler:
-
Add a new Web form to the project. Name the Web form StepByStep3_8a.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Label control, a TextBox control (txtName), a Button control (btnSubmit), and a CheckBox control (cbRemember) on the Web form.
-
Double-click the Submit button control and add the following code in the Click event handler:
-
Set StepByStep3_8.aspx as the start page in the project.
-
Run the project. You should see that you have been redirected to StepByStep3_8a.aspx. Enter a name, select the checkbox, and click the Submit button. You'll now see StepByStep3_8.aspx with a personalized greeting. Post a message. You should see that your name is now posted along with the title of the message, as shown in Figure 3.9.
-
Close this browser window. Open another browser window and browse to StepByStep3_8.aspx. Assuming that you checked the Remember Me check box in step 8, you should see the Weblog window personalized with your name.
private void Page_Load( object sender, System.EventArgs e) { if(Request.Cookies["Name"] == null) { // If the Name cookie does not exist, // ask user to enter name Response.Redirect("StepByStep3_8a.aspx"); } else { // If cookie already exists, show // a personalized welcome message to the user lblName.Text="Welcome " + Request.Cookies["Name"].Value; } ... }
private void btnPost_Click( object sender, System.EventArgs e) { // Format the data entered by the user and // use the name of the user stored in a cookie // Append to it the existing contents of lblWeblog lblWeblog.Text = "<b>" + ddlCategories.SelectedItem.Text + " :: " + txtTitle.Text + ":: by " + Request.Cookies["Name"].Value + "</b> (" + DateTime.Now.ToString() + ")<hr>" + txtMessage.Text + "<p>" + lblWeblog.Text + "</p>"; }
private void btnSubmit_Click(object sender, System.EventArgs e) { // Create a cookie called Name // Set the cookie with the Text of the text box HttpCookie cName = new HttpCookie("Name"); cName.Value = txtName.Text; // Check if the checkbox remember me is checked if(cbRemember.Checked) { // Set the expiration time of the cookie // to 15 minutes from the current time cName.Expires = DateTime.Now + new TimeSpan(0,0,15,0); } // Add the cookie to the response cookies // collection to send it to the client's machine Response.Cookies.Add(cName); // Redirect the response to the message post page Response.Redirect("StepByStep3_8.aspx"); }
Figure 3.9 Cookies can be used to provide personalization settings for individual users.
Step by Step 3.8 demonstrates how cookies can be used to persist state across browser restarts. If you don't select the check box, cookies will just be stored in the primary memory and will be destroyed when the browser window is closed. The program also demonstrates how you can request the browser to set an expiration date and time for the cookie. Step by Step 3.8 sets the expiration time of the cookie to 15 minutes from the current time. You should note that this is just a request; browsers are free to override this with their own settings.
Hidden Fields
Hidden fields contain information that is not visible on the page but is posted to the server along with a page postback. All modern browsers support hidden fields on a Web page. However, hidden fields have some limitations as mentioned in the following list:
Although information stored in a hidden field is not visible on the page, it is still part of the page's HTML code and users can see the value of a hidden field by viewing the HTML source of the page. Hidden fields are therefore not a good choice for storing information that you would like to keep secure.
Hidden fields are part of the page HTML. If you store more information in hidden fields, it increases the size of the HTML page, making it slow for users to download.
Hidden fields only allow you to store a single value in a field. If you want to store structured values such as those in a customer record, you'll have to use several hidden fields.
ASP.NET provides an HTML server control, HtmlInputHidden, that maps to the <input type="hidden"> HTML element. Step by Step 3.9 demonstrates the use of hidden fields to maintain the number of posts on the Weblog page created in Step by Step 3.1.
STEP BY STEP
3.9 Using Hidden Fields to Maintain Client-Side State
-
Make a copy of the Web form StepByStep3_1.aspx and change its name to StepByStep3_9.aspx. Open the ASPX file and the CS file and replace all occurrences of StepByStep3_1 with StepByStep3_9.
-
Place a Label control (lblPosts) and an HTML Hidden control (txtPosts) next to the Post button control on the form.
-
Switch to the code view and modify the Click event handler of the btnPost control as follows:
-
Set StepByStep3_9.aspx as the start page in the project.
-
Run the project. Make a few entries in the Weblog. You will see that with each entry in the Weblog, the total posts value is increased by 1, as shown in Figure 3.10.
private void btnPost_Click(object sender, System.EventArgs e) { // Format the data entered by the user and // append it to the existing contents of lblWeblog lblWeblog.Text ="<b>" + ddlCategories.SelectedItem.Text + " :: " + txtTitle.Text + "</b> (" + DateTime.Now.ToString() + ")<hr>" + txtMessage.Text + "<p>" + lblWeblog.Text + "</p>"; // As one more post is added // Increment the value of the hidden control Int32 intPostCount = Int32.Parse(txtPosts.Value) + 1; txtPosts.Value = intPostCount.ToString(); lblPosts.Text = "Total Posts: (" + txtPosts.Value + ")"; }
Figure 3.10 Contents of hidden fields are posted to the Web server with each page postback.
Step by Step 3.9 shows a typical example in which the hidden fields can be used to maintain state information. Here, because a hidden field is an input control, its value is posted back to the Web server with each page postback. The hidden fields can be used to store page scope values between roundtrips. The HtmlInputHidden control is not available as a Web server control mainly because ASP.NET uses a similar, but more powerful, technique called view state.
View State
View state is the mechanism that ASP.NET uses to maintain the state of controls across page postbacks. Just like hidden fields and cookies, you can also use view state to maintain state for non- control values in a page. However, it is important to note that the view state works only when a page is posted back to itself.
The following sections explain how view state works in various scenarios.
View State for Postback Controls
Some server controls, such as TextBox, CheckBox, and so on, post their values as part of the postback operation. These types of controls are also known as postback controls. For postback controls, ASP.NET retrieves their values one by one from the HTTP Request and copies them to the control values while creating the HTTP response. Traditionally, Web developers had to manually write this code for maintaining state for the postback controls, but now ASP.NET does this automatically.
View state does not require any additional storage either on the client side or on the server side for maintaining state for the postback controls.
View State for Non-postback Controls
In addition to the postback controls, the view state mechanism of ASP.NET also retains values for non-postback controls (that is, the controls that do not post their values as part of the postback operation, such as a Label control). You might wonder how ASP.NET manages to maintain values for a control even when the controls do not post their values. Actually, no magic is involved; ASP.NET extends the concept of hidden fields to accomplish this.
When ASP.NET executes a page, it collects the values of all non-postback controls that are modified in the code and formats them into a single, base64-encoded string. This string is then stored in a hidden field in a control named __VIEWSTATE, as in this example:
<input type="hidden" name="__VIEWSTATE" value= "dDwtMTg3NjA4ODA2MDs7PoYLsizcOhkv2XeRfSJNPt12o1HP" />
The hidden input field is a postback control, so in the next postback of the page, the encoded string stored in the __VIEWSTATE field is also posted. At the Web server, ASP.NET decodes the view state string at page initialization and restores the controls values in the page.
Maintaining state using this technique does not require many server resources, but it definitely increases the size of the HTML file, which therefore increases the amount of time it takes to load the page.
View State for Page-Level Values
The ViewState property of the Page class is a great place to store page-level values. View state will save these values just prior to rendering the page and will restore the values at the time of page initialization after the postback operation. This might sound like cookies or hidden fields, but a major improvement is that you are not just limited to storing simple values. You can use the ViewState to store any object as long as it is serializable.
A good practice is to expose a page-level value as a property that internally manipulates the ViewState of the page. For example,
protected int NumberOfPosts { get { if(ViewState["NumberOfPosts"] == null) { return 0; } else { return Convert.ToInt32( ViewState["NumberOfPosts"]); } } set { ViewState["NumberOfPosts"] = value; } }
I'll use this technique in Step by Step 3.10 to maintain the number of posts on the Weblog using the view state.
STEP BY STEP
3.10 Using View State to Maintain State for Page-Level Values
-
Make a copy of the Web form StepByStep3_1.aspx and change its name to StepByStep3_10.aspx. Open the ASPX file and the CS file and replace all occurrences of StepByStep3_1 with StepByStep3_10.
-
Place a Label control (lblPosts) next to the button control on the form.
-
Switch to the code view and add the following property to the class StepByStep3_10 definition:
-
Modify the event handler for the Click event of the btnPost control as shown here:
-
Set StepByStep3_10.aspx as the start page in the project.
-
Run the project. Make a few entries in the Weblog. You should see that with each entry in the Weblog, the total posts value is increased by 1, just as it did in Step by Step 3.10.
-
View the HTML code rendered in the Web browser. You'll note that the value associated with the __VIEWSTATE field increases as the size of the text in the lblWeblog control increases.
// get or set the number of posts in the Weblog protected int NumberOfPosts { get { if(ViewState["NumberOfPosts"] == null) { // The NumberOfPosts key is not // present in the ViewState return 0; } else { // Retrieve the NumberOfPosts key // from the ViewState return Convert.ToInt32( ViewState["NumberOfPosts"]); } } set { // Set the NumberOfPosts key in the ViewState ViewState["NumberOfPosts"] = value; } }
private void btnPost_Click( object sender, System.EventArgs e) { // Format the data entered by the user and // append it to the existing contents of lblWeblog lblWeblog.Text = "<b>" + ddlCategories.SelectedItem.Text + " :: " + txtTitle.Text + "</b> (" + DateTime.Now.ToString() + ")<hr>" + txtMessage.Text + "<p>" + lblWeblog.Text + "</p>"; // One more post is added // Increment the value of NumberOfPosts // key in the Page's ViewState NumberOfPosts = NumberOfPosts + 1; lblPosts.Text = "Total Posts : (" + NumberOfPosts + ")"; }
As you can see in Step by Step 3.10, view state is internally maintained as a hidden field. However, view state provides a higher degree of customizability and other security features that you'll see shortly.
Disabling View State
By default, view state is enabled in an ASP.NET application. As you have observed in Step by Step 3.10, the size of information stored in view state can increase the size of HTML for a Web page. This is especially important when your application contains complex controls such as a DataList or DataGrid. To optimize a Web page's size, you might want to disable view state in the following cases:
When a page does not postback to itself
When there are no dynamically set control properties
When the dynamic properties are set with each request of the page
ASP.NET provides you complete flexibility to disable view state at various levels as mentioned in the following list:
-
At the level of a controlIf you populate the control's state on each request, you can disable view state at the control level by setting the EnableViewState property of the control to false:
<asp:DataGrid EnableViewState="false" .../>
At the level of a pageIf the page doesn't post back to itself, you can disable view state at the page level by setting the EnableViewState attribute of the Page directive to false in the ASPX page:
<%@ Page EnableViewState="false" %>
At the level of an applicationIf none of the pages in an application post back to themselves, you can disable view state at the application level by adding the following line to the web.config file:
<Pages EnableViewState="false"/>
At the level of the machineIn the unlikely case in which you want to disable view state for all applications running on a Web server, you can do so by adding the following statement to the machine.config file:
<Pages EnableViewState="false"/>
Protecting View State
To prevent malicious users from manipulating the view state, ASP.NET provides a way of knowing if somebody has modified the contents of the view state to fool your application. Using this technique, the view state is encoded using a hash code (using the SHA1 or MD5 algorithms) when it is sent to the browser. When the page is posted back, ASP.NET checks the encoded view state to verify that it has not been tampered with on the client. This type of check is called a machine authentication check (MAC). By default, ASP.NET has the following entry in its machine.config file:
<pages EnableViewStateMac="true" />
ViewState Decoder
You can decode the contents stored in the __VIEWSTATE hidden input control using the ViewState Decoder utility written by Fritz Onion. You can download this utility from
http://www.develop.com/devresources/ resourcedetail.aspx?type=t&id=827
This enables tamper proofing for all applications running on a Web server. You can also manually enable or disable the tamper-proofing check at a page level by setting the EnableViewStateMac attribute of the Page directive to true or false in the ASPX page:
<%@ Page EnableViewStateMac="false"%>
Secure Only When Needed
Running security algorithms puts additional overhead on your Web server and makes applications slower. Therefore, you should enable security for view state only when it is a must.
However, this scheme just makes the view state tamper proof. It does not restrict the users from determining the contents of the view state. Although the values are not directly visible as in the cases of query strings or hidden variables, determined users can readily decode the view state.
View State Security on a Web Farm
When securing the view state for applications running on a Web farm configuration, you must use the same validation key for all the machines on a Web farm. To do this, use a manually assigned key instead of the default autogenerated key with the <machineKey> setting in the machine.config file.
With only a few configuration changes, it's possible to instruct ASP.NET to encrypt the contents of view state using Triple DES symmetric algorithm (3DES), making it extremely difficult for the clients to decode the view state. This kind of encryption can be applied only at the machine level by specifying the following setting in the machine.config file:
<machineKey validation='3DES' />
Choosing a Client-Side State Management Technique
Table 3.10 lists the advantages and disadvantages of the various client-side state management techniques. This table will help you make a quick decision about which client-side state management technique to choose in a given scenario.
Table 3.10 Comparing the Client-Side State Management Techniques
Technique |
Advantage |
Disadvantage |
QueryString |
Requires no postback operation. |
Most browsers limit the length of data that can include in a query string. |
|
|
No Security. |
|
|
No options for persistence. |
|
|
No support for storing structured values. |
Cookies |
State can be persisted on user's computer. |
Some users disable cookies in their browsers. |
|
Requires no postback operation. |
Size restriction by browser (~4 to 8KB). |
|
|
No support for storing structured values. |
|
|
No Security. |
Hidden fields |
Can be used for pages that post to themselves or to other pages. |
Increases HTML size. |
|
|
No support for storing structured values. |
|
|
No Security. |
|
|
No options for persistence. |
View State |
Support for structured values. |
Increases HTML size. |
|
Involves less coding. |
Works only when a page posts back to itself. |
|
Easy configuration options for security. |
No options for persistence. |
Server-Side Techniques for State Management
Unlike client-side techniques for state management, server-side techniques use server resources for storing and managing state. One of the advantages of using server-side techniques for state management is that the possibility of a user spoofing or reading the session data is eliminated, but there is a disadvantage, too: These techniques use server resources, raising scalability issues.
ASP.NET supports server-side state management at two levelsat the level of the Web application using the application state, and at the level of a user session using the session state.
Session State
An ASP.NET application creates a session for each user who sends a request to the application. ASP.NET distinctly identifies each of these sessions by sending a unique SessionID to the requesting browser. This SessionID is sent as a cookie or is embedded in the URL, depending on the application's configuration.
This mechanism of sending SessionID ensures that when the next request is sent to the server, the server can use the unique SessionID to distinctly identify the repeat visit of the user. Both user visits are considered to belong to the same session.
The capability of uniquely identifying and relating requests can be used by Web developers to store session-specific data. A common example is storing the shopping cart contents for the users as they browse through the store. This session-specific information is collectively known as the session state of a Web application.
Comparing ASP.NET Session State with ASP
The concepts of SessionID and session state are not unique to ASP.NET. ASP.NET's predecessor, ASP, also supported these features. However, session state in ASP was considered a flaw and many large sites wrote their own code for maintaining session state. ASP.NET comes with a new implementation of session state that removes all the old problems and provides several enhancements that are equally useful to small and very large Web sites. Table 3.11 compares these improvements.
Table 3.11 Managing the Session State
The ASP Way |
The ASP.NET Way |
ASP maintains the state in the same process that hosts ASP. If the ASP process somehow fails, the session state is lost. |
ASP.NET allows you to store session state out-of-process in a state service or database. |
Each ASP Web server maintains its own session state. This creates a problem in the Web farm scenario, where the user's requests can be dynamically routed to different servers in the Web farm. |
Because ASP.NET can store its session state out-of-process, several computers in a Web farm can use a common computer as their session state server. |
ASP sessions do not work with browsers that don't support cookies or where the users have disabled cookies. |
ASP.NET supports cookieless sessions by storing the SessionID in the URL itself by changing the application configuration. |
Moreover, session state in ASP.NET is configurable. Depending on the requirements of your Web application, you can change the way the session state is maintained in your application by just changing a few lines in an XML-based configuration file (web.config). You will learn about session state configuration in Chapter 15.
Using Session State
ASP.NET uses an instance of the HttpSessionState class to provide access to the session data for the user who originated the request. In an ASPX page, this object is accessible through the Session property of the Page class. This property provides access to the HttpSessionState object that stores the session state as a collection of key-value pairs, where the key is of string type while the value can be any type derived from System.Object. Tables 3.12 and 3.13 explain properties and methods of the HttpSessionState class, respectively.
Table 3.12 Properties of the HttpSessionState Class
Property |
Description |
CodePage |
Specifies the code page identifier for the current session. This provides compatibility with ASP. Response.ContentEncoding.CodePage should be used instead. |
Contents |
Gets a reference to the session state (HttpSessionState) object. This provides compatibility with ASP. |
Count |
Gets the number of objects in the session state. |
IsCookieless |
Indicates whether the session is managed using cookieless session. |
IsNewSession |
Indicates whether the session has been created with the current request. |
IsReadOnly |
Indicates whether the session is read-only. |
IsSynchronized |
Indicates whether access to the session state is synchronized (thread-safe). |
Keys |
Gets a collection of all session keys. |
LCID |
Specifies the locale identifier (LCID) of the current session. |
Mode |
Gets the current session state mode. The values are defined by the SessionStateMode enumerationOff (disabled), InProc (default, session state is stored in process with aspnet_wp.exe), SqlServer (session state is stored in SQL Server), and StateServer (session state is stored in state service). |
SessionID |
Represents the unique session identifier used to identify a session. |
StaticObjects |
Gets a collection of objects declared by <object runat="server" scope="Session"> tags within the ASPX application file global.asax. |
SyncRoot |
Gets an object that can be used to synchronize access to the collection of session state values. |
Timeout |
Specifies the timeout period (in minutes) allowed between requests before the session state provider terminates the session. |
Table 3.13 Methods of the HttpSessionState Class
Property |
Description |
Abandon |
Cancels the current session. |
Add |
Adds a new object to the session state. |
Clear |
Removes all objects from the session state. |
CopyTo |
Copies the session state values to a single-dimensional array at the specified index. |
GetEnumerator |
Gets an enumerator of all session state values in the current session. |
Remove |
Removes an object from the session state. |
RemoveAll |
Removes all the objects from the session state. Calls the Clear() method internally. |
RemoveAt |
Removes an object from the session state at a particular index. |
Step by Step 3.11 demonstrates the use of session state by upgrading the cookie example that you used in Step by Step 3.8 to maintain the session state at the server side instead of maintaining state at the client side.
STEP BY STEP
3.11 Using Session State
-
Make a copy of the Web form StepByStep3_1.aspx and change its name to StepByStep3_11.aspx. Open the ASPX file and the CS file and change all occurrences of StepByStep3_1 with StepByStep3_11.
-
Switch to code view and add the following code above the existing code in the Page_Load() event handler:
-
Double-click the Post button control and add the following code in the Click event handler:
-
Add a new Web form to the project. Name the Web form StepByStep3_11a.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Label control, a TextBox control (txtName), and a Button control (btnSubmit) to the Web form.
-
Double-click the Submit button control and add the following code in the Click event handler:
-
Set StepByStep3_11.aspx as the start page in the project.
-
Run the project. You will see that you have been redirected to StepByStep3_11a.aspx. Enter a name and click the Submit button. You'll now see the StepByStep3_11.aspx page with a personalized greeting. Post a message. You should see that your name is now posted along with the title of the message (refer to Figure 3.9).
-
Close this browser window. Open another browser window and browse to StepByStep3_11.aspx. You should see that you have again been redirected to StepByStep3_11a.aspx to enter your name information.
private void Page_Load( object sender, System.EventArgs e) { if(Session["Name"] == null) { // The Name key is not present in the session // state, navigate to StepByStep3_11a page // to accept name of the user Response.Redirect("StepByStep3_11a.aspx"); } else { // The Name key is present in the session // state, display a greeting lblName.Text="Welcome " + Session["Name"].ToString(); } ... }
private void btnPost_Click(object sender, System.EventArgs e) { // Format the data entered by the user and // append it to the existing contents of lblWeblog lblWeblog.Text = "<b>" + ddlCategories.SelectedItem.Text + " :: " + txtTitle.Text + ":: by " + Session["Name"].ToString() + "</b> (" + DateTime.Now.ToString() + ")<hr>" + txtMessage.Text + "<p>" + lblWeblog.Text + "</p>"; }
private void btnSubmit_Click(object sender, System.EventArgs e) { // Add the Name entered in the Session // Redirect the response to the Weblog page Session["Name"] = txtName.Text; Response.Redirect("StepByStep3_11.aspx"); }
Step by Step 3.11 demonstrates that session state is not persistently stored like cookies. The default technique of passing SessionID is with non-persistent cookies, so this example only works if you are using a cookie-enabled browser. If you instead want to use a cookieless session, you'll have to modify the web.config file associated with this application to set the cookieless attribute to true in the <sessionState> element:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <sessionState mode="Inproc" cookieless="true" /> ... </system.Web> </configuration>
Application State
Application state is used to store data that is globally used throughout the application. The application state is stored in memory, and unlike the session state, application state can't be configured for storage on another server or a SQL database. This limits the usefulness of the application state for Web farm scenarios.
Application state can be easily accessed through the Application property of the Page class. This property provides access to the HttpApplicationState object that stores the application state as a collection of key-value pairs, where the key is a string type, and the value can be any type derived from System.Object. Tables 3.14 and 3.15 discuss properties and methods of the HttpApplicationState class, respectively.
Table 3.14 Properties of the HttpApplicationState Class
Property |
Description |
AllKeys |
Gets the collection of all key names in the application state as a string array. |
Contents |
Gets a reference to the application state (HttpApplicationState) object. This provides compatibility with ASP. |
Count |
Gets the number of objects in the application state. |
Keys |
Gets the NameObjectCollectionBase.KeysCollection collection of all the key names in the application state. |
StaticObjects |
Gets all objects declared via an <object runat="server" scope="Application"></object> tag within the ASP.NET application. |
Table 3.15 Methods of the HttpApplicationState Class
Property |
Description |
Add |
Adds a new object to the application state. |
Clear |
Removes all objects from the application state. |
Get |
Gets an object from the application state by key name or index. |
GetKey |
Gets a key from the application state by index. |
Lock |
Locks access to the application state object. This is used to prevent other clients from changing data stored in the application state. |
Remove |
Removes an object from the application state. |
RemoveAll |
Removes all the objects from the application state. Calls the Clear() method internally. |
RemoveAt |
Removes an object from the application state at a particular index. |
Set |
Updates the value of an object stored in the application state. |
Unlock |
Unlocks access to the application state. |
Step by Step 3.12 demonstrates the use of Application property to store the application-wide data.
STEP BY STEP
3.12 Using the Application State
-
Add a new Web form to the project. Name the Web form StepByStep3_12.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Switch to code view and add the following code in the Page_Load() event handler:
-
Set StepByStep3_12.aspx as the start page in the project.
-
Run the project. You should see that the page shows the number of times it has been accessed. Refresh the page, and you should see that the page access counter increments by 1 as shown in Figure 3.11.
-
Close this browser window. Open another browser window and browse to StepByStep3_12.aspx. You should see that the page retains the value of the counter and increments it by 1.
private void Page_Load( object sender, System.EventArgs e) { // Lock the Application as the // application state value needs to be modified Application.Lock(); if(Application["HitCount"] != null) { // Increment the HitCount variable // stored in the application state Application["HitCount"] = (int) Application["HitCount"] + 1; } else { Application["HitCount"] = 1; } // Unlock the application as the changes are done Application.UnLock(); // Display the hit count of this page by // fetching the value from the HitCount key // in the application state lblInfo.Text = "This page has been accessed (" + Application["HitCount"].ToString() + ") times!"; }
Figure 3.11 Application state allows you to store global information.
Note that the technique used in Step by Step 3.12 is a volatile way to store the hit count (that is, users only see the total number of hits since the last time the application started). If you want the hit count to persist across application restarts, you should store the hit count periodically to a database.
In Step by Step 3.12, I modified the contents of application state using a pair of Application.Lock() and Application.UnLock() methods. Locking is important for keeping application state consistent when multiple users might want to modify the application object's content concurrently. While the application is locked, only the current user will be able to change the contents of the application state. This locking mechanism can severely reduce the scalability of a Web application; therefore, you should usually not store any updatable data in the application state.
No Locking Needed for Application_Start() and Application_End()
There is no need to use the Application.Lock() and Application.Unlock() methods in the Application_Start() and Application_End() event handlers because these event handlers are only called just once during the lifetime of an application.
Later in this book in Chapter 15, you'll learn about an alternative way of maintaining global state for an application using the application data cache. In fact, the application data cache provides everything that application state offers and provides several other advanced features, such as cache expiration policy. I recommend using application state only when you are migrating ASP applications to ASP.NET and want to write minimal code. In all other cases and for all new ASP.NET applications, you should use the application data cache as your preferred choice for storing global data.
REVIEW BREAK
ASP.NET uses a hidden input control named __VIEWSTATE to maintain state for all non-postback controls that are modified in the code. When ASP.NET executes a page, it collects values for all these controls and formats them into a single base64-encoded string. This string is then stored in the __VIEWSTATE control.
You can use the ViewState property of the Page class to store page-level values. The ViewState property allows you to store structured data as long as the data is serializable.
View state is easily configurable. ASP.NET provides configuration schemes for disabling, tamper proofing, or protecting the contents of the view state.
ASP.NET provides session state to store session-specific data for each user. The session state can be scaled to support multiple Web servers in a Web farm with just minor configuration changes.
ASP.NET provide two ways to store the data that is globally used throughout the application. One is the Application state and the other is Application data cache. The application data cache provides all that application state offers and also provides several other advanced features, such as cache expiration policy.
Navigation Between Pages
Implement navigation for the user interface.
A typical Web application is a collection of Web pages linked to each other. In Chapter 2, I discussed the HyperLink control that allows a user to navigate to a different Web page when the hyperlink is clicked. However, there is also a need to navigate to a Web page programmatically. ASP.NET provides the following methods for programmatically navigating between pages:
Response.Redirect()
Server.Transfer()
Server.Execute()
I'll discuss each of these methods in the following sections.
The Response.Redirect() Method
The Response.Redirect() method causes the browser to connect to the specified URL. When the Response.Redirect() method is called, it creates a response whose header contains a 302 (Object Moved) status code and the target URL. When the browser receives this response from the server, it uses the header information to generate another request to the specified URL. When using the Response.Redirect() method, the redirection happens at the client side and involves two roundtrips to the server.
Using the Response.Redirect() method is recommended in the following cases:
You want to connect to a resource on ANY Web server.
You want to connect to a non-ASPX resource (such as an HTML file).
You want to pass query string as part of the URL.
The Server.Transfer() Method
The Server.Transfer() method transfers the execution from the current ASPX page to the specified ASPX page. The path specified to the ASPX page must be on the same Web server and must not contain a query string.
When the Server.Transfer() method is called from an executing ASPX page, the current ASPX page terminates execution and control is transferred to another ASPX page. The new ASPX page still uses the response stream created by the prior ASPX page. When this transfer occurs, the URL in the browser still shows the original page because the redirection occurs on the server side and the browser remains unaware of the transfer.
When you want to transfer control to an ASPX page residing on the same Web server, you should use Server.Transfer() instead of Response.Redirect() because Server.Transfer() will avoid an unnecessary roundtrip and provide better performance and user experience.
The default use of the Server.Transfer() method does not pass the form data and the query string of the original page request to the page receiving the transfer. However, you can preserve the form data and query string of the original page by passing a true value to the optional second argument, of the Server.Transfer() method. The second argument takes a Boolean value that indicates whether to preserve the form and query string collections.
When you set the second argument to true, you need to be aware of one thing: that the destination page contains the form and query string collections that were created by the original page. As a result, the hidden _VIEWSTATE field of the original page is also preserved in the form collection. The view state is page scoped and is valid for a particular page only. This causes the ASP.NET machine authentication check (MAC) to announce that the view state of the new page is tampered with. Therefore, when you choose to preserve the form and query string collections of the original page, you must set the EnableViewStateMac attribute of the Page directive to false for the destination page.
The Server.Execute() Method
The Server.Execute() method allows the current ASPX page to execute a specified ASPX page. The path to the specified ASPX page must be on the same Web server and must not contain a query string.
Bad HTML Code
The output returned to the browser by Server.Execute() and Server.Transfer() might contain multiple <html> and <body> tags because the response stream remains the same while executing another ASPX page. Therefore, the output that results from calling these methods might contain bad HTML code.
After the specified ASPX page is executed, control transfers back to the original page from which the Server.Execute() method was called. This technique of page navigation is analogous to making a method call to an ASPX page.
The called ASPX page has access to the form and query string collections of the calling page: Thus, for the reasons explained in the previous section, you need to set the EnableViewStateMac attribute of the Page directive to false on the called ASPX page.
By default, the output of the executed page is added to the current response stream. This method also has an overloaded version in which the output of the redirected page can be fetched in a TextWriter object instead of adding the output to the response stream. This helps you control where the output is placed on the original page.
STEP BY STEP
3.13 Using the Response.Redirect(), Server.Transfer(), and Server.Execute() Methods
-
Add a new Web form to the project. Name the Web form StepByStep3_13.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add three Label controls, a Literal control (litDynamic), two TextBox controls (txtRows, txtCells), and three Button controls (btnTransfer, btnExecute, and btnRedirect) to the Web form, as shown in Figure 3.12.
-
Double-click the three Button controls to add an event handler to the Click event of each button. Add the following code in their event handlers:
-
Add a new Web form to the project. Name the Web form StepByStep3_13a.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Table control (tblDynamic) from the Web Forms tab of the Toolbox to the Web form.
-
Switch to the HTML view of the StepByStep3_13a.aspx file and modify the Page directive to add the EnableViewStateMac="false" attribute:
-
Switch to code view and add the following method in the class definition:
-
Add the following code in the Page_Load() event handler:
-
Set StepByStep3_13.aspx as the start page in the project.
-
Run the project. Enter the number of rows and cells and click all three buttons one by one. When you click the Redirect button, the browser is redirected to StepByStep3_13a.aspx by passing the Rows and Cells values as the query string data as shown in Figure 3.13. When you click the Transfer button, the browser doesn't change the page name in the location bar, but the control gets transferred to the StepByStep3_13a.aspx page as shown in Figure 3.14. Finally, when you click the Execute button, the StepByStep3_13a.aspx page is executed and control comes back to the calling page, where the output of the Server.Execute() method is displayed as shown in Figure 3.15.
Figure 3.12 The design of a form that allows you to specify rows and columns to create a table dynamically.
private void btnRedirect_Click(object sender, System.EventArgs e) { // Calling Response.Redirect by passing // Rows and Cells values as query strings Response.Redirect("StepByStep3_13a.aspx?Rows=" + txtRows.Text + "&Cells=" + txtCells.Text); } private void btnTransfer_Click(object sender, System.EventArgs e) { // Writing into Response stream Response.Write( "The following table is generated " + "by StepByStep3_13a.aspx page:"); // Calling the Server.Transfer method // with the second argument set to true // to preserve the form and query string data Server.Transfer("StepByStep3_13a.aspx", true); // Control does not come back here } private void btnExecute_Click(object sender, System.EventArgs e) { // Creating a StringWriter object StringWriter sw = new StringWriter(); // Calling the Server.Execute method by // passing a StringWriter object Server.Execute("StepByStep3_13a.aspx", sw); // Control comes back // Displaying the output in the StringWriter // object in a Literal control litDynamic.Text = sw.ToString(); }
<%@ Page language="c#" Codebehind="StepByStep3_13a.aspx.cs" AutoEventWireup="false" Inherits="_315C03.StepByStep3_13a" EnableViewStateMac="false" %>
private void CreateTable(Int32 intRows, Int32 intCells) { // Create a new table TableRow trRow; TableCell tcCell; // Iterate for the specified number of rows for (int intRow=1; intRow <= intRows; intRow ++) { // Create a row trRow = new TableRow(); if(intRow % 2 == 0) { trRow.BackColor = Color.LightBlue; } // Iterate for the specified number of columns for (int intCell=1; intCell <= intCells; intCell++) { // Create a cell in the current row tcCell = new TableCell(); tcCell.Text = "Cell (" + intRow + "," + intCell + ")"; trRow.Cells.Add(tcCell); } // Add the row to the table tblDynamic.Rows.Add(trRow); } }
private void Page_Load( object sender, System.EventArgs e) { if(Request.Form["txtRows"] != null) { // If the request contains form data then the // page is called from the Server.Transfer or // Server.Execute methods from the // StepByStep3_13.aspx page. Get the Rows and // Cells values from the form collection and // Create a table. CreateTable( Int32.Parse(Request.Form["txtRows"]), Int32.Parse(Request.Form["txtCells"])); } else if(Request.QueryString["Rows"] != null) { // If the request contains query string data // that means the response is redirected from // the StepByStep3_14.aspx page. Get the Rows // and Cells value from the query string and // Create a table. Response.Write("StepByStep3_13a.aspx:"); CreateTable( Int32.Parse(Request.QueryString["Rows"]), Int32.Parse(Request.QueryString["Cells"])); } }
Figure 3.13 The Response.Redirect() method can be used to navigate to a URL that contains query strings.
Figure 3.14 The Server.Transfer() method is used to navigate to an ASPX page on the same server without causing an additional roundtrip.
Figure 3.15 The Server.Execute() method executes the specified ASPX page and returns the control back to the calling page.
In fact, it's a good idea to keep the second argument set to false when using the Server.Transfer() method. When you want to pass some values from one page to another in the current HTTP request, instead of using the form and query string collections, you should use the HttpContext object. The HttpContext object gives access to all the information about the current HTTP request. It exposes a key-value collection via the Items property in which you can add values that will be available for the life of the current request. The Page class contains a property called Context that provides access to the HttpContext object for the current request.
You can use two techniques to access the values of one page from another page in the current HTTP request using the HttpContext objectsHttpContext.Handler and HttpContext.Items. I have demonstrated these techniques in the Guided Practice Exercise 3.2 and in the Exercise 3.2, respectively.
Guided Practice Exercise 3.2
When using the Server.Transfer() method, for security reasons, you might not want to disable the machine authentication check for the view state of a page or for an application. How would you pass the state of one page to another in that case?
The Page class contains a property called Context that provides access to the HttpContext object for the current request. The Handler property of the HttpContext object provides the instance of the page that first received the HTTP request.
To use the HttpContext.Handler property in your code, you should take the following steps:
Expose the control values as public properties in the page that transfers the control.
In the target page, create an instance of the previous page's class.
Use the HttpContext.Handler property to retrieve the instance of the handler for the previous page. Initialize the object created in the preceding step with this value.
Use the instance of the previous page's class to access its properties.
In this exercise, you are required to modify Step by Step 3.13 to use the HttpContext.Handler property to retrieve the properties of the first page in the second page. How would you make this modification?
You should try working through this problem on your own first. If you are stuck, or if you'd like to see one possible solution, follow these steps:
-
Open the project 315C03. Add a new Web form GuidedPracticeExercise3_2 to the project. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add three Label controls, two TextBox controls (txtRows, txtCells), and one button control (btnTransfer) on the Web form.
-
Switch to the code view and add the following property definition in the class definition:
-
Double-click the Transfer button control and add the following code in the Click event handler:
-
Add a new Web form to the project. Name the Web form GuidedPracticeExercise3_2a.aspx. Change the pageLayout property of the DOCUMENT element to FlowLayout.
-
Add a Table control (tblDynamic) from the Web Forms tab of the Toolbox to the Web form.
-
Switch to code view and add the following code in the class definition to create an instance of the GuidedPracticeExercise3_2 page:
-
Add the following code in the Page_Load() event handler:
-
Switch to code view and add the following method in the class definition:
-
Set GuidedPracticeExercise3_2.aspx as the start page in the project.
-
Run the project. Enter the number of rows and cells and click the Transfer button. You should see that the browser doesn't changes the page name in the location bar, but the control gets transferred to the GuidedPracticeExercise3_2a.aspx page. The GuidedPracticeExercise3_2a.aspx page is able to access the Rows and Cells properties of the GuidedPracticeExercise3_2.aspx page via the HttpContext.Handler property.
// Declaring properties to expose // the number of Rows and Cells entered public Int32 Rows { get { return Int32.Parse(txtRows.Text); } } public Int32 Cells { get { return Int32.Parse(txtCells.Text); } }
private void btnTransfer_Click(object sender, System.EventArgs e) { // Writing into Response Response.Write( "The following table is generated " + "by GuidedPracticeExercise3_2a.aspx page:"); // Calling the Server.Transfer method Server.Transfer("GuidedPracticeExercise3_2a.aspx"); // Control does not come back here }
// Declare a variable to store an instance of // the GuidedPracticeExercise3_2 Web form public GuidedPracticeExercise3_2 pageExercise3_2;
private void Page_Load( object sender, System.EventArgs e) { if(!IsPostBack) { // Because its the same request context, // get the reference to the // GuidedPracticeExercise3_2 page // through the current request Context. // Get the Rows and Cells value from the // GuidedPracticeExercise3_2 Web form's // properties and Create a table. pageExercise3_2 = (GuidedPracticeExercise3_2) Context.Handler; CreateTable(pageExercise3_2.Rows, pageExercise3_2.Cells); } }
private void CreateTable(Int32 intRows, Int32 intCells) { // Create a new table TableRow trRow; TableCell tcCell; // Iterate for the specified number of rows for (int intRow=1; intRow <= intRows; intRow ++) { // Create a row trRow = new TableRow(); if(intRow % 2 == 0) { trRow.BackColor = Color.LightBlue; } // Iterate for the specified number of columns for (int intCell=1; intCell <= intCells; intCell++) { // Create a cell in the current row tcCell = new TableCell(); tcCell.Text = "Cell (" + intRow + "," + intCell + ")"; trRow.Cells.Add(tcCell); } // Add the row to the table tblDynamic.Rows.Add(trRow); } }
If you have difficulty following this exercise, review the section "Navigation between Pages" earlier in this chapter and perform Step by Step 3.13. After doing this review, try this exercise again.
REVIEW BREAK
The Response.Redirect() method can be used to redirect the browser to any specified URL. The specified URL can point to any resource and might also contain query strings. Use of Response.Redirect() method causes an additional roundtrip.
The Server.Transfer() method performs a server-side redirection of a page, avoiding extra roundtrip to the server. The Server.Transfer() method can only be used to redirect to an ASPX page residing on the same Web server. The URL to the redirected ASPX page cannot contain query strings, although you can preserve the form and query string collection of the main page to the redirected page by passing the true value to an optional second parameter.
The Server.Execute() method is like a method call to an ASPX page. This method executes the specified ASPX page and returns the execution to the calling ASPX page. The page specified as an argument to the Server.Execute() must be an ASPX page residing on the same Web server, and the argument should not contain query string data. The ASPX page to be executed contains access to the form and query string collections of the main page.
You should set the EnableViewStateMac attribute of the Page directive to false for the destination page; in case of calling the page via the Server.Execute() method or the Server.Transfer() method with the second argument, set it to true.
Chapter Summary
KEY TERMS
Postback
Roundtrip
ASP.NET Application
Application state
Query string
Cookies
Hidden fields
View state
Session state
In this chapter, you learned how to deal with the disconnected nature of Web applications using the state management techniques provided by ASP.NET. In addition to the traditional client-side state management techniques like query strings, cookies, and hidden variables, ASP.NET provides a new technique called view state. When used carefully, view state can give great benefits; however, careless use of view state can significantly increase the download size of the rendered HTML file.
You also learned about various server-side state management techniques. In particular, ASP.NET provides great improvements over the session state of ASP. Session state in ASP.NET is highly configurable. With small configuration changes, you can support Web farms and cookieless sessions.
I also discussed various ASP.NET intrinsic objects that can be accessed using the properties of the Page class, such as Request, Response, Session, Application, and Server. You experimented with several properties and methods of these objects throughout this chapter.
I also discussed the Response.Redirect(), Server.Transfer(), and Server.Execute() methods for implementing navigation from one page to another, as well as the advantages and limitations of each of these methods.
Apply Your Knowledge
Exercises
3.1 Using Session State to Create a Shopping Cart
Online stores often use session state to maintain information about a user's shopping cart. This allows the site to keep track of users' selections as they explore the store rather than requiring the users to add all the items at the same time.
In this exercise, you'll use a similar technique to manage a shopping cart. To keep the emphasis on session state, you'll keep the catalog smaller than you'll generally find at most stores.
Estimated time: 20 minutes
-
Create a new Visual C# ASP.NET Web Application project at the location http://localhost/315C03Exercises.
-
Add a Web form to the project. Name it ShoppingPage.aspx.
-
Add three Label controls, three Textbox controls (txtNK, txtCF, and txtHA) and three Button controls (btnNK, btnCF, and btnHA) in to the table on the Web form (see Figure 3.16).
-
Switch to code view and add the following code to add selected items and their quantities to the session:
-
Double-click the three button controls and add the following code to their Click event handlers:
-
Add a new Web form to the project. Name the Web form ShoppingCart.aspx.
-
Drag a Hyperlink control (hlShopping) to the Web form. Set its NavigateUrl property to ShoppingPage.aspx.
-
Switch to code view and add the following code in the Page_Load() event handler:
-
Set ShoppingPage.aspx as the start page in the project.
-
Run the project. You'll see a shopping page as shown in Figure 3.16. Enter a quantity for a product and click on the Add to Cart button. You'll be taken to the shopping cart as shown in Figure 3.17. Add a few more items to the cart; you'll note that the shopping cart remembers your selections.
// Add the selected item to // the session state private void AddToSession( String strProduct, int intQty) { if(Session[strProduct] != null) { // If the product already exists, // increase its quantity Session[strProduct] = (int) Session[strProduct] + intQty; } else { Session[strProduct] = intQty; } }
private void btnNK_Click( object sender, System.EventArgs e) { // Add the selected item // to the shopping cart AddToSession("NK", Int32.Parse( txtNK.Text)); // Display shopping cart Server.Transfer("ShoppingCart.aspx"); } private void btnCF_Click( object sender, System.EventArgs e) { // Add the selected item // to the shopping cart AddToSession("CF", Int32.Parse(txtCF.Text)); // Display shopping cart Server.Transfer("ShoppingCart.aspx"); } private void btnHA_Click( object sender, System.EventArgs e) { // Add the selected item // to the shopping cart AddToSession("HA", Int32.Parse(txtHA.Text)); // Display shopping cart Server.Transfer("ShoppingCart.aspx"); }
private void Page_Load( object sender, System.EventArgs e) { Response.Write( "The shopping cart contains" + " the following items: <br>"); // Display the contents of // the shopping cart for(int intI=0; intI < Session.Count; intI++) { switch (Session.Keys[intI]) { case "NK": Response.Write( "Nestle KitKat (" + Session[intI]+ ")" + "<br>"); break; case "CF": Response.Write( "Cadbury's Fingers (" + Session[intI]+ ")"+ "<br>"); break; case "HA": Response.Write( "Hersheys Almonds (" + Session[intI] + ")" + "<br>"); break; } } }
Figure 3.16 The Add to Cart button updates the session state with the corresponding item and its quantity.
Figure 3.17 The shopping cart page summarizes the user's selections by retrieving the information from the session state.
3.2 Creating a Wizard-like User Interface
When creating a wizard-like user interface, you need to access the information entered in one page from another page in the wizard.
When you use the Server.Transfer() method to navigate from one page to another, both the pages share the same HTTP context. From the first page, you can add items to the HTTP context and then retrieve these items in the second page.
The HttpContext object gives access to all the information about the current HTTP request. It exposes a key-value collection via the Items property in which you can add values that will be available for the life of the current request.
In this exercise, I'll show you how to use the Items property of the HttpContext object to retrieve values from previous page of a wizard.
Estimated time: 20 minutes
-
Add a Web form to the project. Name it Magazine1.aspx.
-
Drag two Label controls, a TextBox control (txtCode), and a Button control (btnCode) on the Web form. (see Figure 3.18).
-
Switch to the code view of the form. Add the following code in the class definition:
-
Double-click the Next button control and add the following code in the Click event handler:
-
Add another Web form to the project. Name it Magazine2.aspx.
-
Drag two Label controls, two TextBox controls (txtName and txtAddress), and a Button control (btnCode) to the Web form (see Figure 3.19).
-
Add the following code in the Page_Load() event handler:
-
Set Magazine1.aspx as the start page of the project.
-
Run the project. You will see the first page of the wizard as shown in Figure 3.18. Enter some text in the text box and click the Next button. You can see that the second page can retrieve the information entered in the first page of the wizard (see Figure 3.19) .
Figure 3.18 The first page of the wizard publishes its properties to the other page by adding it to a key-value collection via the HttpContext.Items property.
// Declaring Code property to expose // the txtCode control's value public String Code { get { return txtCode.Text; } }
private void btnNext_Click( object sender, System.EventArgs e) { // Adding the Code to the Items // collection of the HttpContext // object for the current request Context.Items.Add("Code", txtCode.Text); // Calling the Server.Transfer method Server.Transfer("Magazine2.aspx"); }
private void Page_Load( object sender, System.EventArgs e) { if(!IsPostBack) { // Fetch the Code value from the // HttpContext object of the // current request string strCode = Context.Items["Code"].ToString(); lblCode.Text = "Priority Code: " + strCode; } }
Figure 3.19 The second page of the wizard fetches the value of first page in the wizard through a key-value collection via the HttpContext.Items property.
Review Questions
-
What is a postback? How can you determine when a postback occurs in an ASP.NET page?
-
What file do you use to handle Session and Application level events?
-
What are the classes mapped to the Response, Request, Server, Application, and Session properties of the Page class?
-
What are the client-side techniques available for state management?
-
What are the benefits of using view state in ASP.NET?
-
What is the significance of setting the EnableViewStateMac property to true?
-
What is the difference between the client-side and the server-side state management techniques?
-
What type(s) of data can be stored in a session state and in an application state?
-
When would you store an object in the session state instead of the application state?
-
What methods can be called to perform server-side redirection to an ASPX page?
Exam Questions
-
You are developing a Web form to display weather information. On the initial requests to the Web form, you need to do some initialization that will change the appearance of the form and assign values to some controls. However, this initialization should not be repeated again when the user submits the Web form. How should you write the code to accomplish this? (Select two)
-
Write the code inside the Page_Init() event handler.
-
Write the code inside the Page_Load() event handler.
-
Execute the initialization code only when the Page.IsPostBack property is true.
-
Execute the initialization code only when the Page.IsPostBack property is false.
-
You have used ASP.NET to develop an inventory management system for your organization. Associates can access this application from the company's intranet. When analyzing users' feedback on the applications, you found that users complain that they receive an annoying flash when they submit forms. They also complain that the data entry form does not always remember the active controls and because of this, users have to press the Tab key several times before they can focus again on the desired control. This makes the data entry inconvenient and time- consuming. On analyzing further usage data, you found that all the users in your company use Internet Explorer 5.0 or above to access your application. What should you do to eliminate the problems reported by the users?
-
Set SmartNavigation attribute of the Page directive to true.
-
Set AutoEventWireup attribute of the Page directive to true.
-
Set EnableViewState attribute of the Page directive to true.
-
Set ClientTarget attribute of the Page directive to "ie5".
-
You are developing an ASP.NET Web site for a popular Web development magazine. You want to keep track of how many times each page of your Web application is accessed. This data will help your company to analyze the usage pattern and develop most appropriate content. You want to write minimum code to achieve this task; which of the following techniques will you use?
-
Use the Page_Load() event handler to increment the usage counter of the page.
-
Use the Application_BeginRequest() event handler to increment the usage counter of the page.
-
Use the Session_Start() event handler to increment the usage counter of the page.
-
Use the Application_Start() event handler to increment the usage counter of the page.
-
You are designing a Web application for a multinational company. When users access the Web site, you want them to be automatically redirected to a page specific to their country. Your colleague has developed a method that determines the user's country from the HTTP Request and does the redirection. Where should you call this method in your application?
-
The Session_Start() event handler of the global.asax file
-
The Begin_Request() event handler of the global.asax file
-
The Page_Load() event handler of the default.aspx file
-
The Application_Start() event handler of the global.asax file
-
Your ASP.NET page contains a page-level variable of ArrayList type. You want to preserve the value of this variable across page postbacks. You do not need this variable in any other page in the application. Which of the following state management techniques provides the best way to achieve this?
-
Query strings
-
Cookies
-
Session
-
View state
-
You are developing a Web application for an online bank. Your application allows users to access their account information and transactions right from their desktops. When the user logs on to your application, you want to show the username and current balance on all the pages of the application until the user logs off. You want your application to be safe from malicious users. Which of the following state management techniques should you use? (Select the best answer.)
-
Cookies
-
View state
-
View state with encryption
-
Session
-
You are developing an online retail store using ASP.NET. Users can freely access the catalogs and add items to their shopping carts. Users are only required to log on to the Web site when they are ready to check out. However, you want to remember each user's name and greet the users on their future visits to the retail store. Which of the following state management techniques helps you accomplish this? (Select the best answer.)
-
Hidden fields
-
View state
-
Cookies
-
Session
-
You have developed and deployed a Web application for an online bank. This application allows users to access their account information and transactions right from their desktops. Because the application deals with financial data, you have enabled encryption for the view state of all the pages. The bank business has rapidly increased, and the management has decided to upgrade the single Web server to a Web farm of Web servers. When you were testing the application for the Web farm, sometimes the application worked fine while other times it generated a view state error. What should you do to resolve this problem?
-
Use the same validation key for all the Web servers in a Web farm.
-
Use different validation keys for all the Web servers in a Web farm.
-
Set the EnableViewStateMac attribute to true for all the pages in the application.
-
Set the EnableViewStateMac attribute to false for all the pages in the application.
-
You have recently developed and deployed a Web application for a large automotive parts supplier. This application is used by users from the United States, Europe, and Asia. You have received complaints from several users that the Web pages take very long to download. You did some research and found out that an HTML element named __VIEWSTATE in your pages is storing a large amount of data and is responsible for bigger page sizes. Your manager recommended that you to disable view state wherever it is not needed in the application. In which of the following cases would you like to disable view state in your application? (Select all that apply)
-
Those pages that do not postback.
-
Those pages that postback.
-
Those controls that are not dynamically changed.
-
Those controls that are dynamically changed.
-
Those controls that are modified at every page load.
-
Those controls that are not modified at every page load.
-
You have recently developed and deployed a Web application for a large automotive parts supplier. This application is used by users from the United States, Europe, and Asia. You have received complaints from several users that the Web pages take very long to download. You did some research and found that an HTML element named __VIEWSTATE in your pages is storing a large amount of data and is responsible for bigger page sizes. You have also found that some of your pages do not use view state. You want to do minimum modification to the code. How would you disable view state for such pages?
-
Set the EnableViewState property for all the Web server controls to false.
-
Set the EnableViewState attribute of the Page directive to false.
-
Set the EnableViewStateMac attribute of the Page directive to false.
-
Set the EnableViewState attribute to false for the <Pages> element in the web.config file.
-
In a Web page of your application, you allow users to select a product and its quantity. When the user has made her selection, you want to transfer the user to another page named "ShoppingCart.aspx" with the ProductId and Quantity as the query string parameters to the ASPX page. Which of the following methods would you use in your code to accomplish this?
-
A HyperLink control
-
The Response.Redirect() method
-
The Server.Transfer() method
-
The Server.Execute() method
-
You are using a DataGrid control in a Web form "ShowData.aspx" of your Web application. You want to invoke another ASP.NET page, "GetData.aspx," that returns the data to be displayed in the DataGrid control. Which of the following methods would you use to invoke "GetData.aspx" from "ShowData.aspx"?
-
A HyperLink control
-
The Response.Redirect() method
-
The Server.Transfer() method
-
The Server.Execute() method
-
You are developing an online bill payment system using ASP.NET. When a user logs on to the application by entering her username and password, you want to programmatically redirect the user to a page named "accountdetails.aspx" in the same Web application. You want an application that responds quickly to the users. Which of the following methods would you use to accomplish this?
-
A HyperLink control
-
The Response.Redirect() method
-
The Server.Transfer() method
-
The Server.Execute() method
-
You are using a DataGrid control in an ASP.NET page ("ShowData.aspx") of your Web application. You want to invoke another ASP.NET page, "GetData.aspx," that returns the data to be displayed in the DataGrid control. You are using the Server.Execute() method to invoke "GetData.aspx" from the "ShowData.aspx" page. When you run the application, you get an Invalid View state error. Which of the following options would you choose to resolve this error?
-
Use the Server.Transfer() method instead of the Server.Execute() method.
-
Set the EnableViewStateMac attribute to false in the Page directive of "GetData.aspx."
-
Set the EnableViewStateMac attribute to false in the Page directive of "ShowData.aspx."
-
Set the EnableViewState attribute to false in the Page directive of "GetData.aspx."
-
You are creating a Web site that allows users to create online communities to interact with their friends and families. The creation of a community requires the user to register with the Web site. You have created a User Registration Wizard that allows users to enter registration information in a step by step manner. The Wizard consists of two ASPX pages. You want all the data entered by the user in the first ASPX page to be available in the second page. For security reasons, you are not allowed to disable the view state machine authentication check in your ASP.NET pages. Which of the following options would you use? (Select two)
-
For each screen, add the collected data to the Context.Items collection and retrieve the information from this collection in the last ASPX page.
-
Use the Request.Form collection in the last ASPX page to retrieve the information entered by the user.
-
Use the Server.Transfer() method to transfer the control from one wizard page to the next wizard page.
-
Use the Server.Execute() method to transfer the control from one wizard page to the next wizard page.
Answers to Review Questions
-
When a user submits the form to the Web server, it is called as a postback. The Page.IsPostBack property, when true, indicates that the page is loaded as a result of postback from the client.
-
The ASP.NET application file, global.asax, contains event handlers to handle Session and Application level events.
-
The classes that map to the Response, Request, Server, Application, and Session properties of the Page class are HttpResponse, HttpRequest, HttpServerUtility, HttpApplicationState, and HttpSessionState, respectively.
-
You can use query strings, cookies, hidden fields, and view state for managing state at the client side.
-
View state provides the following benefits:
-
It maintains the state of non-postback controls in a page across page postbacks.
-
You can store any object in the view state as long as it is serializable.
-
You can customize view state to enable protection and encryption.
-
The EnableViewStateMac property, when set to true, performs a machine authentication check (MAC) on the view state during postback to verify that the view state has not been tampered with at the client side.
-
The client-side state management techniques consume client resources to manage state, whereas the server-side techniques consume server resources to manage state.
-
Any object that inherits from System.Object, directly or indirectly by chain of its inheritance, can be stored in session state and application state.
-
When you need to store data that does not apply to all the users of the application but only to specific users, you should choose session state instead of the application state.
-
Server.Transfer() and Server.Execute() methods can perform server-side redirection to an ASPX page.
Answers to Exam Questions
-
B and D. The code for the initialization of controls should be placed inside the Page_Load() event handler. If you want to execute the initialization code only when the page is first requested and do not want to run that code again at the time of page postback, you must execute the code when the IsPostBack property of the Page class is false. For more information, see the section "The IsPostBack Property" in this chapter.
-
A. When all users are using Internet Explorer versions 5.0 or later, you can set the SmartNavigation property to true. This will eliminate the flash and will cause Internet Explorer to focus active control. For more information, see the section "The SmartNavigation Property" in this chapter.
-
B. Options C and D do not work with each page request, so only options A and B are viable choices. Between these two choices, you should choose to write the code in the Application_BeginRequest() event handler of the global.asax file because if you use the Page_Load() event handler, you'll have to write code in each and every ASPX page in the application. For more information, see the section "ASP.NET Application" in this chapter.
-
A. When a user visits the site, the browser establishes a new session with the Web server. At that time, the Session_Start() event handler is executed. This method is executed only once for the user session and is an appropriate choice for the case in question. Page_Load() event handler might not work in all cases because the user could enter the Web site through a page other than default.aspx. Begin_Request() works for the entire HTTP request and not just the first request. The Application_Start() method will only redirect the first user of the application. For more information, see the section "ASP.NET Application" in this chapter.
-
D. Because the variable is only required on a single page, you might not want to consume server resources by storing the values in session. You can instead use a client-side technique for state management, but cookies and hidden fields do not allow you to stored structured data. Therefore, the best option is to use view state. For more information, see the section "State Management" in this chapter.
-
D. Cookies can be easily accessed and used by malicious users. View state with encryption does provide a high level of encryption but is only available on the same page. In the application, you want the name and current balance to be displayed on all the pages, so the correct choice is session. Session data is stored at the server side and cannot be easily tampered with. For more information, see the section "State Management" in this chapter.
-
C. You want the information to be available across browser restarts. In this case, cookies are the right choice because they allow you to store a small amount of information on the user's computer. For more information, see the section "Client-side Techniques for State Management" in this chapter.
-
A. When you use view state encryption in a Web farm, you must use the same validation key for all the Web servers. If the validation keys don't match, you will get an error when the user is directed to a different server in the Web farm. For more information, see the section "View State" in this chapter.
-
A, C, and E. If the pages don't postback to themselves, they are not making use of view state; in that case, it's a good idea to disable view state for the whole page. For all other pages, the controls that are not dynamically changed need not have their view state enabled. Also, the controls whose values are modified on every page load need not store their values in the view state. For more information, see the section "View State" in this chapter.
-
B. Setting the EnableViewState property for all the Web server controls to false does the trick but involves a lot of coding. An option that requires less code is to set the EnableViewState attribute of the Page directive to false. Changing EnableViewState to false in the web.config file will affect all the pages in the Web applicationnot just the one that uses view stateand is not recommended in the given case. For more information, see the section "View State" in this chapter.
-
B. You cannot use query strings with the Server.Transfer() and Server.Execute() methods. The Hyperlink control does accept query strings, but the redirection needs to be performed within code. Therefore, the only choice that works is the use of Response.Redirect() method. For more information, see the section "Navigation Between Pages" in this chapter.
-
D. Only the Server.Execute() method works like a method call. That is, it invokes the specified page and returns the control back to the original page. For more information, see the section "The Server.Execute() Method" in this chapter.
-
C. Response.Redirect() involves an additional roundtrip and therefore is not a good option when you want the application to be faster. You should instead use the Server.Transfer() method to redirect your user to another ASPX page on the same Web server. For more information, see the section "The Server.Transfer() Method" in this chapter.
-
B. You get an error while executing the Server.Execute() method because the view state of the "ShowData.aspx" page is passed to the "GetData.aspx" page along with the form and query string collections, causing the ASP.NET machine authentication check to fail. You need to set the EnableViewState attribute of the Page directive in the "GetData.aspx" page to false in order to resolve this error. For more information, see the section "Navigation Between Pages" in this chapter.
-
A and C. You should choose Server.Transfer() and Context.Items to accumulate data from the previous page over the Server.Execute() and Request.Form methods because you cannot disable the view state machine authentication check and thus cannot preserve the form data. For more information, see the section "Navigation Between Pages" in this chapter.
Suggested Readings and Resources
-
The Visual Studio .NET Combined Help Collection, including the following:
-
Introduction to Web Forms State Management
-
Web Forms Page Processing
-
ASP.NET/Visual Studio .NET Tips. http://www.swarren.net
-
Fritz Onion. Essential ASP.NET. Addison-Wesley, 2002
-
Jeff Prosise. Programming Microsoft .NET. Microsoft Press, 2002