the web controls they contain. This chapter builds on that information by examining the role of the
Global.asax file and the underlying HttpApplication type. As you will see, the functionality of
HttpApplication allows you to intercept numerous events that enable you to treat your web applications
as a cohesive unit, rather than a set of stand-alone *.aspx files.
In addition to investigating the HttpApplication type, this chapter also addresses the allimportant
topic of state management. Here you will learn the role of view state, session and
application variables (including the application cache), cookie data, and the ASP.NET Profile API.
The Issue of State
protocol. This very fact makes web development extremely different from the process of building an
executable assembly. For example, when you are building a Windows Forms application, you can
rest assured that any member variables defined in the Form-derived class will typically exist in memory
until the user explicitly shuts down the executable:
public partial class MainWindow : System.Windows.Forms.Form
{
// State data!
private string userFavoriteCar = "Yugo";
}
In the world of the World Wide Web, however, you are not afforded the same luxurious assumption.
To prove the point, create a new ASP.NET website named SimpleStateExample. Within the
code-behind file of your initial *.aspx file, define a page-level string variable named
userFavoriteCar:
public partial class _Default : System.Web.UI.Page
{
// State data?
private string userFavoriteCar = "Yugo";
protected void Page_Load(object sender, EventArgs e)
{
}
}
The server-side Click event handler for the Set button (named btnSetCar) will allow the user to
assign the string member variable to the value within the TextBox (named txtFavCar):
protected void btnSetCar_Click(object sender, EventArgs e)
{
// Store fave car in member variable.
userFavoriteCar = txtFavCar.Text;
}
while the Click event handler for the Get button (btnGetCar) will display the current value of the
member variable within the page’s Label widget (lblFavCar):
protected void btnGetCar_Click(object sender, EventArgs e)
{
// Show value of member variable.
lblFavCar.Text = userFavoriteCar;
}
Now, if you were building a Windows Forms application, you would be right to assume that
once the user sets the initial value, it would be remembered throughout the life of the desktop
application. Sadly, when you run this web application, you will find that each time you post back to
the web server (by clicking either button), the value of the userFavoriteCar string variable is set
back to the initial value of “Yugo”; therefore, the Label’s text is continuously fixed.
Again, given that HTTP has no clue how to automatically remember data once the HTTP
response has been sent, it stands to reason that the Page object is destroyed almost instantly. Therefore,
when the client posts back to the *.aspx file, a new Page object is constructed that will reset
any page-level member variables. This is clearly a major dilemma. Imagine how useless online
shopping would be if every time you posted back to the web server, any and all information you
previously entered (such as the items you wished to purchase) were discarded. When you wish to
remember information regarding the users who are logged on to your site, you need to make use of
various state management techniques.
Note This issue is in no way limited to ASP.NET. Java servlets, CGI applications, classic ASP, and PHP applications all must contend with the thorny issue of state management.

To remember the value of the userFavoriteCar string type between postbacks, you are required
to store the value of this string type within a session variable. You will examine the exact details of session state in the pages that follow. For the sake of completion, however, here are the necessary updates for the current page (note that you are no longer using the private string member variable, therefore feel free to comment out or remove the definition altogether):
public partial class _Default : System.Web.UI.Page
{
// State data?
// private string userFavoriteCar = "Yugo";
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSetCar_Click(object sender, EventArgs e)
{
// Store value to be remembered in session variable.
Session["UserFavCar"] = txtFavCar.Text;
}
protected void btnGetCar_Click(object sender, EventArgs e)
{
// Get session variable value.
lblFavCar.Text = (string)Session["UserFavCar"];
}
}
If you now run the application, the value of your favorite automobile will be preserved across
postbacks, thanks to the HttpSessionState object manipulated indirectly by the inherited Session
properties.
ASP.NET State Management Techniques
ASP.NET provides several mechanisms that you can use to maintain stateful information in your
web applications. Specifically, you have the following options:
• Make use of ASP.NET view state.
• Make use of ASP.NET control state.
• Define application-level variables.
• Make use of the cache object.
• Define session-level variables.
• Define cookie data.
The one thing these approaches have in common is that they each demand that a given user is
in session and that the web application is loaded into memory. As soon as a user logs off (or times
out) from your site (or your website is shut down), your site is once again stateless. If you wish to persist user data in a permanent manner, ASP.NET provides an out-of-the-box Profile API. We’ll examine the details of each approach in turn, beginning with the topic of ASP.NET view state.
Understanding the Role of ASP.NET View State
The term view state has been thrown out a few times here and in the previous two chapters without a formal definition, so let’s demystify this term once and for all. Under classic (COM-based) ASP, web developers were required to manually repopulate the values of the incoming form widgets during the process of constructing the outgoing HTTP response. For example, if the incoming HTTP request contained five text boxes with specific values, the *.asp file required script code to extract the current values (via the Form or QueryString collections of the Request object) and manually place them back into the HTTP response stream (needless to say, this was a drag). If the developer failed to do so, the caller was presented with a set of five empty text boxes! Under ASP.NET, we are no longer required to manually scrape out and repopulate the values contained within the HTML widgets because the ASP.NET runtime will automatically embed a hidden formfield (named __VIEWSTATE), which will flow between the browser and a specific page. The data assigned to this field is a Base64-encoded string that contains a set of name/value pairs that represent the values of each GUI widget on the page at hand. The System.Web.UI.Page base class’s Init event handler is the entity in charge of reading the incoming values found within the __VIEWSTATE field to populate the appropriate member variables in the derived class (which is why it is risky at best to access the state of a web widget within the scope of a page’s Init event handler).
Also, just before the outgoing response is emitted back to the requesting browser, the
__VIEWSTATE data is used to repopulate the form’s widgets, to ensure that the current values of the HTML widgets appear as they did prior to the previous postback.
Clearly, the best thing about this aspect of ASP.NET is that it just happens without any work on
your part. Of course, you are always able to interact with, alter, or disable this default functionality if you so choose. To understand how to do this, let’s see a concrete view state example.
Demonstrating View State
First, create a new ASP.NET web application called ViewStateApp. On your initial *.aspx page, add
a single ASP.NET ListBox web control (named myListBox) and a single Button type (named
btnPostback). Handle the Click event for the Button to provide a way for the user to post back to
the web server:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnPostback_Click(object sender, EventArgs e)
{
// No-op. This is just here to allow a postback.
}
}
Now, using the Visual Studio 2008 Properties window, access the Items property and add four
ListItems to the ListBox using the associated dialog box. The resulting markup looks like this:
Note that you are hard-coding the items in the ListBox directly within the *.aspx file. As you
already know, all
their HTML representation before the final HTTP response (provided they have the runat="server"
attribute).
The <%@Page%> directive has an optional attribute called EnableViewState that by default is set
to true. To disable this behavior, simply update the <%@Page%> directive as follows:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" EnableViewState ="false" %>
So, what exactly does it mean to disable view state? The answer is, it depends. Given the previous
definition of the term, you would think that if you disable view state for an *.aspx file, the
values within your ListBox would not be remembered between postbacks to the web server. However,
if you were to run this application as is, you might be surprised to find that the information in
the ListBox is retained regardless of how many times you post back to the page.
In fact, if you examine the source HTML returned to the browser (by right-clicking the page
within the browser and selecting View Source), you may be further surprised to see that the hidden
__VIEWSTATE field is still present:
The reason the view state string is still visible is the fact that the *.aspx file has explicitly
defined the ListBox items within the scope of the HTML
No comments:
Post a Comment