DCSIMG
Mvc custom ActionFilterAttribute for ajax requests caching - new { Name = ”Shay Jacoby” }

new { Name = ”Shay Jacoby” }

Maximum separation, minimum Dependencies, No Injections.

Mvc custom ActionFilterAttribute for ajax requests caching

One of the most important performance improvements issues on Web Applications is caching AJAX calls on client browser.

Faster page responses improve the client UI as well.

Since I read about this little hack of omar zabir that fixes a known .net framework Cache-Control header setting bug  I implement this solution on every project.

For Web Application I keep on using MVC Framework beta so a very elegant to implement ajax responses caching by creating a custom ActionFilterAttribute class.

Important: You can put in client side cache only Ajax "GET" requests.

the Code:

namespace Framework.Mvc.ActionFilters
{
 
    using System;
    using System.Reflection;
    using System.Web;
    using System.Web.Mvc;
 
    public class AjaxOutputCache : ActionFilterAttribute
    {
        /// <summary>
        /// Gets or sets the duration.
        /// </summary>
        /// <value>The duration.</value>
        public double Duration { get; set; }
 
        /// <summary>
        /// Called when [action executed].
        /// </summary>
        /// <param name="filterContext">The filter context.</param>
        public override void OnActionExecuted(ActionExecutedContext
 filterContext)
        {
            if (Duration <= 0) return;
            SetCache(Duration);
        }
 
 
        /// <summary>
        /// Sets cache header to client's browser.
        /// </summary>
        /// <param name="cacheDurationInMinutes" type="double">
Cache duration (in minutes).</param>
        private static void SetCache(double cacheDurationInMinutes)
        {
            TimeSpan duration = 
TimeSpan.FromMinutes(cacheDurationInMinutes);
            HttpCachePolicy cache = 
HttpContext.Current.Response.Cache;
            cache.SetCacheability(HttpCacheability.Public);
            cache.SetExpires(DateTime.Now.Add(duration));
            cache.SetMaxAge(duration);
            cache.AppendCacheExtension("must-revalidate, 
proxy-revalidate");
            FieldInfo maxAgeField = cache.GetType().GetField(
"_maxAge", BindingFlags.Instance | BindingFlags.NonPublic);
            maxAgeField.SetValue(cache, duration);
 
        }
 
    }
}

 Example usage:

 /// <summary>
 /// Find client data by specifies client id.
 /// </summary>
 /// <param name="id" type="string">client unique 
identifier.</param>
 /// <returns>results in json format.</returns>
 [AjaxOutputCache(Duration = 10)]
 public JsonResult Show(string id)
 {
   id = id.DecodeUrl();
   var item = _client.FindBy(id);
   return Json(item);
}

once this method is executed, it's results is cached by the client browser for 10 minutes (see the attribute: (Duration = 10)).

I checked the http protocol with fiddler on IE and firebug on FF and I saw that the the first request has status code 200 (OK) and takes about 3 seconds, the next request (with same parameter) take 2-3 milliseconds and not served by IIS at all.

 

I attched the class as attachment.
Good Luck.

Shay

תוכן התגובה

ASP.NET MVC Archived Blog Posts, Page 1 כתב/ה:

Pingback from  ASP.NET MVC Archived Blog Posts, Page 1

# December 5, 2008 11:41 PM

Avi Pinto כתב/ה:

very nice

thanks

# December 6, 2008 4:45 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 8 and 5 and type the answer here:


Enter the numbers above: