选择自定义输出缓存提供特定的控制器操作 [英] Selecting custom output cache provider for specific controller actions

查看:175
本文介绍了选择自定义输出缓存提供特定的控制器操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现的MongoDB /内存组合输出缓存提供与MVC4使用。这是我最初的实现:

 公共类CustomOutputCacheProvider:OutputCacheProvider
{
    公众覆盖对象获取(字符串键)
    {
        FileLogger.Log(键);
        返回null;
    }    公众覆盖对象添加(字符串键,对象条目,日期utcExpiry)
    {
        返回进入;
    }    公共覆盖无效设置(字符串键,对象条目,日期utcExpiry)
    {
    }    公共覆盖无效删除(字符串键)
    {
    }
}

和我的web配置项:

 <&缓存GT;
  <的OutputCache defaultProvider =CustomOutputCacheProvider>
    <供应商>
      <添加名称=CustomOutputCacheProviderTYPE =MyApp.Base.Mvc.CustomOutputCacheProvider/>
    < /供应商>
  < /&的OutputCache GT;
< /缓存>

和的HomeController中的用法:

  [的OutputCache(持续时间= 15)]
公众的ActionResult指数()
{
    返回的内容(主页);
}

我的问题是,当我检查日志文件的请求的钥匙,我看到的不仅是请求家居控制器,但所有其他路径,以及:

  A2 /<  - 只应登录该条目
A2 /测试
A2 /图像/测试/ 50115c53 / 1f37e409 / 4c7ab27d / 50115c531f37e4094c7ab27d.jpg
A2 /脚本/ jQuery的,1.7.2.min.js

我已经想通,我不应该设置CustomOutputCacheProvider为defaultProvider在Web.Config中,我无法弄清楚是如何指定我想用一个特定的控制器动作缓存提供商。

%@的OutputCache时间=60的VaryByParam =无的providerName =DiskCache%&GT; 通过Asp.Net网页,你可以使用&LT完成它>在页面的顶部,但对于MVC我能找到的唯一的解决办法是覆盖<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.httpapplication.getoutputcacheprovidername.aspx\"相对=nofollow> HttpApplication.GetOutputCacheProviderName方法在Global.asax中。

有没有使用[的OutputCache]属性做到这一点?一个更优雅的方式。


解决方案

  

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


我想答案是否定的,(当然不是当前mvc4发布),因为有实现自定义的 OutputCacheProvider 装潢用一个动作<之间没有任何关系code>的OutputCache 属性。

当你通过实现自定义的提供者和中看到到Web服务器的每个请求的Get方法登录的发现。如果你是从你所有的行动中删除的OutputCache 属性,你仍然会看到出日志文件中的每个请求。我想这个答案ASP.NET MVC命中的OutputCache为是pretty确认有用的每一个动作。

因为它看起来像你只是想实现一个输出缓存提供那么我认为你唯一的选择是的的设置默认的供应商,并继续覆盖 GetOutputCacheProviderName 实现(因为你已经提到)。也许这样的事情排除所有的内容图片的和的脚本

 公众覆盖字符串GetOutputCacheProviderName(HttpContext的背景下)
{
    字符串absolutePath = context.Request.Url.AbsolutePath;    如果(absolutePath.StartsWith(/内容/,StringComparison.CurrentCultureIgnoreCase)
        || absolutePath.StartsWith(/脚本/,StringComparison.CurrentCultureIgnoreCase)
        || absolutePath.StartsWith(/图片/,StringComparison.CurrentCultureIgnoreCase))
        返回base.GetOutputCacheProviderName(上下文);    返回CustomOutputCacheProvider
}

如果你需要实现多个输出缓存提供那么我想你必须实现一个助​​手给你正确的提供程序名称。但在这里,我已经解决了您的路由数据的例子;其中,作为$ P $光伏例如在URL直接看了。

 公众覆盖字符串GetOutputCacheProviderName(HttpContext的背景下)
{
    RouteCollection RC =新RouteCollection();
    MvcApplication.RegisterRoutes(RC);
    RD的RouteData = rc.GetRouteData(新HttpContextWrapper(HttpContext.Current));    如果(RD == NULL)
        返回base.GetOutputCacheProviderName(上下文);    。VAR控制器= rd.Values​​ [控制器]的ToString();
    VAR行动= rd.Values​​ [行动]的ToString()。    如果(controller.Equals(内容,StringComparison.CurrentCultureIgnoreCase)
        || controller.Equals(脚本,StringComparison.CurrentCultureIgnoreCase)
        || controller.Equals(图像,StringComparison.CurrentCultureIgnoreCase))
        返回base.GetOutputCacheProviderName(上下文);    如果(controller.Equals(账户,StringComparison.CurrentCultureIgnoreCase))
        返回AccountOutputCacheProvider
    如果(controller.Equals(东西,StringComparison.CurrentCultureIgnoreCase))
        返回控制器+OutputCacheProvider    返回CustomOutputCacheProvider
}

I'm trying to implement a MongoDB / Memory combined Output Cache Provider to use with 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:

[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.

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.

Is there a more elegant way to accomplish this by using the [OutputCache] attribute?

解决方案

Is there a more elegant way to set the OutputCacheProvider using the [OutputCache] attribute?

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.

As you discovered by implementing the custom provider and logging in the Get method you see every request made to the web server. If you were to remove the OutputCache attribute from all your actions you will still see every request in out log file. I thought the answer for this ASP.NET MVC hits outputcache for every action was pretty useful to confirm that.

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

这篇关于选择自定义输出缓存提供特定的控制器操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆