2011-07-06 33 views
0

之前执行rewiter HTTP模块我已经开发了处理.aspx页面中(它只是设置app.Response.Filter做一些简单的字符串替换),它是由ASP.NET呈现后自定义HTTP模块。它正在完美运行,但我遇到了一个小问题 - OutputCache HTTP模块不会缓存我使用app.Response.Filter所做的更改。的OutputCache

由于性能上的好处,我会喜欢,如果它是反向字符串替换和输出缓存的某种可能性。

那么,有没有办法做到这一点?使用HttpHandlers是否会走?

这里是替代品的电流源代码:

public class StringReplaceModule : IHttpModule 
{ 
    void IHttpModule.Dispose() 
    { 
     // Nothing to dispose; 
    } 

    void IHttpModule.Init(HttpApplication context) 
    { 
     context.PreSendRequestHeaders += 
      (sender, e) => HttpContext.Current.Response.Headers.Remove("Server"); 

     context.BeginRequest += new EventHandler(context_BeginRequest); 
    } 

    void context_BeginRequest(object sender, EventArgs e) 
    { 
     HttpApplication app = sender as HttpApplication; 
     string url = app.Request.RawUrl.ToLower(); 
     if (!url.Contains(".aspx/") && 
      (url.Contains(".aspx") || url.Contains(".css") || url.Contains("/shorturl/"))) 
     { 
      app.Response.Filter = new StringReplaceFilter(app.Response.Filter); 
     } 
    } 

    #region Stream filter 

    private class StringReplaceFilter : Stream 
    { 
     public StringReplaceFilter(Stream sink) 
     { 
      _sink = sink; 
     } 

     private Stream _sink; 
     private static string[] find; 
     private static string[] replace; 
     static StringReplaceFilter() 
     { 
      var config = StringReplaceModuleConfig.CurrentConfigSection(); 

      find = config.Find.ToArray(); 
      replace = config.Replace.ToArray(); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      byte[] data = new byte[count]; 
      Buffer.BlockCopy(buffer, offset, data, 0, count); 
      string html = System.Text.Encoding.Default.GetString(buffer); 

      for (int i = 0; i < find.Length; i++) 
      { 
       html = html.Replace(find[i], replace[i]); 
      } 

      byte[] outdata = System.Text.Encoding.Default.GetBytes(html); 
      _sink.Write(outdata, 0, outdata.GetLength(0)); 
     } 


     #region Less Important 

     public override bool CanRead 
     { 
      get { return true; } 
     } 

     public override bool CanSeek 
     { 
      get { return true; } 
     } 

     public override bool CanWrite 
     { 
      get { return true; } 
     } 

     public override void Flush() 
     { 
      _sink.Flush(); 
     } 

     public override long Length 
     { 
      get { return 0; } 
     } 

     private long _position; 
     public override long Position 
     { 
      get { return _position; } 
      set { _position = value; } 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      return _sink.Read(buffer, offset, count); 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      return _sink.Seek(offset, origin); 
     } 

     public override void SetLength(long value) 
     { 
      _sink.SetLength(value); 
     } 

     public override void Close() 
     { 
      _sink.Close(); 
     } 

     #endregion 
    } 
    #endregion 
} 

回答

1

可以粘贴的,你在这里做什么一些示例代码?

这听起来像你正试图找到别的东西代替某个单词/关键字的任何实例,如果你在输出找到它的方法吗?

你可以尝试这样做http://forums.asp.net/t/1123505.aspx并增加了明确的到期而不是使用同样asp.net

using System; 
using System.Web; 

namespace TT.Web.HttpModules 
{ 
     /// <summary> 
     /// HttpModule to prevent caching 
     /// </summary> 
     public class NoCacheModule : IHttpModule 
     { 
     public NoCacheModule() 
     { 
     } 

     #region IHttpModule Members 

     public void Init(HttpApplication context) 
     { 
      context.EndRequest += (new EventHandler(this.Application_EndRequest)); 
     } 

     public void Dispose() 
     { 
     } 

     private void Application_EndRequest(Object source, EventArgs e) 
     { 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      context.Response.Cache.SetLastModified(DateTime.Now); 
      context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(GetExpiryTime())); 
      context.Response.Cache.SetCacheability(HttpCacheability.Public); 
      context.Response.Cache.AppendCacheExtension("post-check=7200"); 
     //The pre-check is in seconds and the value configured in web.config is in minutes. So need to multiply it with 60 
      context.Response.Cache.AppendCacheExtension("pre-check=" + (GetExpiryTime() * 60).ToString()); 
      context.Response.CacheControl = "public"; 
     } 

     #endregion 
    } 
} 
  • 的输出缓存设施 - 这是页面加载只有一次?或在回发?
+0

贴出的源代码;关于明确过期的想法是有趣的......会考虑如果我能以某种方式使用它。 – kape123

1

Response.Filter过滤器,以便通过当时的页面已经生成,并(缓存,)准备发出的输出流。

您必须向自己的过滤器添加自定义缓存(会影响每次点击的性能),或者让您的模块挂钩到生命周期早期的事件中,例如UpdateRequestCache,以便替换字符串只会在内容前发生一次被缓存。

+0

我还可以使用app.Response.Filter吗?或者我需要改变逻辑?我发布了源代码,并很乐意听到您对此有何评论。 – kape123