9

output cache is implemented in ASP.NET MVC2 using code below.

GetVaryByCustomString method is not called: placing breakpoint to its first line and running application shows that breakpoint is not reached. Breakpoint in controller Index() is reached.

How to use VaryByCustom in ASP.NET MVC2 ?

Controller:

        [OutputCache(VaryByCustom = "user")]
        public ActionResult Index(string _entity, string id)
        {
...

Global.asax.cs:

public class MvcApplication : System.Web.HttpApplication
{
    public  override string GetVaryByCustomString(HttpContext context, string arg)
    {
        if (arg == "user")
        {
            HttpCookie cookie = context.Request.Cookies["Company"];
            if (cookie != null)
                return Thread.CurrentPrincipal.Identity.Name + "," + cookie.Value;
            return Thread.CurrentPrincipal.Identity.Name;
        }
        return base.GetVaryByCustomString(context, arg);
    }

}
Mrchief
  • 75,126
  • 20
  • 142
  • 189
Andrus
  • 26,339
  • 60
  • 204
  • 378

3 Answers3

10

Your OutputCache definition is wrong. You must specify the Duration:

[OutputCache(VaryByCustom = "user", Duration = 50)]
public ActionResult Index(string _entity, string id)

Now your overridden GetVaryByCustomString method will be called. Also don't forget that the GetVaryByCustomString method will be called only after the controller action has finished executing.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Thank you. After adding this Vary:* header is sent to browser and this disables browser cache. How to enable browser cache with VaryByCustom? – Andrus Oct 17 '12 at 10:09
2

I just want to mention 2 other causes

If there is any [NoCache] attribute in project, GetVaryByCustomString will not fire.

If you put

Location = OutputCacheLocation.Client, 

GetVaryByCustomString will not fire.

Roope Hakulinen
  • 7,326
  • 4
  • 43
  • 66
Lara G
  • 23
  • 2
1

A project that I worked on recently had a global filter preventing output caching from working:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new NoCacheResponseAttribute());
    }
}

public class NoCacheResponseAttribute : BaseActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
       var response = filterContext.RequestContext.HttpContext.Response;
       response.Cache.SetCacheability(HttpCacheability.NoCache);
       response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
       response.Cache.SetNoStore();
    }
}

After commenting the line which adds the filter, output caching started working as expected.

JCallico
  • 1,446
  • 18
  • 25