【发布时间】: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.com、janedoe.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