Now that you’ve explored the page life cycle and learned how a page contains controls, it’s worth pointing out that the page itself is also instantiated as a type of control object. In fact, all web forms are actually instances of the ASP.NET Page class, which is found in the System.Web.UI namespace.
Every code-behind class explicitly derives from System.Web.UI.Page. This means that every web form you create is equipped with an enormous amount of out-of-the-box functionality. Deriving from the Page class gives your code the following extremely useful properties:
- Session
- Application
- Cache
- Request
- Response
- Server
- User
- Trace
Many of these properties correspond to intrinsic objects that you could use in classic ASP web pages. However, in classic ASP you accessed this functionality through built-in objects that were available at all times. In ASP.NET, each of these built-in objects actually corresponds to a Page property that exposes an instance of a full-featured class.
The following sections introduce these objects.
Session, Application, and Cache
The Session object is an instance of the System.Web.SessionState.HttpSessionState class. It’s designed to store any type of user-specific data that needs to persist between web-page requests.
The Session object provides dictionary-style access to a set of name/value pairs that represents the User’s data for that session. Session state is often used to maintain things such as the user’s name, the user’s ID, a shopping cart, or various other elements that are discarded when a given user is no longer accessing pages on the website.
The Application object is an instance of the System.Web.HttpApplicationState class. Like the Session object, it is also a name/value dictionary of data. However, this data is global to the entire application.
Finally, the Cache object is an instance of the System.Web.Caching.Cache class. It also stores global information, but it provides a much more scalable storage mechanism because ASP.NET can remove objects if server memory becomes scarce. Like the other state collections, it’s essentially a name/value collection of objects, but you can also set specialized expiration policies and dependencies for each item.
Deciding how to implement state management is one of the key challenges of programming a web application.
Request
The Request object is an instance of the System.Web.HttpRequest class. This object represents the values and properties of the HTTP request that caused your page to be loaded. It contains all the URL parameters and all other information sent by a client. Much of the information provided by the Request object is wrapped by higher-level abstractions (such as the ASP.NET web control model), so it isn’t nearly as important as it was in classic ASP. However, you might still use the Request object to find out what browser the client is using or to set and examine cookies.
Table 1 describes some of the more common properties of the Request object.
HttpRequest Properties
Property |
Description |
ApplicationPath and PhysicalPath | ApplicationPath gets the ASP.NET application’s virtual directory (URL), while PhysicalPath gets the “real” directory. |
AnonymousID | This uniquely identifies the current user if you’ve enabled anonymous access. |
Browser | This provides a link to an HttpBrowserCapabilities object, which contains properties describing various browser features, such as support for ActiveX controls, cookies, VBScript, and frames. |
ClientCertificate | This is an HttpClientCertificate object that gets the security certificate for the current request, if there is one. |
Cookies | This gets the collection cookies sent with this request. |
FilePath and CurrentExecutionFilePath | These return the real file path (relative to the server) for the currently executing page. FilePath gets the page that started the execution process. This is the same as CurrentExecutionFilePath, unless you’ve transferred the user to a new page without a redirect (for example, using the Server.Transfer() method), in which case CurrentExecutionFilePath reflects the new page and FilePath indicates the original page. |
Form | This represents the collection of form variables that were posted back to the page. In almost all cases, you’ll retrieve this information from control properties instead of using this collection. |
Headers and ServerVariables | These provide a name/value collection of HTTP headers and server variables. You can get the low-level information you need if you know the corresponding header or variable name. |
IsAuthenticated and IsSecureConnection | These return true if the user has been successfully authenticated and if the user is connected over SSL (Secure Sockets Layer). |
IsLocal | This returns true if the user is requesting the page from the current computer. |
QueryString | This provides the parameters that were passed along with the query string. Chapter 6 shows how you can use the query string to transfer information between pages. |
Url and UrlReferrer | These provide a Url object that represents the current address for the page and the page where the user is coming from (the previous page that linked to this page). |
UserAgent | This is a string representing the browser type. Internet Explorer provides the value MSIE for this property. |
UserHostAddress and UserHostName | These get the IP address and the DNS name of the remote client. You could also access this information through the
ServerVariables collection. However, this information may not always be available. |
UserLanguages | This provides a sorted string array that lists the client’s language preferences. This can be useful if you need to create multilingual pages. |
Response
The Response object is an instance of the System.Web.HttpResponse class, and it represents the web server’s response to a client request. In classic ASP, the Response object was the only way to programmatically send HTML text to the client. Now server-side controls have nested, object oriented methods for rendering themselves. All you have to do is set their properties. As a result, the Response object doesn’t play nearly as central a role.
The HttpResponse does still provide some important functionality.namely, cookie features and the Redirect () method. The Redirect () method allows you to send the user to another page.
Here’s an example:
// you can redirect to a file in the current directory.
Response.Redirect(“newpage.aspx”);
// You can redirect to another website.
Response.Redirect(“http://www.prosetech.com”);
The Redirect () method requires a round-trip. Essentially, it sends a message to the browser that instructs it to request a new page. If you want to transfer the user to another page in the same web application, you can use a faster approach with the Server.Transfer () method.
Tip: Another way also exists to get from one page to the next.crosspage posting. Using this technique, you can create a page that posts itself to another page, which allows you to effectively transfer all the view state information and the contents of any controls.
Table 2 lists common HttpResponse members.
HttpResponse Members
Member |
Description |
BufferOutput | When set to true (the default), the page isn’t sent to the client until it’s completely rendered and ready to be sent, as opposed to being sent piecemeal. |
Cache | This references an HttpCachePolicy object that allows you to configure output caching. |
Cookies | This is the collection of cookies sent with the response. You can use this property to add additional cookies. |
Expires and ExpiresAbsolute | You can use these properties to cache the rendered HTML for the page, improving performance for subsequent requests. |
IsClientConnected | This is a Boolean value indicating whether the client is still connected to the server. If it isn’t, you might want to stop a time-consuming operation. |
Write(), BinaryWrite(),and WriteFile() | These methods allow you to write text or binary content directly to the response stream. You can even write the contents of a file. These methods are de-emphasized in ASP.NET and shouldn’t be used in conjunction with server controls. |
Redirect() | This method transfers the user to another page in your application or a different website. |
Server
The Server object is an instance of the System.Web.HttpServerUtility class. It provides a handful of miscellaneous helper methods and properties, as listed in Table 3.
Table 3 HttpServerUtility Methods
Method |
Description |
MachineName | A property representing the computer name of the computer on which the page is running. This is the name the web server computer uses to identify itself to the rest of the network. |
CreateObject() | Creates an instance of the COM object that is identified by its progID (programmatic ID). This is included for backward compatibility, because it will generally be easier to interact with COM objects using .NET’s support for COM interop, which provides strongly typed interaction. |
GetLastError | Retrieves the exception object for the most recently encountered error (or a null reference, if there isn’t one). This error must have occurred while processing the current request and it must not have been handled. This is most commonly used in an application event handler that checks for error conditions. |
HtmlEncode() and HtmlDecode() | Changes an ordinary string into a string with legal HTML characters (and back again). |
UrlEncode() and UrlDecode() | Changes ordinary string into a string with legal URL characters (and back again). |
UrlEncodeToken() and UrlDecodeToken() | Performs the same work as UrlEncode() and UrlDecode(), except they work on a byte array that contains Base64-encoded data. |
MapPath() | Returns the physical file path that corresponds to a specified virtual file path on the web server. |
Transfer() | Transfers execution to another web page in the current application. This is similar to the Response.Redirect() method, but it’s faster. It cannot be used to transfer the user to a site on another web server or to a non-ASP.NET page (such as an HTML page or an ASP page). |
The Transfer () method is the quickest way to redirect the user to another page in your application.
When you use this method, a round-trip is not involved. Instead, the ASP.NET engine simply loads the new page and begins processing it. As a result, the URL that’s displayed in the client’s browser won’t change.
// you can transfer to a file in the current web application.
Server.Transfer (“newpage.aspx”);
// you can’t redirect to another website.
// this attempt will cause an error.
Server.Transfer (“http://www.prosetech.com”);
The MapPath() method is another useful method of the Server object. For example, imagine you want to load a file named info.txt from the current virtual directory. Instead of hard-coding the path, you can use Request.ApplicationPath() to get the current relative virtual directory and Server.MapPath() to convert this to an absolute physical path. Here’s an example:
string physicalPath = Server.MapPath(Request.ApplicationPath + “/info.txt”));
// Now open the file.
StreamReader reader = new StreamReader(physicalPath);
// (Process the file here.)
reader.Close()
HTML and URL Encoding
The Server class also includes methods that change ordinary strings into a representation that can safely be used as part of a URL or displayed in a web page. For example, imagine you want to display this text on a web page:
To bold text use the <b> tag.
If you try to write this information to a page or place it inside a control, you would end up with this instead:
To bold text use the tag.
Not only will the text <b> not appear, but the browser will interpret it as an instruction to make the text that follows bold. To circumvent this automatic behavior, you need to convert potential problematic values to their special HTML equivalents. For example, < becomes < in your final HTML page, which the browser displays as the < character. Table 3-4 lists some special characters that need to be encoded.
Table 4 Common HTML Entities
Result | Description | Encoded Entity |
Nonbreaking space | | |
< | Less-than symbol | < |
> | Greater-than symbol | > |
& | Ampersand | & |
“ | Quotation mark | " |
Here’s an example that circumvents the problem using the Server.HtmlEncode() method:
Label1.Text = Server.HtmlEncode(“To bold text use the <b> tag.”)
You also have the freedom to use HtmlEncode for some input, but not for all of it if you want to insert a combination of text that could be invalid and HTML tags. Here’s an example:
Label1.Text = “To <b>bold</b> text use the “;
Label1.Text += Server.HtmlEncode(“<b>”) + ” tag.”;
The HtmlEncode() method is particularly useful if you’re retrieving values from a database and you aren’t sure if the text is valid HTML. You can use the HtmlDecode() method to revert the text to its normal form if you need to perform additional operations or comparisons with it in your code. Similarly, the UrlEncode() method changes text into a form that can be used in a URL, escaping spaces and other special characters. This step is usually performed with information you want to add to the query string.
It’s worth noting that the HtmlEncode() method won’t convert spaces to nonbreaking spaces. This means that if you have a series of space characters, the browser will display only a single space. Although this doesnft invalidate your HTML, it may not be the effect you want. To change this behavior, you can manually replace spaces with nonbreaking spaces using the String.Replace() method. Just make sure you perform this step after you encode the string, not before, or the nonbreaking space character sequence (&nbps;) will be replaced with character entities and treated as ordinary text.
// Encode illegal characters.
line = server.HtmlEncode(line);
// Replace spaces with nonbreaking spaces.
line = line.Replace(” “, “ ”);
Similarly, the HtmlEncode() method wonft convert line breaks into the <br> tag. This means that hard returns will be ignored unless you specifically insert <br> tags.
User
The User object represents information about the user making the request of the web server, and it allows you to test that user’s role membership.
The User object always implements System.Security.Principal.IPrincipal. The specific class depends on the type of authentication youfre using. For example, you can authenticate a user based on Windows account information using IIS or through cookie-based authentication with a dedicated login page. However, itfs important to realize that the User object provides useful information only if your web application is performing some sort of authentication that restricts anonymous users.
Trace
The Trace object is a general-purpose tracing tool (and an instance of the System.Web.TraceContext class). It allows you to write information to a log that is scoped at the page level. This log has detailed timing information so that not only can you use the Trace object for debugging but you can also use it for performance monitoring and timing. Additionally, the trace log also shows a compilation of miscellaneous information, grouped into several sections. Table 5 describes all the information you’ll see.
Table 3-5. Trace Log Information
Section | Description |
Request Details | This section includes some basic information about the request context, including the current session ID, the time the web request was made, and the type of web request and encoding. |
Trace Information | This section shows the different stages of processing the page went through before being sent to the client. Each section has additional information about how long it took to complete, as a measure from the start of the first stage (From First) and as a measure from the start of the previous stage (From Last). If you add your own trace messages (a technique described shortly), they will also appear in this section. |
Control Tree | The control tree shows you all the controls on the page, indented to show their hierarchy, similar to the control tree example earlier in this chapter. One useful feature of this section is the Viewstate column, which tells you how many bytes of space are required to persist the current information in the control. This can help you gauge whether enabling control state could affect page transmission times. |
Session State and Application State | These sections display every item that is in the current session or application state. Each item is listed with its name, type, and value.
If you’re storing simple pieces of string information, the value is straightforward. If you’re storing an object, .NET calls the object’s ToString() method to get an appropriate string representation. For complex objects, the result may just be the class name. |
Cookies Collection | This section displays all the cookies that are sent with the response, as well as the content and size of each cookie in bytes. Even if you haven’t explicitly created a cookie, you’ll see the ASP.NET_SessionId cookie, which contains the current session ID. If you’re using forms-based authentication, you’ll also see the security cookie. |
Headers Collection | This section lists all the HTTP headers associated with the request. |
Forms Collection | This section lists the posted-back form information. |
QueryString Collection | This section lists the variables and values submitted in the query string. |
Server Variables | This section lists all the server variables and their contents. |
You can enable tracing in two ways. You can set the Trace.IsEnabled property to true at any point in your code, as follows:
Trace.IsEnabled = true;
Usually, you’ll do this in the Page.Load event handler. Another option is to use the Trace attribute
in the Page directive:
<%@ Page language=”c#” CodeFile=”PageFlow.aspx.cs” AutoEventWireup=”true” Inherits=”PageFlow” Trace=”true” %>
By default, trace messages are listed in the order they were generated. Alternatively, you can specify that messages should be sorted by category, using the TraceMode attribute in the Page directive, as follows:
<%@ Page language=”c#” CodeFile=”PageFlow.aspx.cs” AutoEventWireup=”true” Inherits=”PageFlow” Trace=”true” TraceMode=”SortByCategory” %>
or the TraceMode property of the Trace object in your code:
Trace.TraceMode = TraceMode.SortByCategory;
Figure 10 shows a partial listing of trace information with the PageFlow example demonstrated earlier.
You can also write your own information to the trace log (the portion of the trace log that appears in the Trace Information section) using the Trace.Write() or Trace.Warn() method. These methods are equivalent. The only difference is that Warn() displays the message in red lettering, which makes it easier to distinguish from other messages in the list.
Here’s a code snippet that writes a trace message when the user clicks a button:
protected void Button1_Click(object sender, System.EventArgs e)
{
// You can supply just a message, or include a category label,
// as shown here.
Trace.Write(“Button1_Click”, “About to update the label.”);
lblInfo.Text += “Button1.Click event handled.<br />”;
Trace.Write(“Button1_Click”, “Label updated.”);
}
When you write trace messages, they are automatically sent to all trace listeners. However, if you’ve disabled tracing for the page, the messages are simply ignored. Tracing messages are automatically HTML-encoded. This means tags such as <br /> and <b> are displayed as text, not interpreted as HTML.
Figure 3-10. Basic trace information
Figure 3-11.Writing custom trace messages
Application Tracing
By default, tracing is enabled on a page-by-page basis. This isn’t always convenient. In some cases,
You want to collect trace statistics for a page and then view them later. ASP.NET supports this approach with application-level tracing.
To enable application-level tracing, you need to modify the web.config configuration file. Look for the <trace> element and enable it as shown here:
<configuration>
<system.web>
<trace enabled=”true” requestLimit=”10″ pageOutput=”false”
traceMode=”SortByTime” localOnly=”true” />
</system.web>
</configuration>
When you enable application-level tracing, you wonft see the trace information on the page. Instead, to view tracing information you must request the trace.axd application extension in your web applicationfs root directory. This extension doesnft correspond to an actual file. instead, ASP.NET automatically intercepts the request and lists the most recently collected trace requests (as shown in Figure 3-12), provided youfre making the request from the local machine or have enabled remote tracing. You can see the detailed information for any request by clicking the View Details link.
Table 3-6 describes the full list of tracing options in the web.config <trace> element.
Table 6 Tracing Options
Attribute | Values | Description |
Enabled | true, false | Turns tracing on or off for all pages. This is the default setting for your web application—you can still override it on a page-by-page basis with the Page directive. Use the pageOutput setting to determine whether trace information is shown in the page or collected silently. |
traceMode | SortByTime, SortByCategory | Determines the sort order of trace messages. |
localOnly | true, false | Determines whether tracing information will be shown only to local clients (clients using the same computer) or can be shown to remote clients as well. By default, this is true and remote clients cannot see tracing information. In a production-level application, this should always be true to ensure security. |
pageOutput | true, false | Determines whether tracing information will be displayed on the page (as it is with pagelevel tracing) or just stored on the server (application-level tracing). If you choose false to use application-level tracing, you’ll still be able to view the collected information by requesting trace.axd from the virtual directory where your application is running. |
requestLimit | Any integer | When using application-level tracing, this is the number of HTTP requests for which tracing information will be stored. Unlike page-level tracing, this allows you to collect a batch of information from multiple requests. If you specify any value greater than 10,000, ASP.NET treats it as 10,000. When the maximum is reached, the behaviour depends on the value of the most Recent setting. |
mostRecent | true, false | If true, ASP.NET keeps only the most recent trace messages. When the requestLimit
maximum is reached, the information for the oldest request is abandoned every time a new request is received. If false (the default), ASP.NET stops collecting new trace messages when the limit is reached and ignores subsequent requests. |
writeToDiagnosticsTrace | true, false | If true, all trace messages are also forwarded to the System.Diagnostics tracing infrastructure and received by any trace listeners you has configured using that model. The default is false. The System.Diagnostics trace features are not ASP.NET-specific and can be used in a wide variety of .NET applications. They may be used in ASP.NET as a way to automatically capture trace messages and enter them in an event log. |
Tracing with the ASP.NET Development Helper
If you’ve installed the ASP.NET Development Helper introduced in Chapter 2 (and available at http://www.nikhilk.net/ASPNETDevHelperTool.aspx), you have another option for looking at tracing information. Viewing it in a separate window; When the ASP.NET Developer Helper is running (both on the web server and web browser), it automatically removes trace information from the page. To access it, you can either uncheck the Hide Trace from Page check box (which shows it in the page) or click the Show Trace link.
Accessing the HTTP Context in Another Class
Over the past several sections, you’ve seen how the Page class exposes a significant number of useful features that let you retrieve information about the current HTTP context. These details are available because they’re provided as properties of the Page class. But what if you want to retrieve this information from inside another class, one that doesn’t derive from Page?
Fortunately, another way exists to get access to all the HTTP context information. You can use the System.Web.HttpContext class. This class exposes a static property called Current, which returns an instance of the HttpContext class that represents all the information about the current request and response. It provides the same set of built-in ASP.NET objects as properties.
Figure 3-13.Managing trace information with the ASP.NET Development Helper
For example, here’s how you would write a trace message from another component that doesn’t
Derive from Page but is being used by a web page as part of a web request:
HttpContext.Current.Trace.Write(“This message is from DB Component”);
If you want to perform multiple operations, it may be slightly faster to retrieve a reference to the current context and then reuse it:
HttpContext current = HttpContext.Current;
current.Trace.Write(“This is message 1”);
current.Trace.Write(“This is message 2”);