2013-07-11 109 views
2

给出的通用处理器:ASP.net缓存ASHX文件服务器端

<%@ WebHandler Language="C#" Class="autocomp" %> 

using System; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Web; 
using System.Web.UI; 

public class autocomp : IHttpHandler { 

    public void ProcessRequest (HttpContext context) { 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim(); 

     context.Response.Write(searchTerm); 
     context.Response.Write(DateTime.Now.ToString("s")); 

     context.Response.Flush(); 
    } 

    public bool IsReusable { 
     get { 
      return false; 
     } 
    } 

} 

我怎么会server side缓存文件1小时基础上,name_startsWith查询字符串参数?随着网络用户控制它很简单:

<%@ OutputCache Duration="120" VaryByParam="paramName" %> 

但我一直在寻找了一段时间做同样的与通用处理器(ashx)文件并不能找到任何解决方案。

+0

你会在客户端上使用[这个东西(缓存http://stackoverflow.com/questions/1109768/how-to-use-output-caching-on -ashx-handler),然后在您要获取数据时使用HttpContext.Cache将实际数据用于服务器端缓存。但是你不能为此使用任何类型的输出缓存。此外,请记住确保您的HttpContext.Cache代码是线程安全的。 ;) – Tombala

+0

在下面编辑我的答案以回答对帖子的更改。 –

回答

7

使用您提供的代码,您告诉最终用户浏览器将结果缓存30分钟,因此您没有执行任何服务器端缓存。

如果你想缓存结果服务器端,你可能会寻找HttpRuntime.Cache。这将允许您将项目插入全局可用的缓存中。然后在页面加载时,您需要检查缓存项目的存在,然后如果该项目不存在或在缓存中过期,请转至数据库并检索对象。

编辑

有了更新的代码示例中,我发现https://stackoverflow.com/a/6234787/254973这在我的测试工作。所以在你的情况下,你可以这样做:

public class autocomp : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters 
     { 
      Duration = 120, 
      Location = OutputCacheLocation.Server, 
      VaryByParam = "name_startsWith" 
     }); 

     page.ProcessRequest(HttpContext.Current); 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim(); 

     context.Response.Write(searchTerm); 
     context.Response.Write(DateTime.Now.ToString("s")); 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
    private sealed class OutputCachedPage : Page 
    { 
     private OutputCacheParameters _cacheSettings; 

     public OutputCachedPage(OutputCacheParameters cacheSettings) 
     { 
      // Tracing requires Page IDs to be unique. 
      ID = Guid.NewGuid().ToString(); 
      _cacheSettings = cacheSettings; 
     } 

     protected override void FrameworkInitialize() 
     { 
      base.FrameworkInitialize(); 
      InitOutputCache(_cacheSettings); 
     } 
    } 
} 
+0

'OutputCachedPage'是位于代码示例底部的自定义密封类。没有需要的程序集/名称空间。 –

+0

对不起,傻了我。我将该处理程序复制并粘贴到我的项目中,但输出不是缓存。它似乎没有工作。 –

+0

@TomGullen我的道歉,删除'context.Response.Flush()'ProcessRequest'的结尾,它再次为我工作。我在http://outputcachetest.azurewebsites.net/CacheTest.ashx?name_startsWith=t vs http://outputcachetest.azurewebsites.net/CacheTest.ashx?name_startsWith= anyvaluehere –

0

IIS不使用Max Age来缓存任何内容,因为它不是HTTP代理。

这是因为您没有设置某个相关文件的上次修改日期时间。 IIS需要缓存依赖性(文件依赖性,以便它可以检查上次更新时间)并将其与缓存进行比较。 IIS不能用作HTTP代理,因此它不会将项目缓存30秒,而是IIS只会根据某种日期时间或某种缓存变量更新缓存。

您可以添加缓存依赖关系,称为“文件依赖关系”和“Sql缓存依赖关系”。

动态缓存如何在IIS中工作,可以说你有一个html文件。 IIS将静态HTML文本视为可缓存文件,并将其缓存并将缓存副本放入其缓存中。如果静态html的上次更新时间比缓存时间早,那么它将使用缓存。如果文件被修改,IIS会发现html的最后更新时间大于缓存时间,所以它会重置缓存。

对于动态内容,您必须相应地规划您的缓存。如果您基于存储在SQL表中某行的内容提供内容,那么您应该跟踪该行上的最后一次更新时间,并在IIS上添加对IIS的缓存依赖性以查询您尝试缓存的项目的上次更新时间。

0

对于多个查询字符串参数

public class test : IHttpHandler 
{ 

    public void ProcessRequest(HttpContext context) 
    { 
     OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters 
     { 
      Duration = 120, 
      Location = OutputCacheLocation.Server, 
      VaryByParam = "name;city" 
     }); 

     page.ProcessRequest(HttpContext.Current); 

     context.Response.ContentType = "application/json"; 
     context.Response.BufferOutput = true; 

     var searchTerm = (context.Request.QueryString["name"] + "").Trim(); 
     var searchTerm2 = (context.Request.QueryString["city"] + "").Trim(); 

     context.Response.Write(searchTerm+" "+searchTerm2+" "); 
     context.Response.Write(DateTime.Now.ToString("s")); 
    } 

    public bool IsReusable 
    { 
     get 
     { 
      return false; 
     } 
    } 
    private sealed class OutputCachedPage : Page 
    { 
     private OutputCacheParameters _cacheSettings; 

     public OutputCachedPage(OutputCacheParameters cacheSettings) 
     { 
      // Tracing requires Page IDs to be unique. 
      ID = Guid.NewGuid().ToString(); 
      _cacheSettings = cacheSettings; 
     } 

     protected override void FrameworkInitialize() 
     { 
      base.FrameworkInitialize(); 
      InitOutputCache(_cacheSettings); 
     } 
    } 
}