【问题标题】:ASP.net cache ASHX file server-sideASP.net 缓存 ASHX 文件服务器端
【发布时间】:2013-07-09 20:10:57
【问题描述】:

给定通用处理程序:

<%@ 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 根据 name_startsWith 查询字符串参数将此文件缓存 1 小时?使用网络用户控件很容易:

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

但我一直在寻找一段时间来对通用处理程序 (ashx) 文件执行相同操作,但找不到任何解决方案。

【问题讨论】:

  • 您将在客户端使用this stuff 进行缓存,然后在您要获取数据时使用 HttpContext.Cache 对实际数据使用服务器端缓存。但是您将无法为此使用任何类型的输出缓存。另外,请记住确保您的 HttpContext.Cache 代码是线程安全的。 ;)
  • 在下面编辑了我的答案以回答对帖子的更改。

标签: c# asp.net caching


【解决方案1】:

使用您提供的代码,您是在告诉最终用户浏览器将结果缓存 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);
        }
    }
}

【讨论】:

  • OutputCachedPage 是位于代码示例底部的自定义密封类。不需要程序集/命名空间。
  • 对不起,我太傻了。我将该处理程序复制并粘贴到我的项目中,但输出没有缓存。它似乎不起作用。
  • @TomGullen 抱歉,删除context.Response.Flush() 末尾的ProcessRequest,它再次为我工作。我在outputcachetest.azurewebsites.net/…outputcachetest.azurewebsites.net/… 设置了一个快速示例
  • 无需道歉,非常感谢您的帮助!删除冲洗工作完美。感谢您抽出宝贵时间提供帮助。
【解决方案2】:

对于多个查询字符串参数

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);
        }
    }
}

【讨论】:

    【解决方案3】:

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

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

    你可以添加缓存依赖两个说,文件依赖和Sql缓存依赖。

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

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

    【讨论】:

      【解决方案4】:

      要缓存文件,例如 .js、.css 或其他文件,您需要将其放入 context.cache。示例:

          public void ProcessRequest(HttpContext context)
          {
              var cachedResult = context.Cache.Get(context.Request.Path);
      
              if (cachedResult != null && cachedResult.GetType() == typeof(VueFileRequestResult))
              {
                  RequestedFileResponce(context, cachedResult as VueFileRequestResult);
                  return;
              }
              
              // SOME ACTIONS WITH NON-CACHED FILE
      
              var fileContent = System.IO.File.ReadAllBytes(filePath);
              var result = new VueFileRequestResult(contentType.GetDescription(), fileContent);
      
              RequestedFileResponce(context, result);
      
              var expirationDate = DateTime.Now.AddYears(1);
              var dependency = new CacheDependency(filePath);
              context.Cache.Add(context.Request.Path, result, dependency, expirationDate, TimeSpan.Zero, CacheItemPriority.Low, null);
      
              return;
          }
      

      【讨论】:

        猜你喜欢
        • 2011-07-17
        • 1970-01-01
        • 2013-02-12
        • 1970-01-01
        • 2011-02-14
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        • 1970-01-01
        相关资源
        最近更新 更多