简体   繁体   English

为特定控制器操作选择自定义输出缓存提供程

[英]Selecting custom output cache provider for specific controller actions

I'm trying to implement a MongoDB / Memory combined Output Cache Provider to use with MVC4. 我正在尝试实现MongoDB / Memory组合输出缓存提供程序以与MVC4一起使用。 Here is my initial implementation: 这是我最初的实现:

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)
    {
    }
}

And my web config entry: 我的网络配置条目:

<caching>
  <outputCache defaultProvider="CustomOutputCacheProvider">
    <providers>
      <add name="CustomOutputCacheProvider" type="MyApp.Base.Mvc.CustomOutputCacheProvider" />
    </providers>
  </outputCache>
</caching>

And the usage within HomeController: 以及HomeController中的用法:

[OutputCache(Duration = 15)]
public ActionResult Index()
{
    return Content("Home Page");
}

My problem is, when I check the logfile for the keys that are requested, I see not only the request to home controller, but all other paths as well: 我的问题是,当我检查日志文件中所请求的密钥时,我不仅看到了对主控制器的请求,还看到了所有其他路径:

a2/  <-- should only log this entry
a2/test
a2/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d.jpg
a2/scripts/jquery-1.7.2.min.js

I've figured that I shouldn't set the CustomOutputCacheProvider as the defaultProvider in Web.Config, what I couldn't figure out is how to specify the cache provider that I want to use for a specific controller action. 我想我不应该将CustomOutputCacheProvider设置为Web.Config中的defaultProvider,我无法弄清楚如何指定我想用于特定控制器操作的缓存提供程序。

With Asp.Net Web Pages you can accomplish it by using <%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %> at the top of the page, but for MVC the only solution I could find is to override HttpApplication.GetOutputCacheProviderName Method in Global.asax. 使用Asp.Net网页,您可以通过在页面顶部使用<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>来完成它,但对于MVC,我能找到的唯一解决方案是覆盖Global.asax中的HttpApplication.GetOutputCacheProviderName方法

Is there a more elegant way to accomplish this by using the [OutputCache] attribute? 有没有更优雅的方法来使用[OutputCache]属性来实现这一目标?

Is there a more elegant way to set the OutputCacheProvider using the [OutputCache] attribute? 是否有更优雅的方法使用[OutputCache]属性设置OutputCacheProvider?

I think the answer is no, (well not with the current mvc4 release) since there is no relationship between implementing a custom OutputCacheProvider and decorating an action with the OutputCache attribute. 我认为答案是否定的(当前mvc4版本没有),因为实现自定义OutputCacheProvider和使用OutputCache属性修饰操作之间没有任何关系。

As you discovered by implementing the custom provider and logging in the Get method you see every request made to the web server. 正如您通过实现自定义提供程序并登录 Get方法所发现的那样,您会看到对Web服务器发出的每个请求。 If you were to remove the OutputCache attribute from all your actions you will still see every request in out log file. 如果要从所有操作中删除OutputCache属性,您仍将在out日志文件中看到每个请求。 I thought the answer for this ASP.NET MVC hits outputcache for every action was pretty useful to confirm that. 我认为这个ASP.NET MVC的答案会针对每个动作点击outputcache ,这对确认它非常有用。

Since it looks like you only want to implement one output-cache provider then I think your only option is to not set the default provider and continue to override the GetOutputCacheProviderName implementation (as you have already mentioned). 由于看起来您只想实现一个输出缓存提供程序,因此我认为您唯一的选择是设置默认提供程序并继续覆盖GetOutputCacheProviderName实现(如您所述)。 Perhaps something like this to exclude all Content , Images and Scripts 也许这样排除所有内容图像脚本

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";
}

If you need to implement more than one output-cache provider then I guess you'll have to implement a helper to give you the correct provider name. 如果您需要实现多个输出缓存提供程序,那么我猜您必须实现一个帮助程序才能为您提供正确的提供程序名称。 But here's an example where I've resolved the routing data for you; 但是这里有一个例子,我已经为你解决了路由数据; where as the prev example looked directly at the 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";
}

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

Check this article from MSDN Magazine (with source code and examples referencing MongoDB & Azure as distributed cache providers) may well provide some insight http://msdn.microsoft.com/en-us/magazine/gg650661.aspx 查看MSDN杂志上的这篇文章(源代码和示例引用MongoDB和Azure作为分布式缓存提供程序)可能会提供一些见解http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

EDIT 编辑

Can you use the CacheProfile setting to specify the provider as suggested here? 您是否可以使用CacheProfile设置来指定此处建议的提供程序?

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM