Asp.Net MVC 3部分页面输出缓存不符合配置设置

时间:2011-01-25 19:31:34

标签: .net asp.net-mvc iis caching

我有一个简单的局部视图,我在主视图中使用:

进行渲染
 @Html.Action("All", "Template")

在我的控制器上我有这个:

    [OutputCache(CacheProfile = "Templates")]
    public ActionResult All()
    {
        return Content("This stinks.");
    }

在我的配置中:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <clear/>
      <add name="Templates" duration="3600" varyByParam="none"/>       
    </outputCacheProfiles>
  </outputCacheSettings>
  <outputCache  enableOutputCache="false" enableFragmentCache="false" />
</caching>

这将在运行时失败,但异常:

  

执行处理程序'System.Web.Mvc.HttpHandlerUtil + ServerExecuteHttpHandlerAsyncWrapper

的子请求时出错

内在异常:

  

持续时间必须为正数

现在显然它没有拿起我的web.config设置,因为如果我将其更改为:

[OutputCache(Duration = 3600)]

它会起作用,但在我的web.config中也会注意到我关闭了 enableOutputCache enableFragmentCache ,但是它没有遵循这些设置。

奇怪的是,在普通视图中这些设置工作正常,那么部分视图是什么打破了这个呢?我错过了什么吗? The Gu says this should work just fine... 简而言之,是否应该尊重web.config中的缓存设置,如果没有,为什么不呢?

2 个答案:

答案 0 :(得分:5)

所以我花了一分钟看了MVC 3的来源。我遇到的第一件事就是这个功能看起来有些笨拙。主要是因为他们正在重用一个属性,该属性在一种情况下适用于所有属性和配置设置,然后在子操作场景中忽略所有这些设置并仅允许 VaryByParam 持续时间即可。

如何确定支持的内容超出了我的范围。因为除非您提供持续时间和 VaryByParam

,否则他们想要抛出的不支持的设置的例外将永远不会被抛出

这是代码的主要代码:

if (Duration <= 0) {
    throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidDuration);
}

if (String.IsNullOrWhiteSpace(VaryByParam)) {
    throw new InvalidOperationException(MvcResources.OutputCacheAttribute_InvalidVaryByParam);
}

if (!String.IsNullOrWhiteSpace(CacheProfile) ||
    !String.IsNullOrWhiteSpace(SqlDependency) ||
    !String.IsNullOrWhiteSpace(VaryByContentEncoding) ||
    !String.IsNullOrWhiteSpace(VaryByHeader) ||
    _locationWasSet || _noStoreWasSet) {
    throw new InvalidOperationException(MvcResources.OutputCacheAttribute_ChildAction_UnsupportedSetting);
}

我不确定为什么在documentation中没有调用它,但即使它是api也应该说清楚,或者至少抛出正确的异常。

简而言之,部分输出缓存有效,但不像你想要的那样。我将努力修复代码并兑现一些设置,例如启用

<强>更新 我将当前的实现修复为至少适用于我的情况,尊重启用标志并允许来自web.config的缓存配置文件。 Detailed in my blog post.

答案 1 :(得分:0)

如果出现以下情况,这是一种更简单的方法:

  • 您的基本目标是能够在调试期间禁用缓存在部署期间启用它
  • 您没有复杂的缓存政策
  • 您没有复杂的部署系统依赖于Web.config的缓存语法
  • 非常适合使用XDT web transformations已经

我所做的只是创建了一个新属性'DonutCache'。

[DonutCache]
public ActionResult HomePageBody(string viewName)
{
    var model = new FG2HomeModel();

    return View(viewName, model);
}

不幸的是,您只能使用常量初始化[Attribute],因此您需要在其构造函数中初始化该属性。 注意:这不会阻止您在[DonutCache]声明中设置'varyByParam'。

class DonutCacheAttribute : OutputCacheAttribute
{
    public DonutCacheAttribute()
    {
        Duration = Config.DonutCachingDuration;
    }
}

这里我只是通过静态属性从web.config初始化属性:

<appSettings>
    <add key="DonutCachingDuration" value="5"/> 
</appSettings>


public static class Config {
    public static int DonutCachingDuration
    {
        get
        {
            return int.Parse(ConfigurationManager.AppSettings["DonutCachingDuration"]);
        }
    }
}

当然,你可以使用你已经用来改变这个值的XDT网页转换