In this article we will see how to precisely control the cache of the client
(the browser of your PC, for example) in order to avoid the transmission of data
from the server when the client already owns them. The ASP.NET server already
has systems for data caching, for example to avoid repeating the same database
query; would not it be nice not to avoid sending these data to avoid bandwidth
The technique is called conditional GET and uses the
304 HTTP status code and in practice implements the following dialogue
between client and server:
Client: "Hello server, I need some data. The last time
you gave them to me, you told me they were update to the following date/time"
At this point, the server checks the provided date/time and, whether the data
are changed, it responds:
Server: "Hello client, the data have changed since then,
here's the new ones. If you need them again in future, note that data are update
to the following date/time."
Server: "Hello client, the data have not changed since
then, so I avoid send them again, you have them in your cache."
This type of optimization is particularly useful when data are dynamically
generated on the server side and change during the time.
Let us transform this dialogue in C# code, using the example of
an HttpHandler that generates a RSS file dynamically (that's
what happens when you subscribe to the RSS feeds of this blog). In this example
we do not address the topic of ther dynamic generation of RSS feeds, as this
would be beyond the scope of the article, but we'll just see how to implement
the conditional caching.
Let's assume that the method
the UTC date/time of the last blog update.
BlogRssHandler : IHttpHandler, IRequiresSessionState
// If the client already has the updated RSS, do not send it again
// Generate the RSS feed
// Returns false if contents can be retrieved from the browser's cache
// (HTTP response 304 optimization)
Boolean BuildResponseHeader(HttpContext Context)
// Get the last modification date/time stored in the database
// NOTE: the date/time must be UTC
DateTime serverLastUpdateUTC = GetLastBlogUpdateDateTime();
// Get the last modification date provided by the browser (if any)
String ifModifiedSinceHeaderText = Context.Request.Headers.
DateTime clientLastUpdateUTC = DateTime.Parse(ifModifiedSinceHeaderText);
clientLastUpdateUTC = clientLastUpdateUTC.Value.ToUniversalTime();
// If the modification date/time of the client is equal to the server one
(serverLastUpdateUTC <= clientLastUpdateUTC)
// ...tell the browser that contents have not changed and return
Context.Response.StatusCode = (Int32)
// Tell the browser to cache the new contents
// Force the browser to not use it's current cache
TimeSpan(0, 0, 0));
When the server sends the date/time to the client it is better to round it
It 'also important to specify that the date/time is UTC (
method), this thing is not mentioned in some examples around the web, but it is