text: Originally, critics accused the Internet and e-business of failing to provide the kind of customized service typically experienced in "brick-and-mortar" stores. To address this problem, e-businesses began to establish mechanisms by which they could personalize users' browsing experiences, tailoring content to individual users while enabling them to bypass irrelevant information. Businesses achieve this level of service by tracking each customer's movement through the Internet and combining the collected data with information provided by the consumer, including billing information, personal preferences, interests and hobbies.
  Personalization
  Personalization makes it possible for e-businesses to communicate effectively with their customers and also improves users' ability to locate desired products and services. Companies that provide content of particular interest to users can establish relationships with customers and build on those relationships over time. Furthermore, by targeting consumers with personal offers, recommendations, advertisements, promotions and services, e-businesses create customer loyalty. Web sites can use sophisticated technology to allow visitors to customize home pages to suit their individual needs and preferences. Similarly, online shopping sites often store personal information for customers, tailoring notifications and special offers to their interests. Such services encourage customers to visit sites more frequently and make purchases more regularly.
  Privacy
  A trade-off exists, however, between personalized e-business service and protection of privacy. Some consumers embrace the idea of tailored content, but others fear the possible adverse consequences if the info they provide to e-businesses is released or collected by tracking technologies. Consumers and privacy advocates ask: What if the e-business to which we give personal data sells or gives that information to another organization without our knowledge? What if we do not want our actions on the Interneta supposedly anonymous mediumto be tracked and recorded by unknown parties? What if unauthorized parties gain access to sensitive private data, such as credit-card numbers or medical history? All of these are questions that must be debated and addressed by programmers, consumers, e-businesses and lawmakers alike.
  Recognizing Clients
  To provide personalized services to consumers, e-businesses must be able to recognize clients when they request information from a site. As we have discussed, the request/response system on which the Web operates is facilitated by HTTP. Unfortunately, HTTP is a stateless protocolit does not support persistent connections that would enable Web servers to maintain state information regarding particular clients. This means that Web servers cannot determine whether a request comes from a particular client or whether the same or different clients generate a series of requests. To circumvent this problem, sites can provide mechanisms by which they identify individual clients. A session represents a unique client on a Web site. If the client leaves a site and then returns later, the client will still be recognized as the same user. To help the server distinguish among clients, each client must identify itself to the server. Tracking individual clients, known as session tracking, can be achieved in a number of ways. One popular technique uses cookies (Section 21.6.1); another uses ASP.NET's HttpSessionState object (Section 21.6.2). Additional sessiontracking techniques include the use of input form elements of type "hidden" and URL rewriting. Using "hidden" form elements, a Web Form can write session-tracking data into a form in the Web page that it returns to the client in response to a prior request. When the user submits the form in the new Web page, all the form data, including the "hidden" fields, is sent to the form handler on the Web server. When a Web site performs URL rewriting, the Web Form embeds session-tracking information directly in the URLs of hyperlinks that the user clicks to send subsequent requests to the Web server.
  Note that our previous examples set the Web Form's EnableSessionState property to False. However, because we wish to use session tracking in the following examples, we keep this property's default settingtrue.
  21.6.1. Cookies
  Cookies provide Web developers with a tool for personalizing Web pages. A cookie is a piece of data stored in a small text file on the user's computer. A cookie maintains information about the client during and between browser sessions. The first time a user visits the Web site, the user's computer might receive a cookie; this cookie is then reactivated each time the user revisits that site. The collected information is intended to be an anonymous record containing data that is used to personalize the user's future visits to the site. For example, cookies in a shopping application might store unique identifiers for users. When a user adds items to an online shopping cart or performs another task resulting in a request to the Web server, the server receives a cookie containing the user's unique identifier. The server then uses the unique identifier to locate the shopping cart and perform any necessary processing.
  In addition to identifying users, cookies also can indicate clients' shopping preferences. When a Web Form receives a request from a client, the Web Form can examine the cookie(s) it sent to the client during previous communications, identify the client's preferences and immediately display products of interest to the client.
  Every HTTP-based interaction between a client and a server includes a header containing information either about the request (when the communication is from the client to the server) or about the response (when the communication is from the server to the client). When a Web Form receives a request, the header includes information such as the request type (e.g., Get) and any cookies that have been sent previously from the server to be stored on the client machine. When the server formulates its response, the header information contains any cookies the server wants to store on the client computer and other information, such as the MIME type of the response.
  The expiration date of a cookie determines how long the cookie remains on the client's computer. If you do not set an expiration date for a cookie, the Web browser maintains the cookie for the duration of the browsing session. Otherwise, the Web browser maintains the cookie until the expiration date occurs. When the browser requests a resource from a Web server, cookies previously sent to the client by that Web server are returned to the Web server as part of the request formulated by the browser. Cookies are deleted when they expire.
  Using Cookies to Provide Book Recommendations
  The next Web application demonstrates the use of cookies. The example contains two pages. In the first page (Figs. 21.2321.24), users select a favorite programming language from a group of radio buttons and submit the XHTML form to the Web server for processing. The Web server responds by creating a cookie that stores a record of the chosen language, as well as the ISBN number for a book on that topic. The server then returns an XHTML document to the browser, allowing the user either to select another favorite programming language or to view the second page in our application (Figs. 21.25 and 21.26), which lists recommended books pertaining to the programming language that the user selected previously. When the user clicks the hyperlink, the cookies previously stored on the client are read and used to form the list of book recommendations.
  Figure 21.23. ASPX file that presents a list of programming languages.
  Figure 21.24. Code-behind file that writes a cookie to the client.
  (This item is displayed on pages 1097 - 1099 in the print version)
  Figure 21.25. ASPX file that displays book recommendations based on cookies.
  (This item is displayed on pages 1099 - 1100 in the print version)
  Figure 21.26. Reading cookies from a client to determine book recommendations.
  (This item is displayed on page 1101 in the print version)
  The ASPX file in Fig. 21.23 contains five radio buttons (lines 2127) with the values Visual Basic 2005, Visual C# 2005, C, C++, and Java. Recall that you can set the values of radio buttons via the ListItem Collection Editor, which is opened either by clicking the RadioButtonList's Items property in the Properties window or by clicking the Edit Items... link in the RadioButtonList Tasks smart tag menu. The user selects a programming language by clicking one of the radio buttons. The page contains a Submit button, which when clicked, creates a cookie containing a record of the selected language. Once created, this cookie is added to the HTTP response header, and a postback occurs. Each time the user chooses a language and clicks Submit, a cookie is written to the client.
  When the postback occurs, certain controls are hidden and others are displayed. The Label, RadioButtonList and Button used to select a language are hidden. Toward the bottom of the page, a Label and two HyperLinks are displayed. One link requests this page (lines 3638), and the other requests Recommendations.aspx (lines 4143). Notice that clicking the first hyperlink (the one that requests the current page) does not cause a postback to occur. The file Options.aspx is specified in the NavigateUrl property of the hyperlink. When the hyperlink is clicked, this page is requested as a completely new request. Recall that earlier in the chapter, we set NavigateUrl to a remote Web site (). To set this property to a page within the same ASP.NET application, click the ellipsis button next to the NavigateUrl property in the Properties window to open the Select URL dialog. Use this dialog to select a page within your project as the destination for the HyperLink.
  Adding and Linking to a New Web Form
  Setting the NavigateUrl property to a page in the current application requires that the destination page exist already. Thus, to set the NavigateUrl property of the second link (the one that requests the page with book recommendations) to Recommendations.aspx, you must first create this file by right clicking the project location in the Solution Explorer and selecting Add New Item... from the menu that appears. In the Add New Item dialog, select Web Form from the Templates pane and change the name of the file to Recommendations.aspx. Finally, check the box labeled Place code in separate file to indicate that the IDE should create a code-behind file for this ASPX file. Click Add to create the file. (We discuss the contents of this ASPX file and code-behind file shortly.) Once the Recommendations.aspx file exists, you can select it as the NavigateUrl value for a HyperLink in the Select URL dialog.
  Writing Cookies in a Code-Behind File
  Figure 21.24 presents the code-behind file for Options.aspx (Fig. 21.23). This file contains the code that writes a cookie to the client machine when the user selects a programming language. The code-behind file also modifies the appearance of the page in response to a postback.
  Lines 1617 create books as a Hashtable (namespace System.Collections)a data structure that stores keyvalue pairs. A program uses the key to store and retrieve the associated value in the Hashtable. In this example, the keys are strings containing the programming languages' names, and the values are strings containing the ISBN numbers for the recommended books. Class Hashtable provides method Add, which takes as arguments a key and a value. A value that is added via method Add is placed in the Hashtable at a location determined by the key. The value for a specific Hashtable enTRy can be determined by indexing the Hashtable with that value's key. The expression
  HashtableName[ keyName ]
  returns the value in the keyvalue pair in which keyName is the key. For example, the expression books[ language ] in line 64 returns the value that corresponds to the key contained in language. Class Hashtable is discussed in detail in Chapter 25, Data Structures.
  Clicking the Submit button creates a cookie if a language is selected and causes a postback to occur. In the submitButton_Click event handler (lines 5672), a new cookie object (of type HttpCookie) is created to store the language and its corresponding ISBN number (line 67). This cookie is then Added to the Cookies collection sent as part of the HTTP response header (line 70). The postback causes the condition in the if statement of Page_Load (line 33) to evaluate to true, and lines 3751 execute. Lines 3739 reveal the initially hidden controls responseLabel, languageLink and recommendationsLink. Lines 4244 hide the controls used to obtain the user's language selection. Line 47 determines whether the user selected a language. If so, that language is displayed in responseLabel (lines 4849). Otherwise, text indicating that a language was not selected is displayed in responseLabel (line 51).
  Displaying Book Recommendations Based on Cookie Values
  After the postback of Options.aspx, the user may request a book recommendation. The book recommendation hyperlink forwards the user to Recommendations.aspx (Fig. 21.25) to display the recommendations based on the user's language selections.
  Recommendations.aspx contains a Label (lines 1619), a ListBox (lines 2122) and a HyperLink (lines 2427). The Label displays the text Recommendations if the user has selected one or more languages; otherwise, it displays No Recommendations. The ListBox displays the recommendations created by the code-behind file, which is shown in Fig. 21.26. The HyperLink allows the user to return to Options.aspx to select additional languages.
  Code-Behind File That Creates Book Recommendations From Cookies
  In the code-behind file Recommendations.aspx.cs (Fig. 21.26), method Page_Init (lines 1740) retrieves the cookies from the client, using the Request object's Cookies property (line 20). This returns a collection of type HttpCookieCollection, containing cookies that have previously been written to the client. Cookies can be read by an application only if they were created in the domain in which the application is runninga Web server can never access cookies created outside the domain associated with that server. For example, a cookie created by a Web server in the deitel.com domain cannot be read by a Web server in any other domain.
  Line 23 determines whether at least one cookie exists. Lines 2527 add the information in the cookie(s) to the booksListBox. The for statement retrieves the name and value of each cookie using i, the statement's control variable, to determine the current value in the cookie collection. The Name and Value properties of class HttpCookie, which contain the language and corresponding ISBN, respectively, are concatenated with " Howto Program. ISBN# " and added to the ListBox. Lines 3338 execute if no language was selected. We summarize some commonly used HttpCookie properties in Fig. 21.27.
  21.6.2. Session Tracking with HttpSessionState
  C# provides session-tracking capabilities in the Framework Class Library's HttpSessionState class. To demonstrate basic session-tracking techniques, we modified Fig. 21.26 so that it uses HttpSessionState objects. Figure 21.28 presents the ASPX file, and Fig. 21.29 presents the code-behind file. The ASPX file is similar to that presented in Fig. 21.23, except Fig. 21.28 contains two additional Labels (lines 3536 and lines 3839), which we discuss shortly.
  Figure 21.28. ASPX file that presents a list of programming languages.
  (This item is displayed on pages 1103 - 1105 in the print version)
  Every Web Form includes an HttpSessionState object, which is accessible through property Session of class Page. Throughout this section, we use property Session to manipulate our page's HttpSessionState object. When the Web page is requested, an HttpSessionState object is created and assigned to the Page's Session property. As a result, we often refer to property Session as the Session object.
  Adding Session Items
  When the user presses Submit on the Web Form, submitButton_Click is invoked in the code-behind file (Fig. 21.29). Method submitButton_Click responds by adding a keyvalue pair to our Session object, specifying the language chosen and the ISBN number for a book on that language. These keyvalue pairs are often referred to as session items. Next, a postback occurs. Each time the user clicks Submit, submitButton_Click adds a new session item to the HttpSessionState object. Because much of this example is identical to the last example, we concentrate on the new features.
  Figure 21.29. Creates a session item for each programming language selected by the user on the ASPX page.
  Like a cookie, an HttpSessionState object can store namevalue pairs. These session items are placed in an HttpSessionState object by calling method Add. Line 74 calls Add to place the language and its corresponding recommended book's ISBN number in the HttpSessionState object. If the application calls method Add to add an attribute that has the same name as an attribute previously stored in a session, the object associated with that attribute is replaced.
  The application handles the postback event (lines 3360) in method Page_Load. Here, we retrieve information about the current client's session from the Session object's properties and display this information in the Web page. The ASP.NET application contains information about the HttpSessionState object for the current client. Property SessionID (line 56) contains the unique session IDa sequence of random letters and numbers. The first time a client connects to the Web server, a unique session ID is created for that client. When the client makes additional requests, the client's session ID is compared with the session IDs stored in the Web server's memory to retrieve the HttpSessionState object for that client. Property Timeout (line 59) specifies the maximum amount of time that an HttpSessionState object can be inactive before it is discarded. Figure 21.30 lists some common HttpSessionState properties.
  Displaying Recommendations Based on Session Values
  As in the cookies example, this application provides a link to Recommendations.aspx (Fig. 21.31), which displays a list of book recommendations based on the user's language selections. Lines 2122 define a ListBox Web control that is used to present the recommendations to the user.
  Figure 21.31. Session-based book recommendations displayed in a ListBox.
  Code-Behind File That Creates Book Recommendations from a Session
  Figure 21.32 presents the code-behind file for Recommendations.aspx. Event handler Page_Init (lines 1747) retrieves the session information. If a user has not selected a language on Options.aspx, our Session object's Count property will be 0. This property provides the number of session items contained in a Session object. If Session object's Count property is 0 (i.e., no language was selected), then we display the text No Recommendations and update the Text of the HyperLink back to Options.aspx.
  Figure 21.32. Session data used to provide book recommendations to the user.
  If the user has chosen a language, the for statement (lines 2534) iterates through our Session object's session items, temporarily storing each key name (line 27). The value in a keyvalue pair is retrieved from the Session object by indexing the Session object with the key name, using the same process by which we retrieved a value from our Hashtable in the preceding section.
  Line 27 accesses the Keys property of class HttpSessionState, which returns a collection containing all the keys in the session. Line 27 indexes this collection to retrieve the current key. Lines 3133 concatenate keyName's value to the string " Howto Program. ISBN#: " and the value from the Session object for which keyName is the key. This string is the recommendation that appears in the ListBox.