8

我正在尝试实现一个 MongoDB / Memory 组合的输出缓存提供程序以与 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");
}

我的问题是,当我检查日志文件中请求的密钥时,我不仅看到了对家庭控制器的请求,还看到了所有其他路径:

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,我不知道如何指定要用于特定控制器操作的缓存提供程序。

使用 Asp.Net 网页,您可以通过<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>在页面顶部使用来完成它,但对于 MVC,我能找到的唯一解决方案是覆盖Global.asax 中的HttpApplication.GetOutputCacheProviderName 方法

有没有更优雅的方法通过使用 [OutputCache] 属性来实现这一点?

4

3 回答 3

7

有没有更优雅的方法来使用 [OutputCache] 属性设置 OutputCacheProvider?

我认为答案是否定的(当然不是当前的 mvc4 版本),因为实现自定义和使用属性OutputCacheProvider装饰动作之间没有关系。OutputCache

正如您通过实现自定义提供程序并登录Get 方法所发现的那样,您会看到对 Web 服务器发出的每个请求。如果您OutputCache要从所有操作中删除该属性,您仍然会在输出日志文件中看到每个请求。我认为这个ASP.NET MVC 的每个操作都会命中输出缓存的答案对于确认这一点非常有用。

由于看起来您只想实现一个输出缓存提供程序,那么我认为您唯一的选择是设置默认提供程序并继续覆盖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";
}
于 2012-08-13T15:08:34.187 回答
1

如果我在哪里,我会尝试编写从 OutputCachAttribute 继承的 MyOutputCachAttribute,它将通过其参数选择提供者。

于 2012-08-08T07:15:34.057 回答
0

查看 MSDN 杂志的这篇文章(源代码和引用 MongoDB 和 Azure 作为分布式缓存提供程序的示例)可能会提供一些见解http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

编辑

您可以按照此处的建议使用 CacheProfile 设置来指定提供程序吗?

http://www.dotnetcurry.com/ShowArticle.aspx?ID=665

于 2012-08-13T09:18:43.657 回答