【问题标题】:Use OutputCache and GetVaryByCustomString to cache same content for multiple paths使用 OutputCache 和 GetVaryByCustomString 为多个路径缓存相同的内容
【发布时间】:2017-12-15 00:28:21
【问题描述】:

我的 MVC 控制器中有以下代码:

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

我在 Global.asax.cs 类中有以下 GetVaryByCustomString 实现:

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

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

在我们的应用程序中,客户将拥有自己的子域(即 johndoe.app.comjanedoe.app.com)。

所以缓存应该因子域而异。

但是,该完全限定 URL 上的任何“路径”都应共享相同的缓存。所以下面应该读取相同的输出缓存:

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

这是一个令人筋疲力尽的原因,但简而言之,它是一个 SPA 应用程序,“路径”实际上只是一个跟踪器。这不能更改为查询字符串。

当路径(跟踪器)改变时,索引方法被新访问。我可以通过调试器告诉这一点。需要注意的是,GetVaryByCustomString 仍会被调用,但会在 Index 方法处理完毕后调用。

如何根据子域改变缓存,但不管 URL 上的路径(跟踪器)如何都使用该缓存?

如果它提供任何有益的东西,这是我的 MVC 路线:

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 版本 5.2.3、.NET 4.6.1

【问题讨论】:

  • 我不确定这是否有效,但如果您希望在索引操作之前执行 GetVaryByCustomString 作为自定义过滤器,您不能实现它吗??
  • @RAHULSR 我不这么认为。您必须在 Global.asax.cs 中覆盖它。我可以实现自定义缓存解决方案,包括动作过滤器、全局 Web 处理程序或类似的东西,但这并不理想。
  • 把它放在控制器的构造函数中怎么样?请分享你的答案我现在有点好奇
  • 只是一个建议,但您可以将子域转换为参数并在其上缓存。我找到了几个参考这个的博客。请参阅以下要点:gist.github.com/IDisposable/77f11c6f7693f9d181bb
  • @JohnBabb 是的,这就是我要做的。很高兴看到这个想法得到验证。基本上编写一个 IIS 重写规则,将路径转换为查询字符串。然后 .NET 可以使用 VaryByParam 设置从那里获取它。

标签: .net asp.net-mvc caching asp.net-mvc-5 outputcache


【解决方案1】:

您是否尝试过使用:VaryByHeader = "Host" ?

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

您可以在此处找到有关如何以不同方式执行此操作的更多信息:

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

【讨论】:

  • 按主机变化有利于按子域等变化。但这是相同的域、协议等,只是路径不同。
  • 您无法做到这一点,因为子域之后的所有内容都由您的 SPA 应用程序控制器控制。如果您在子域之后缓存了部分,则意味着您无法从 SPA 应用程序控制 url。
  • @contactmatt 我找到了这样的解决方案:techblog.dorogin.com/…。可以发反馈吗?
猜你喜欢
  • 2013-02-13
  • 1970-01-01
  • 2010-10-11
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 2011-02-01
相关资源
最近更新 更多