juristr
1/25/2013 - 10:02 AM

EnhancedOutputCacheAttribute.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Juristr.Mvc
{
    /// <summary>
    /// Custom OutputCache to overcome a bug in IE8:
    /// - http://support.microsoft.com/kb/316431
    /// - http://blogs.msdn.com/b/ieinternals/archive/2009/10/02/internet-explorer-cannot-download-over-https-when-no-cache.aspx
    /// - http://stackoverflow.com/questions/13119340/ie6-8-unable-to-download-file-from-https-site
    /// </summary>
    public class EnhancedOutputCacheAttribute : OutputCacheAttribute
    {

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {

            if (!IsFileResultAndOldIE(filterContext))
                base.OnActionExecuted(filterContext);
            else
            {
                //try the best to avoid any kind of caching
                filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
                filterContext.HttpContext.Response.Cache.SetMaxAge(new TimeSpan(0));
                filterContext.HttpContext.Response.Cache.SetExpires(DateTime.Now.AddMinutes(-5D));
            }
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!IsFileResultAndOldIE(filterContext))
                base.OnActionExecuting(filterContext);
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (!IsFileResultAndOldIE(filterContext))
                base.OnResultExecuted(filterContext);
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            if (!IsFileResultAndOldIE(filterContext))
                base.OnResultExecuting(filterContext);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="filterContext"></param>
        /// <returns><c>true</c> for FileResults and if the browser is < IE9</returns>
        private bool IsFileResultAndOldIE(dynamic filterContext)
        {
            return filterContext.Result is FileResult &&
                   filterContext.HttpContext.Request.IsSecureConnection &&
                   string.Equals(filterContext.HttpContext.Request.Browser.Browser, "IE", StringComparison.OrdinalIgnoreCase) &&
                   filterContext.HttpContext.Request.Browser.MajorVersion < 9;
        }

    }
}