我有一个包含<% Html.RenderAction<MyController>(c => c.SidebarStats()); %>
的ViewPage。在操作SidebarStats的控制器操作上,我有一个OutputCache操作过滤器,只缓存页面的那一部分。但是,整个页面都被缓存,而不仅仅是那个动作。
我记得在某个地方看到这可能是ASP.NET MVC的一个错误,虽然我不确定。我目前正在使用ASP.NET MVC RC1,IIS7,Windows Server 2008和.NET 3.5 SP1。
答案 0 :(得分:10)
我在博客solution to this problem here上写了一篇文章。它很简单,但只有在使用WebFormViewEngine时才有效。我们将仔细研究如何使其适用于所有视图引擎。
答案 1 :(得分:2)
根据微软的说法,这是一个已知的错误,没有已知的修复程序。建议的解决方法是创建自己的OutputCache操作过滤器。
答案 2 :(得分:0)
我现在正在使用his blog中制作的 Steve Sanderson ,这非常好:
public class ActionOutputCacheAttribute : ActionFilterAttribute
{
// This hack is optional; I'll explain it later in the blog post
private static readonly MethodInfo _switchWriterMethod = typeof (HttpResponse).GetMethod("SwitchWriter",
BindingFlags.Instance |
BindingFlags.NonPublic);
private readonly int _cacheDuration;
private string _cacheKey;
private TextWriter _originalWriter;
public ActionOutputCacheAttribute(int cacheDuration)
{
_cacheDuration = cacheDuration;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
_cacheKey = ComputeCacheKey(filterContext);
var cachedOutput = (string) filterContext.HttpContext.Cache[_cacheKey];
if (cachedOutput != null)
filterContext.Result = new ContentResult {Content = cachedOutput};
else
_originalWriter =
(TextWriter)
_switchWriterMethod.Invoke(HttpContext.Current.Response,
new object[] {new HtmlTextWriter(new StringWriter())});
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (_originalWriter != null) // Must complete the caching
{
var cacheWriter =
(HtmlTextWriter)
_switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] {_originalWriter});
string textWritten = (cacheWriter.InnerWriter).ToString();
filterContext.HttpContext.Response.Write(textWritten);
filterContext.HttpContext.Cache.Add(_cacheKey, textWritten, null,
DateTime.Now.AddSeconds(_cacheDuration), Cache.NoSlidingExpiration,
CacheItemPriority.Normal, null);
}
}
private string ComputeCacheKey(ActionExecutingContext filterContext)
{
var keyBuilder = new StringBuilder();
foreach (var pair in filterContext.RouteData.Values)
keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
foreach (var pair in filterContext.ActionParameters)
keyBuilder.AppendFormat("ap{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
return keyBuilder.ToString();
}
}
请访问Steve Sanderson blog's article了解详情。