OutputCache is sending wrong Vary header when the call hits the cache

前端 未结 3 2192
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-20 06:59

I have an action method that I want to cache:

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom=\"index\")]
public ActionResult Index()
         


        
3条回答
  •  醉话见心
    2021-02-20 07:38

    I don't think the [OutputCache] attribute is what you want, the VaryByCustom method is basically saying that I want to cache different versions based on these parameters, it doesn't really have an option for Do Not Cache and the majority of the code in the attribute is built around server based caching.

    That being said the documentation on MSDN for custom caching seems to indicate you need to return a string to vary on based on the authentication state:

    public override string GetVaryByCustomString(HttpContext context, string custom)
    {
        if(custom == "user") return "User:" + context.Request.User.Identity.Name;
    
        return base.GetVaryByCustomString(context, custom);
    }
    

    And then use the user literal in the VaryByCustom:

    [OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="user")]
    public ActionResult Index()
    {
        return View();
    }
    

    So basically this would result in a cache being built for anonymous (assuming the anonymous identity is empty string or something) and every user on the server, and a Vary: * sent to the client I believe. Obviously not ideal what you are looking for.

    If you really just want to cache the unauthenticated version using HTTP caching I would recommend not using the OutputCacheAttribute and using something more custom.

    You could easily just write in your own custom attribute something like what you have for your GetVaryByCustomString implementation (this is just some pseudo code, would need more than this):

    public class HttpCacheUnauthenticatedAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            if(!filterContext.HttpContext.Request.IsAuthenticated) {
                //TODO: set unauthenticated caching values and vary here
            }
        }
    }
    

    And then tag your action method with it:

    [HttpCacheUnauthenticated]
    public ActionResult Index()
    {
        return View();
    }
    

提交回复
热议问题