3

I've got a problem using outputcache together with urlrewriting. We've got an application that rewrites url (IE http://localhost/about/) to "~/page.aspx". Based on the URL (/about/) we figure out which content to show.

Now we're trying to add outputcache to that page:

< %@ outputcache duration="600" location="Server" varybyparam="Custom" varybycustom="RawURL" %>

And in the Global.asax we override GetVaryByCustomString like below:

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom == "RawUrl")
    {
        return context.Request.RawUrl;
    }
    else
    {
        return string.Empty;
    }
}

However, when we publish the page i'd like to invalidate the cache so that the editors see the change directly. But no matter what I try, I cannot seem to invalidate the cache. If I'd like to invalidate "/about/" I would like to do this:

HttpResponse.RemoveOutputCacheItem("/about/");

That doesn't work unfortunately. The only thing that seems to work is:

HttpResponse.RemoveOutputCacheItem("/page.aspx");

This clears the cache for all my pages, not just "/about/".

Is there any way to invalidate the cache based on the url? Or should we provide a cache key or something per page to be able to invalidate the cache programmatically?

Thanks in advance!

Asphyxion
  • 31
  • 3
  • I'm guessing that the part of the asp.net engine which takes care of purging the cache is not aware of your rewrite scheme, and thus you have to use an actual file name. – Elad Lachmi Mar 31 '11 at 07:17
  • Yes. Fair enough. So is there another option? Like use the id of the page as a cache key? Most rewrite examples I see rewrite to "page.aspx?id=x", this is not what we do. – Asphyxion Mar 31 '11 at 11:03
  • I understand what your looking to do, but I am very skeptical if it's possible. Unless you want to implement the RemoveOutputCacheItem yourself :) Maybe you can create an enum to map keys to physical files. – Elad Lachmi Mar 31 '11 at 11:27
  • 1
    Actually, I just did that. And it works: `response.AddCacheItemDependency(currentCategoryGuid);` I do this in the "/page.aspx" where currentCategoryGuid is an string and guid of the current page (ie of /about/). When publishing I do: `HttpResponse.RemoveOutputCacheItem(currentCategoryGuid);` This removes it from the cache. Actually quite simple. :) – Asphyxion Mar 31 '11 at 11:30

2 Answers2

0

I've solved with using following link. http://www.superstarcoders.com/blogs/posts/making-asp-net-output-cache-work-with-post-back.aspx

Basically on my usercontrol;

protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        if (Request.QueryString["url"] == null)
            return;
        string url = "www." + Request.QueryString["url"].ToString().Replace("http://", "").Replace("https://", "").Replace("www.", "").ToLower();


        Response.AddCacheItemDependency(url);
    }
Sam Salim
  • 2,145
  • 22
  • 18
0

You don't need to invalidate the cache. You can tell the server to not use the cache for certain requests.

To do this in your page load add this

Response.Cache.AddValidationCallback((ValidateCache), Session);

Then add this method to tell app whether use what is in the output cache for the current request

    public static void ValidateCache(HttpContext context, Object data, ref HttpValidationStatus status)
    {

        bool isEditor = /*assignment here*/;
        if (!isEditor)
        {
            status = HttpValidationStatus.Valid;
        }
        else
        {
            status = HttpValidationStatus.IgnoreThisRequest;
        }
    }

If you do not want a certain request to be cached for other users to see use the following

 Response.Cache.SetCacheability(HttpCacheability.NoCache);
danielfishr
  • 879
  • 6
  • 9
  • This isn't really an option, since we're serving around 10.000 pages through "/page.aspx". using outputcache makes the app so much faster, so we would like to use it for all pages, and invalidate/remove the cache per page when something is republished. – Asphyxion Mar 31 '11 at 11:01