我正在尝试实现一个 MongoDB/内存组合输出缓存提供程序以与 MVC4 一起使用。这是我的初步实现:
public class CustomOutputCacheProvider : OutputCacheProvider
{
public override object Get(string key)
{
FileLogger.Log(key);
return null;
}
public override object Add(string key, object entry, DateTime utcExpiry)
{
return entry;
}
public override void Set(string key, object entry, DateTime utcExpiry)
{
}
public override void Remove(string key)
{
}
}
还有我的网络配置条目:
<caching>
<outputCache defaultProvider="CustomOutputCacheProvider">
<providers>
<add name="CustomOutputCacheProvider" type="MyApp.Base.Mvc.CustomOutputCacheProvider" />
</providers>
</outputCache>
</caching>
以及 HomeController 中的用法:
[OutputCache(Duration = 15)]
public ActionResult Index()
{
return Content("Home Page");
}
我的问题是,当我检查所请求 key 的日志文件时,我不仅看到了对家庭 Controller 的请求,还看到了所有其他路径:
a2/ <-- should only log this entry
a2/test
a2/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d.jpg
a2/scripts/jquery-1.7.2.min.js
我认为我不应该将 CustomOutputCacheProvider 设置为 Web.Config 中的 defaultProvider,我想不通的是如何指定我想用于特定 Controller 操作的缓存提供程序。
对于 Asp.Net 网页,您可以使用 <%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>
来完成它在页面顶部,但对于 MVC,我能找到的唯一解决方案是覆盖 HttpApplication.GetOutputCacheProviderName Method在 Global.asax 中。
是否有更优雅的方法通过使用 [OutputCache] 属性来完成此操作?
最佳答案
Is there a more elegant way to set the OutputCacheProvider using the [OutputCache] attribute?
我认为答案是否定的(当前的 mvc4 版本不是),因为在实现自定义 OutputCacheProvider
和使用 OutputCache
装饰 Action 之间没有任何关系属性。
正如您通过在 Get 方法中实现自定义提供程序和日志记录 所发现的那样,您会看到对 Web 服务器发出的每个请求。如果您要从所有操作中删除 OutputCache
属性,您仍会在输出日志文件中看到每个请求。我想到了这个 ASP.NET MVC hits outputcache for every action 的答案对确认这一点非常有用。
因为看起来您只想实现一个输出缓存提供程序,所以我认为您唯一的选择是不设置默认提供程序并继续覆盖 GetOutputCacheProviderName
实现(正如您已经提到的)。也许这样可以排除所有内容、图像 和脚本
public override string GetOutputCacheProviderName(HttpContext context)
{
string absolutePath = context.Request.Url.AbsolutePath;
if (absolutePath.StartsWith("/Content/", StringComparison.CurrentCultureIgnoreCase)
|| absolutePath.StartsWith("/Scripts/", StringComparison.CurrentCultureIgnoreCase)
|| absolutePath.StartsWith("/Images/", StringComparison.CurrentCultureIgnoreCase))
return base.GetOutputCacheProviderName(context);
return "CustomOutputCacheProvider";
}
如果您需要实现多个输出缓存提供程序,那么我想您必须实现一个助手来为您提供正确的提供程序名称。但这里有一个例子,我已经为你解决了路由数据;上一个示例直接查看 url。
public override string GetOutputCacheProviderName(HttpContext context)
{
RouteCollection rc = new RouteCollection();
MvcApplication.RegisterRoutes(rc);
RouteData rd = rc.GetRouteData(new HttpContextWrapper(HttpContext.Current));
if (rd == null)
return base.GetOutputCacheProviderName(context);
var controller = rd.Values["controller"].ToString();
var action = rd.Values["action"].ToString();
if (controller.Equals("Content", StringComparison.CurrentCultureIgnoreCase)
|| controller.Equals("Scripts", StringComparison.CurrentCultureIgnoreCase)
|| controller.Equals("Images", StringComparison.CurrentCultureIgnoreCase))
return base.GetOutputCacheProviderName(context);
if (controller.Equals("Account", StringComparison.CurrentCultureIgnoreCase))
return "AccountOutputCacheProvider";
if (controller.Equals("Something", StringComparison.CurrentCultureIgnoreCase))
return controller + "OutputCacheProvider";
return "CustomOutputCacheProvider";
}
关于c# - 为特定 Controller 操作选择自定义输出缓存提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11818528/