
Pro CSharp And The .NET 2.0 Platform (2005) [eng]
.pdf
904 CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS
Figure 24-4. The cache application GUI
In the page’s Load event handler, configure your GridView to display the current contents of the cached DataSet the first time the user posts to the page:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
carsGridView.DataSource = (DataSet)Cache["AppDataSet"]; carsGridView.DataBind();
}
}
In the Click event handler of the Add this Car button, insert the new record into the Cars database using an ADO.NET SqlCommand object. Once the record has been inserted, call a helper function named RefreshGrid(), which will update the UI via an ADO.NET SqlDataReader (so don’t forget to “use” the System.Data.SqlClient namespace). Here are the methods in question:
protected void btnAddCar_Click(object sender, EventArgs e)
{
//Update the Inventory table
//and call RefreshGrid().
SqlConnection cn = new SqlConnection(); cn.ConnectionString =
"User ID=sa;Pwd=;Initial Catalog=Cars;" + "Data Source=(local)";
cn.Open(); string sql; SqlCommand cmd;


906 CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS
Maintaining Session Data
So much for our examination of application-level state data. Next, let’s check out the role of peruser data stores. As mentioned earlier, a session is little more than a given user’s interaction with a web application, which is represented via the HttpSessionState type. To maintain stateful infor-
mation for a particular user, the HttpApplication-derived type and any System.Web.UI.Page-derived types may access the Session property. The classic example of the need to maintain per-user data would be an online shopping cart. Again, if ten people all log on to an online store, each individual will maintain a unique set of items that she (may) intend to purchase.
When a new user logs on to your web application, the .NET runtime will automatically assign the user a unique session ID, which is used to identify the user in question. Each session ID is assigned a custom instance of the HttpSessionState type to hold on to user-specific data. Inserting or retrieving session data is syntactically identical to manipulating application data, for example:
// Add/retrieve a session variable for current user.
Session["DesiredCarColor"] = "Green";
string color = (string) Session["DesiredCarColor"];
The HttpApplication-derived type allows you to intercept the beginning and end of a session via the Session_Start() and Session_End() event handlers. Within Session_Start(), you can freely create any per-user data items, while Session_End() allows you to perform any work you may need to do when the user’s session has terminated:
<%@ Application Language="C#" %> <script runat="server">
...
void Session_Start(Object sender, EventArgs e)
{
}
void Session_End(Object sender, EventArgs e)
{
}
</script>
Like the HttpApplicationState type, the HttpSessionState may hold any System.Object-derived type, including your custom classes. For example, assume you have a new web application (SessionState) that defines a helper class named UserShoppingCart:
public class UserShoppingCart
{
public string desiredCar; public string desiredCarColor; public float downPayment; public bool isLeasing;
public DateTime dateOfPickUp;
public override string ToString()
{
return string.Format
("Car: {0}<br>Color: {1}<br>$ Down: {2}<br>Lease: {3}<br>Pick-up Date: {4}", desiredCar, desiredCarColor, downPayment, isLeasing, dateOfPickUp.ToShortDateString());
}
}
Within the Session_Start() event handler, you can now assign each user a new instance of the
UserShoppingCart class:

CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS |
907 |
void Session_Start(Object sender, EventArgs e)
{
Session["UserShoppingCartInfo"] = new UserShoppingCart();
}
As the user traverses your web pages, you are able to pluck out the UserShoppingCart instance and fill the fields with user-specific data. For example, assume you have a simple *.aspx page that defines a set of input widgets that correspond to each field of the UserShoppingCart type and a Button used to set the values (see Figure 24-5).
Figure 24-5. The session application GUI
The server-side Click event handler is straightforward (scrape out values from TextBoxes and display the shopping cart data on a Label type):
protected void btnSubmit_Click(object sender, EventArgs e)
{
// Set current user prefs.
UserShoppingCart u = (UserShoppingCart)Session["UserShoppingCartInfo"];
u.dateOfPickUp = myCalendar.SelectedDate; u.desiredCar = txtCarMake.Text; u.desiredCarColor = txtCarColor.Text;



910 CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS
The System.Web.HttpCookie type is the class that represents the server side of the cookie data (persistent or temporary). When you wish to create a new cookie, you access the Response.Cookies property. Once the new HttpCookie is inserted into the internal collection, the name/value pairs flow back to the browser within the HTTP header.
To check out cookie behavior firsthand, create a new ASP.NET web application (CookieStateApp) and create the UI displayed in Figure 24-7.
Figure 24-7. The UI of CookiesStateApp
Within the Button’s Click event handler, build a new HttpCookie and insert it into the Cookie collection exposed from the HttpRequest.Cookies property. Be very aware that the data will not persist itself to the user’s hard drive unless you explicitly set an expiration date using the HttpCookie.Expires property. Thus, the following implementation will create a temporary cookie that is destroyed when the user shuts down the browser:
protected void btnInsertCookie_Click(object sender, System.EventArgs e)
{
// Make a new (temp) cookie.
HttpCookie theCookie =
new HttpCookie(txtCookieName.Text, txtCookieValue.Text);
Response.Cookies.Add(theCookie);
}
However, the following generates a persistent cookie that will expire on March 24, 2009:
private void btnInsertCookie_Click(object sender, EventArgs e)
{
// Make a new (persistent) cookie.
HttpCookie theCookie =
new HttpCookie(txtCookieName.Text, txtCookieValue.Text);
theCookie.Expires = DateTime.Parse("03/24/2009"); Response.Cookies.Add(theCookie);
}
If you were to run this application and insert some cookie data, the browser automatically persists this data to disk. When you open this text file, you will see something similar to Figure 24-8.


912 CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS
At this point in the chapter, you have examined numerous ways to remember information about your users. As you have seen, view state and application, cache, session, and cookie data are manipulated in more or less the same way (via a class indexer). As you have also seen, the HttpApplication type is often used to intercept and respond to events that occur during your web application’s lifetime. Next up: the role of the Web.config file.
■Source Code The CookieStateApp files are included under the Chapter 24 subdirectory.
Configuring Your ASP.NET Web Application Using
Web.config
During your examination of .NET assemblies, you learned that client applications can leverage an XML-based configuration file to instruct the CLR how it should handle binding requests, assembly probing, and other runtime details. The same holds true for ASP.NET web applications, with the notable exception that web-centric configuration files (introduced in Chapter 23) are always named Web.config (unlike *.exe configuration files, which are named based on the related client executable).
When you insert a Web.config file to your site using the WebSite Add New Item menu option, the default structure looks something like the following (comments removed for clarity):
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0"> <appSettings/>
<connectionStrings/>
<system.web>
<compilation debug="false"/> <authentication mode="Windows"/>
</system.web>
</configuration>
Like any *.config file, Web.config defines the root-level <configuration> element. Nested within the root is the <system.web> element, which can contain numerous subelements used to control how your web application should behave at runtime. Under ASP.NET, the Web.config file can be modified using any text editor. Table 24-4 outlines some of the subelements that can be found within a Web.config file.
■Note Look up the topic “ASP.NET Settings Schema” within the .NET Framework 2.0 SDK documentation for full details on the format of Web.config.
Table 24-4. Select Elements of a Web.config File
Element |
Meaning in Life |
<appSettings> |
This element is used to establish custom name/value pairs that can be |
|
programmatically read in memory for use by your pages. |
<authentication> |
This security-related element is used to define the authentication mode |
|
for this web application. |
<authorization> |
This is another security-centric element used to define which users can |
|
access which resources on the web server. |

CHAPTER 24 ■ ASP.NET 2.0 WEB APPLICATIONS |
913 |
Element |
Meaning in Life |
<compilation> |
This element is used to enable (or disable) debugging and define the |
|
default .NET language used by this web application, and it may |
|
optionally define the set of external .NET assemblies that should be |
|
automatically referenced. |
<connectionStrings> |
This element is used to hold external connection strings used within |
|
this website. |
<customErrors> |
This element is used to tell the runtime exactly how to display errors |
|
that occur during the functioning of the web application. |
<globalization> |
This element is used to configure the globalization settings for this web |
|
application. |
<sessionState> |
This element is used to control how and where session state data will |
|
be stored by the .NET runtime. |
<trace> |
This element is used to enable (or disable) tracing support for this web |
|
application. |
|
|
A Web.config file may contain additional subelements above and beyond the set presented in Table 24-4. The vast majority of these items are security-related, while the remaining items are useful only during advanced ASP.NET scenarios such as creating with custom HTTP headers or custom HTTP modules (not covered here). If you wish to see the complete set of elements that can appear in a Web.config file, look up the topic “ASP.NET Settings Schema” using the online help.
Enabling Tracing via <trace>
The first aspect of the Web.config file you’ll examine is the <trace> subelement. This XML entity may take any number of attributes to further qualify its behavior, as shown in the following skeleton:
<trace enabled="true|false" localOnly="true|false" pageOutput="true|false" requestLimit="integer" traceMode="SortByTime|SortByCategory"/>
Table 24-5 hits the highlights of each attribute.
Table 24-5. Attributes of the <trace> Element
Attribute |
Meaning in Life |
Enabled |
Specifies whether tracing is enabled for an application as a whole (the default |
|
is false). As you saw in the previous chapter, you can selectively enable tracing |
|
for a given *.aspx file using the @Page directive. |
localOnly |
Indicates that the trace information is viewable only on the host web server |
|
and not by remote clients (the default is true). |
pageOutput |
Specifies how trace output should be viewed. |
requestLimit |
Specifies the number of trace requests to store on the server. The default is |
|
10. If the limit is reached, trace is automatically disabled. |
traceMode |
Indicates that trace information is displayed in the order it is processed. The |
|
default is SortByTime, but it can also be configured to sort by category. |
|
|
Recall from the previous chapter that individual pages may enable tracing using the <%@Page%> directive. However, if you wish to enable tracing for all pages in your web application, simply update <trace> as follows: