Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use OutputCache and GetVaryByCustomString to cache same content for multiple paths

I have the following code in my MVC controller:

[HttpGet]
[OutputCache(Duration = 3600, VaryByParam = "none", VaryByCustom = "app")]
public async Task<ViewResult> Index(string r)
{
   // Stuff...
}

And I have the following implementation of GetVaryByCustomString in my Global.asax.cs class:

public override string GetVaryByCustomString(HttpContext context, string arg)
{
        switch (arg.ToLower())
        {
            case "app":
                return context.Request.Url.Host;

            default:
                return base.GetVaryByCustomString(context, arg);
        }
    }

In our application, customers will have their own subdomain (i.e. johndoe.app.com, janedoe.app.com).

So caching should vary on subdomain.

However, any "path" on that fully qualified URL should share the same cache. So the following should read the same output cache:

  • johndoe.app.com/
  • johndoe.app.com/123
  • johndoe.app.com/abc

There's an exhausting reason why this is the way it is, but in short, it's a SPA app, and the "path" is really just a tracker. This can't be changed to a query string.

When the path (tracker) changes, the index method is freshly accessed. I can tell this through the debugger. As a note, GetVaryByCustomString is still called, but it's called after the Index method has been processed.

How can I vary cache based on subdomain, but use that cache regardless of the path (tracker) on the URL?

If it offers anything benefical, here's my MVC routes:

routes.MapRoute(
            name: "Tracker",
            url: "{r}",
            defaults: new { controller = "Home", action = "Index", id = "" });

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

MVC version 5.2.3, .NET 4.6.1

like image 848
contactmatt Avatar asked Jul 11 '17 05:07

contactmatt


1 Answers

Have you tried to use: VaryByHeader = "Host" ?

[HttpGet]
[OutputCache(Duration = 3600, VaryByHeader = "Host")]
public async Task<ViewResult> Index(string r)
{
   // Stuff...
}

More information how to do this in different ways you can find here:

Output cache for multi-tenant application, varying by hostname and culture

like image 122
Artur Poniedziałek Avatar answered Sep 23 '22 04:09

Artur Poniedziałek