Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list OutputCache entry

in my asp.net mvc application i'm using the OutputCache attribute on different action method. Is possible to view the current entries on the cache related to OutputCache attribute? If i cicle on System.Web.HttpContext.Current.Cache i don't find this type of entry. Thanks in advance F.

like image 469
tartafe Avatar asked Jul 01 '10 10:07

tartafe


People also ask

What is OutputCache in action filter?

In ASP.NET MVC, there is an OutputCache filter attribute that you can apply and this is the same concept as output caching in web forms. The output cache enables you to cache the content returned by a controller action. Output caching basically allows you to store the output of a particular controller in the memory.

What is OutputCache?

The output cache enables you to cache the content returned by a controller action. That way, the same content does not need to be generated each and every time the same controller action is invoked. Imagine, for example, that your ASP.NET MVC application displays a list of database records in a view named Index.

What is VaryByParam OutputCache?

It allows varying the cached output by GET query string or form POST parameters. For instance, you can vary the user-control output to the cache by specifying the user-control name along with either a query string or a form POST parameter. For more information, see Caching Multiple Versions of User Control Output.

Where is output cache stored?

The output cache is located on the Web server where the request was processed. This value corresponds to the Server enumeration value. The output cache can be stored only at the origin server or at the requesting client. Proxy servers are not allowed to cache the response.


1 Answers

Output Cache is not publicly-accessible so you will not find it in System.Web.HttpContext.Current.Cache . In ASP.NET 2 it is contained in the CacheInternal's _caches member, which you can guess by the name is a private member of an internal abstract class. It is possible to retrieve it with reflection, though it is not an easy task.

Also if you retrieve it you'll see that it contains all kinds of internal cache entries like configuration files path cache, dynamically generated classes cache, mobile capabilities, raw response cache (this one is the type of the output cache items).

Let's say that you can filter the items related to output cache. The problem is that they don't contain much human readable information apart from the key and raw response (as byte array). The key generally consists of information if GET (a1) or POST (a2) method i used, the site name, root relative url and hash of the dependent parameters.

I guess it was a common pain-point so in ASP.NET 4 a new concept of custom output cache providers was introduced. You can implement your own output cache provider inheriting from OutputCacheProvider and provide a method that returns all entries. You can check out this article - http://weblogs.asp.net/gunnarpeipman/archive/2009/11/19/asp-net-4-0-writing-custom-output-cache-providers.aspx. I personally haven't looked in the new OutputCache infrastructure, so if you find anything it will be interesting to write about it.

This is the code to retrieve the internal cache entries. You can browse their values while debugging in Visual Studio:

Type runtimeType = typeof(HttpRuntime);

PropertyInfo ci = runtimeType.GetProperty(
   "CacheInternal", 
   BindingFlags.NonPublic | BindingFlags.Static);

Object cache = ci.GetValue(ci, new object[0]);

FieldInfo cachesInfo = cache.GetType().GetField(
    "_caches", 
    BindingFlags.NonPublic | BindingFlags.Instance);
object cacheEntries = cachesInfo.GetValue(cache);

List<object> outputCacheEntries = new List<object>();

foreach (Object singleCache in cacheEntries as Array)
{
   FieldInfo singleCacheInfo =
   singleCache.GetType().GetField("_entries",
      BindingFlags.NonPublic | BindingFlags.Instance);
   object entries = singleCacheInfo.GetValue(singleCache);

   foreach (DictionaryEntry cacheEntry in entries as Hashtable)
   {
      FieldInfo cacheEntryInfo = cacheEntry.Value.GetType().GetField("_value",
         BindingFlags.NonPublic | BindingFlags.Instance);
      object value = cacheEntryInfo.GetValue(cacheEntry.Value);
      if (value.GetType().Name == "CachedRawResponse")
      { 
         outputCacheEntries.Add(value);
      }
   }
}
like image 181
Branislav Abadjimarinov Avatar answered Sep 24 '22 07:09

Branislav Abadjimarinov