Chapter 14: Building Effective Web Applications

Caching Data Between Round-Trips

All right. So you know how to display data on a Web page. You know how to execute queries and use bound controls to convert that data to HTML. What if you don't want to execute the same queries every time someone hits your Web server? Maybe you want to cache the results of a process-intensive query. Maybe you want to store the contents of the user's shopping cart.

ASP.NET offers many caching features that let you control how you maintain data for your application or for each separate session. The features themselves are very straightforward. However, there's no single universal "right" or "wrong" way to cache data. Relying on a particular caching feature in one application might improve performance, while using the same feature in another application might hinder performance.

To understand which, if any, caching feature you should use in your application, you need to understand the architecture of the application you're building, as well as how each caching feature works, its pros and its cons. Rather than make sweeping statements like "Caching data in the Application object is a lousy idea," this text will quickly cover the basics of the various ASP.NET caching features as well as some of the pros and cons for each feature.

The Stateless Approach—Maintaining No State

There's no programming law saying that you must cache data. You can have your Web application's ASP.NET code be completely stateless.

You can have your ASP.NET code execute queries and convert the results to HTML using bound controls. If you're working with an order-entry application in which the user stores items in a shopping cart, you can store the contents of the current user's shopping cart in your database, relying on the session ID as a way to locate which rows in the database belong to the current user.

Benefits to Statelessness

This approach has obvious merits. By not caching data in your ASP.NET code, the application requires a minimum of memory per user. Purely from a memory standpoint, this approach is the most scalable.

Drawbacks to Statelessness

However, that's a very simplistic view of building scalable applications. Say application is an online catalog and you're displaying a list of product categories on all pages. Do you really want to query your database for the list of product categories each and every time a user accesses a page?

Caching Data at the Client

If you want to cache data but don't want to maintain that data on your servers, you can use various options to cache data at the client.

Cookies

Many Web sites use cookies to store user information at the client. The ASP.NET Request and Response objects each expose a Cookies collection that you can use to store and retrieve information between round-trips. For example, you could use the following code in your ASP.NET code to track the date and time of the user's last visit in a cookie:

Visual Basic .NET

If Request.Cookies("LastVisit") Is Nothing Then     lblLastVisit.Text = "This is your first visit!  Welcome!"     Response.AppendCookie(New HttpCookie("LastVisit", Now.ToString)) Else     lblLastVisit.Text = "Welcome back.  Your last visit was: " & _                         Request.Cookies("LastVisit").Value     Response.Cookies("LastVisit").Value = Now.ToString End If

Visual C# .NET

if (Request.Cookies["LastVisit"] == null) {     lblLastVisit.Text = "This is your first visit!  Welcome!";     Response.AppendCookie(new HttpCookie("LastVisit",                                          DateTime.Now.ToString())); } else {     lblLastVisit.Text = "Welcome back.  Your last visit was: " +                         Request.Cookies["LastVisit"].Value;     Response.Cookies["LastVisit"].Value = DateTime.Now.ToString(); }

Benefits to maintaining state using cookies

ASP.NET makes working with cookies simple. Storing data at the client allows your ASP.NET code to be stateless, which improves your scalability. Cookies are also configurable. You can control when the cookie expires by setting the HttpCookie object's Expires property.

Drawbacks to maintaining state using cookies

Cookies are designed to store small pieces of information. Most browsers will not let you store more than a couple kilobytes of data in a cookie, so they're not terribly handy for caching the results of a query that returns more than a couple rows.

Also, Internet developers are becoming less reliant on cookies. Depending on the browser's settings, the browser might reject the cookie. Keep that in mind before deciding to use cookies to store user settings.

Cookies aren't completely secure. The user can modify the contents of the cookie.

Hidden Fields

You can store information in a hidden field on your Web page. This process is somewhat analogous to a hidden control on a Windows Form. However, hidden fields aren't easily accessible through ASP.NET code. So, rather than examine the benefits and drawbacks to hidden fields in any depth, let's move along to a similar feature that's more developer-friendly—ViewState.

ViewState

The Page class in the System.Web.UI namespace exposes a ViewState property, which contains a StateBag object. Essentially, a StateBag object is similar to a collection of name/value pairs. You use it to store information, similar to the Cookies collections on the Request and Response objects.

You can store data in a page's ViewState and then retrieve that data in the next post-back event for the page. Working with the page's ViewState is as simple as working with cookies, as shown in the following code sample:

Visual Basic .NET

If ViewState("LastVisit") Is Nothing Then     lblLastVisit.Text = "This is your first visit!  Welcome!"     ViewState("LastVisit") = Now.ToString Else     lblLastVisit.Text = "Welcome back.  Your last visit was: " & _                         ViewState("LastVisit")     ViewState("LastVisit") = Now.ToString End If

Visual C# .NET

if (ViewState["LastVisit"] == null) {     lblLastVisit.Text = "This is your first visit!  Welcome!";     ViewState["LastVisit"] = DateTime.Now.ToString(); } else {     lblLastVisit.Text = "Welcome back.  Your last visit was: " +                         ViewState["LastVisit"];     ViewState["LastVisit"] = DateTime.Now.ToString(); }

Figure 14-1 shows the source for a page that uses the preceding code snippet to maintain the data and time of the user's last visit in the page's ViewState. If you look closely at the page's HTML, you'll see that the ViewState is maintained in a hidden field. Because all browsers support hidden fields regardless of their configuration, you can use the ViewState to store data for many scenarios in which using cookies would cause problems.

Figure 14-1

Examining a page's ViewState

Benefits to maintaining state in ViewState

As with cookies, storing data in a page's ViewState allows the ASP.NET code to remain stateless, which improves your code's scalability. Because ViewState is implemented as a hidden field, you can store and retrieve data from a page's ViewState regardless of the browser's security settings. And unlike cookies, the page can hold much larger items in its ViewState.

Drawbacks to maintaining state in ViewState

The data you store in a page's ViewState is sent down to the browser, so the more data you store the longer it takes to load pages and post back to the server. Also, while the data stored in ViewState is hashed, it's still possible for the user to decrypt the data stored there. Thus, it's not completely secure.

You can't store just any data in ViewState. You can store only data that your ASP.NET code knows how to serialize. You can store simple data types such as strings and integers. However, you can't store generic objects in ViewState because ASP.NET doesn't know how to store and re-create generic objects. Classes that support the ISerializable interface, such as DataSet objects and DataTable objects, can be written to ViewState.

Maintaining State in Your Web Server

ASP.NET also gives you various options for maintaining state on the server.

Session

The Page class exposes a Session property, which returns an instance of an HttpSessionState class. You can store data in the page's Session, just as you can in the page's ViewState. However, the data that you store in the page's Session is kept on the server rather than sent down to the browser along with the HTML for the page.

ASP.NET maintains the settings stored in Session until the user's session ends. Also, these settings are kept separate from those of other sessions. So the information stored in the page's Session is specific to that session.

Benefits to maintaining state in Session

Because the data is maintained by the Web server rather than by the browser, the data is secure. The user cannot access or modify the contents of the Session object through the browser. Also, because the data is maintained on the server, you can rely on the Session object regardless of the user's browser settings.

Drawbacks to maintaining state in Session

Storing data in the page's Session means your ASP.NET code might be less scalable as a result. Maintaining state in Session requires resources for each session of your application.

Say the user searches your product catalog and you maintain the results of that search in Session so that the user can page back and forth through the results without having to re-execute the query with each change of a page. Estimate how much memory is required to store the results of that query. 5 KB? 50 KB? 500 KB? Now multiply that by the number of people accessing this feature of your Web application. 10? 100? 1000? More? Think about the total server resources you'll likely use if you decide to maintain state in Session scope.

Application

The Application object is similar to the Session object except that the data available through the page's Application property is shared across all sessions. Thus, data you store in Application is available to all users.

Benefits to maintaining state in Application

As with data that you store in Session, the data you store in Application is secure because it's maintained on the server and the functionality is available regardless of the user's browser settings.

Because the data stored in Application is global to all sessions of the application, it's an ideal place to store non-volatile data that's used in all sessions, such as a list of product categories.

Drawbacks to maintaining state in Application

Data that you store in Application uses resources on your server. Storing too much data in Application can adversely affect the performance of your application.

Cache

The Page object exposes a Cache property, which returns an instance of the Cache object. You can think of the Cache object as a more robust Application object. The data stored in Cache is available in all sessions of the application. You can access and modify the contents of the Cache object just like the Application object, but the Cache object gives you the following additional functionality when you add an item to the Cache via the Add or Insert method:

  • You can specify when that item will be removed from the cache by supplying either a specific (DateTime) value or a relative (TimeSpan) value.

  • You can specify a CacheDependancy, which will force the item to be removed from the cache when the dependent item changes. For example, you can supply a CacheDependancy that will force the item in the cache to be removed when the contents of a specific XML file change.

  • You can specify a callback function that ASP.NET will call when the item is removed from the cache.

  • The benefits and drawbacks to using the Cache object are the same as those for the Application object, except that the Cache object offers additional cache removal features.

Output Caching

Imagine that all pages in your Web application will show a list of site options along the left margin of the page. This list might contain the available product categories or it might simply list the various areas of your Web site. In either case, let's say that the data that you use to construct this list is stored in your database somewhere and rarely changes.

You might decide to retrieve this data into a DataSet and store this DataSet in the Application object. This way your ASP.NET code does not need to fetch that data from the database each time it serves up a page. That would probably save a lot of network traffic, but you still wind up converting the contents of the DataSet to HTML each time you serve up a page of data.

ASP.NET offers another option: output caching. You can cache the output for a page or a portion of a page. You can also cache full or partial pages based on parameters. If you're looking to cache data to HTML for a page or a portion of the page, you should take a look at this powerful feature.

Benefits to using output caching

If you need to repeatedly generate the same HTML based on the contents of the DataSet, output caching is more efficient because it requires less processing at the server. Like the Cache object, you can control how long the output remains cached.

Drawbacks to using output caching

As with other server-side caching features, output caching still consumes resources on your server.

Maintaining State in Your Database

No one says you must maintain state in your Web server. Database servers are designed to maintain and serve up data. You can use your database to store global and session-specific data for your Web application, such as the contents of each user's shopping cart.

Your application might execute a query that's so complex or time consuming that you'd rather store the results of the query in a separate table than execute the query each time the user requests the next page worth of results. For example, the user might supply input to query your inventory database to find CD burners under $200, capable of writing at 20x or greater, that support USB and FireWire, and that are available at stores within a 30-mile radius of the user's home. The query might look something like this:

SELECT ProductID, ProductName, Description, UnitPrice, ... FROM Products     WHERE UnitPrice < 200 AND Description LIKE '%USB%' AND           Description LIKE '%FireWire%' AND ...

Suppose that query returns 50 records and the user will see 10 items per page. You can execute the query each time the user requests another page of results, or you can store the results in a table in your database. You could create a table to store the results of queries against this table using an INSERT INTO query and include the user's session ID so that you can keep track of which results belong to which session:

INSERT INTO ProductsQueryCache SELECT ? AS SessionID, ProductID, ProductName, Description, UnitPrice, ...      FROM Products     WHERE UnitPrice < 200 AND Description LIKE '%USB%' AND           Description LIKE '%FireWire%' AND ...

Then you could simply retrieve the next page's rows from this results table rather than executing the original query against your main catalog table. This particular example might not do the technique justice, but it can prove helpful when working with queries that you'd rather not execute repeatedly.

note

If you use this technique, be sure you remove the cached rows from the database in the Session object's End event, or wherever is appropriate.

Benefits to Maintaining State in Your Database

By storing state in your database, your ASP.NET code can remain stateless. Data that you store in your database is durable. If your Web server crashes for whatever reason, the data that you've stored in your database will still be available once you get the Web server back on line. The data that you store in the database is secure because it is not readily available to the user except through your ASP.NET code. Databases are designed to handle large result sets. If you absolutely must maintain large result sets between page requests, storing that data in your database is probably your best bet.

Drawbacks to Maintaining State in Your Database

Maintaining state in your database is more complex than simply storing data in simple objects and collections such as Session, Application, Cache, ViewState, or a cookie.

Guidelines for Maintaining State

How and where you maintain your state can have an enormous impact on the performance, scalability, and security of your Web applications. There are no absolute guidelines to determining if, how, and where you should maintain state for your Web application. However, here are some general guidelines.

Storing Data in ViewState

Store data in ViewState if you're working with small result sets and you're OK with the user being able to view this data. If you're concerned about security and don't want to take any chances on the user modifying this data, store it in the Session object or in your database. Remember that the data you store in ViewState is passed back and forth between the server and the client on each round-trip. The more data you store in ViewState, the longer each round-trip will take.

Storing Data in the Application Object

Store in the Application object small amounts of data that's global to all sessions for the application. Remember that the more data you store in the Application object, the more you'll adversely affect performance.

Storing Data in the Session Object

Store in the Session object small amounts of data that's critical to that particular session and that you're not comfortable storing in ViewState for security reasons. Remember that the more data you store in the Session object, the more you'll adversely affect performance, and at a more accelerated rate than with the Application object. For example, storing 100 KB of data in a Session doesn't sound like much until you multiply that by the number of sessions that ASP.NET will maintain at any given time. Store large amounts of session-specific data in your database instead.

Storing Data in the Database

Store large amounts of session-specific data in your database. Accessing data from memory is obviously faster than retrieving the same information from your database. But, if you need to store large amounts of session-specific data, maintaining that data in your database lowers the total amount of memory in use on your server at any given time.

Using Output Caching

If you want to generate the same static HTML over and over again, use ASP.NET output caching rather than caching the data required to generate that HTML.



Microsoft ADO. NET Core Reference
Microsoft ADO.NET (Core Reference) (PRO-Developer)
ISBN: 0735614237
EAN: 2147483647
Year: 2002
Pages: 104
Authors: David Sceppa

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net