Response.Flush打破页面缓存

时间:2010-02-03 16:46:14

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

我有一些代码用于将某些页面输出替换为其他文本。我实现这一点的方法是将Response.Filter设置为Stream,刷新响应,然后将该Stream读回字符串。从那里我可以操纵字符串并输出结果代码。您可以在Render a view as a string找到基本代码。

但是,我注意到在第一次Response.Flush调用之后,页面缓存不再有效。

我将一个简单的ASP.NET WebApp放在一起作为示例。我有一个Default.aspx,其中@OutputCache设置为30秒。所有这一切都是输出DateTime.Now.ToLongTimeString()。我重写了渲染。如果我执行Response.Flush(即使在base.Render之后),页面也不会被缓存。这与我设置的任何程序化可缓存性无关。

所以似乎Response.Flush完全破坏了正在使用的任何页面缓存。这是为什么?

额外信用:有没有办法实现我想要的(渲染输出到字符串)不会导致页面缓存被绕过?

ASPX页面

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestCacheVsFlush._Default" %>
<%@ OutputCache Duration="30" VaryByParam="none" %>
<%= DateTime.Now.ToLongTimeString() %>

代码隐藏(页面缓存):

    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(writer);
    }

代码隐藏(页面未缓存):

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);
    Response.Flush();
}

代码隐藏(页面仍未缓存):

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);
    Response.Cache.SetCacheability(HttpCacheability.Server);
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(30));
    Response.Flush();
}

1 个答案:

答案 0 :(得分:3)

好的,我想我会给你一个部分答案。

来自here

  

输出缓存模块填充   IHttpCachePolicy内在的   BeginRequest阶段如果匹配   找到个人资料。其他模块可以   仍然改变了缓存策略   当前请求可能会改变   用户模式或内核模式缓存   行为。输出缓存高速缓存200   仅对GET请求作出回应。 如果   一些模块已经刷新了   响应时间请求到达   UpdateRequestCache阶段或标头   被抑制,响应不被缓存   在输出缓存模块中

那篇文章是特定于IIS7的,因此不确定这是如何转换为其他版本的,但它可能类似。 UpdateRequestCacheHttpApplication pipeline events之一,它发生在IHttpHandler(例如您的Page对象)处理完请求之后。

所以...在你的页面内执行同花是不合适的。