473,414 Members | 1,707 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

Output caching dynamic pages

Hi.

I had a very frustrating afternoon and evening but I have got it all under
control now so all of a sudden I am in a good mood. I want to share some
insights on output caching with you lot.

After looking at the use of the OutputCache directive and tinkering with it
a bit I found its usability.very limited. Think of it: it is okay for static
content. Well that's nice but no big deal. Static content is cheap anyway,
the file system cache will take care of caching static content for me
automatically, ASP.NET doing it once again seems more like a waste to me
than an efficiency boost.

So much for caching static content. For dynamic content it is absolutely
useless because there is no way to invalidate the cache based on a parameter
value which is the one thing you want when applying output caching on a
dynamic page. Take a message board page. When someone posts a message, you
would do something like

<form id="MsgForm" action="board.aspx?action=post" method="Post">

so you can detect the post-back based on the value of the action parameter.
You would switch to code that saves the message and then redirect to display
the updated message list. Of course, at that time you would want the cache
to be invalidated in order not to have the old message list being returned
instead of your save logic being invoked. Currently there is no way to deal
with this using the OutputCache directive. All you can do with VaryByParam
is add more cached pages, you cannot exclude a page based on a parameter
value which is what you need here.

It doesn't seem hard for the ASP.NET developers to expand the OutputCache
directive to support this kind of behavior and I don't see why they did not
do so in the first place. Code that invalidates a page isn't of much use
while ASP.NET keeps serving cached responses, disregarding any server side
logic. It's catch 22, you cannot pull yourself from the swamp pulling your
bootstraps.
So, this morning I hit something interesting:
System.Web.HttpCachePolicy.AddValidationCallback. At last, this seemed like
what I had been looking for all along: a call-back. I would be asked whether
it was okay to use the cached page or not. How convenient, I, the
programmer, actually got a say in the way requests were handled again. Nice!

I had three kinds of request to deal with for the same page. First there was
the parameterless request, listing all previously posted data. Then there
was the edit request for which the response is a form to be filled in and
posted back by the user. And finally there was the post request for which
the posted form is received , the data collected and stored and a redirect
is performed to simulate the first type of request.

What took me about 4 hours to figure out is that for the post request my
call-back never gets called. This makes sense, the logic behind my post
request does not produce a response, it just stores data and that's it. If
there's no response, there will be no cached data for the request hence
there is nothing to query for ASP.NET.

At this point it may seem simple. Why bother with call-back routines if we
do get the post request at all times, just when we need to take control? The
problem is that you don't have the context for normel (parameterless)
request at that time so you cannot invalidate it when you want to. Perhaps
there is a way I am not aware of to get to a page's cache from within
another context after al. If so I would like to hear about it. I found
another solution.

The way to make it work just perfectly is to declare a static flag in your
page class, have that set by your store logic (that gets invoked by the post
request) and then check that flag in the call-back implementation for a
normal request. If the flag is set it means we had a new post and the cached
list is not current anymore so we need to invalidate. You should also reset
the flag.
The aspx file could have an ordinairy OutputCache directive:

<%@ OutputCache Duration="16934400" VaryByParam="*" Location="Server" %>
<!-- keeping page hot for 4 weeks -->

and on any normal request expiration could be refreshed to the same same
amount ().

Below are the interesting parts of the code-behind file.
namespace mwte
{
using System;
using System.Web;

public class MyPage : System.Web.UI.Page
{
public string URL_of_this_page = null;

static Boolean IsDirty = false;

static protected void Validate(HttpContext context, Object data, ref
HttpValidationStatus status)
{
string action = (context.Request["action"] == null) ? "" :
context.Request["action"];

// The default page should only expire when IsDirty
// was set because of an earlier post request.
if (action == "")
{
if (IsDirty)
{
status = HttpValidationStatus.Invalid;
// reset flag
IsDirty = false;
}
else
{
status = HttpValidationStatus.Valid;
// reset expiration time to a day from this moment on
context.Response.Cache.SetExpires(DateTime.Now.Add Days(1));
}
return;
}

// the edit form never expires
if (action == "edit")
{
status = HttpValidationStatus.Valid;
return;
}

// Note that we do not test for action == "post" here. While it would
// be nice if we could, we can't because Validate is not called for
// post requests. There is no response for post requests, hence no
// cached page, hence Validate is not called. We need to set IsDirty
// in Page_Load instead.
}

protected void Page_Init(object sender, EventArgs e)
{
URL_of_this_page = Request.ServerVariables["SCRIPT_NAME"];
Response.Cache.AddValidationCallback(new
HttpCacheValidateHandler(Validate), null);
}

protected void Page_Load(object sender, EventArgs e)
{
// no local caching
Response.Expires = 0;

string action = (Request["action"] == null) ? "" : Request["action"];

if (action == "")
{
// keep page hot another 4 weeks
Response.Cache.SetExpires(DateTime.Now.AddDays(28) );

// aspx with asp:Xml control does it all
return;
}

if (action == "edit")
{
// let aspx respond with input form
return;
}

if (action == "post")
{
// store logic
// ...

// signal next request handler to invalidate the cached page
IsDirty = true;

// display (and cache) the new list
Response.Redirect(URL_of_this_page);
return;
}
}
}
}


Nov 18 '05 #1
0 2109

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Behzad | last post by:
Hi all I'am ASP programmer and I have built a site that users can upload and download files.All things store in a DB and everytime someone enters a page,the application requery the Db and shows...
0
by: Troy Simpson | last post by:
Hi, I have a website which is made up of dynamic pages. Each page that's loaded has some code which looks at which template to load amongst other things, which causes the page to take a little...
8
by: Nick Gilbert | last post by:
Hi, Our development web server (Win 2003 Server) seems to be caching the output of various files (CSS and .aspx files) if they have no query string. The moment you put a question mark in the...
13
by: tshad | last post by:
How do we handle Caching in IE? It seems that my system works fine in Mozilla and Netscape when I make changes. But in IE the changes are not brought across when someone has been to the site...
1
by: Ben Fidge | last post by:
What are best practices for page output caching on pages that are dynamically generated from database tables. Our site has left-hand navigation that is comprised of dynamically generated menus...
3
by: ary | last post by:
I try to create a weblog host site! in this case i can't use cache for every page because that cause to be my Server ram full of caching page. but if I can save cache in hard disk my problem...
3
by: Smithers | last post by:
Just wondering what it would take to cache a copy of the output HTML from a dynamically constructed aspx page before it is sent to the browser. Reason being: the page is constructed of a few user...
0
by: Jordan S. | last post by:
Using .NET 3.5... in a "plain old" .aspx page I have the following code in the Init event: this.Context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));...
2
by: Ken Fine | last post by:
I have a question about ASP.NET output caching. I want to use screen scraping as a temporary hack to pull in some complex Classic ASP-rendered content into some ASP.NET pages: protected String...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.