【问题标题】:Setting value of "expires" http header programmatically in asp.net在 asp.net 中以编程方式设置“过期”http 标头的值
【发布时间】:2013-01-27 21:29:18
【问题描述】:

在 ASP.NET 站点中,我想为某些静态文件添加“Expires”标头,因此我为这些文件所在的文件夹添加了类似这样的 clientCache 配置:

<system.webServer>
  <staticContent>
    <clientCache cacheControlMode="UseExpires" httpExpires="Wed, 13 Feb 2013 08:00:00 GMT" />
  </staticContent>

如果可能,我想以编程方式计算 httpExpires 的值,例如将其设置为文件上次更新时间 + 24 小时。

有没有办法通过调用方法来配置缓存控件获取httpExpires的值?

如果没有,有什么替代方案?我想过写一个自定义的http处理程序,但也许有一个更简单的解决方案......

编辑:请注意,这些是静态文件,因此常规的 asp.net 页面处理程序不提供它们。

【问题讨论】:

    标签: c# asp.net caching http-headers


    【解决方案1】:

    您可以使用 Response.Cache 以编程方式设置缓存。

    Here's 一个漂亮的教程。

    基本上你想将缓存策略设置为Public(客户端+代理)并设置过期标头。有些方法的命名相当笨拙,但这个方法很简单。

    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
    HttpContext.Current.Response.Cache.SetExpires(yourCalculatedDateTime);
    

    (ASP.NET 设计者不太喜欢得墨忒耳法则,是吗?)

    您也可以通过Response.Headers 集合访问听者,您可以在其中明确更改它们。

    这两种方式都可以在所有 ASP.NET 处理程序(aspx、asmx)中访问,并且可能在您可以访问当前 HttpContext 的任何地方进行更改。

    【讨论】:

    • 谢谢,但这些是静态文件,假设它们具有“xyz”扩展名,因此通常的 asp.net 处理程序不提供它们。我必须自己写吗?
    • 哦,抱歉,在您的问题中错过了这一点。在这种情况下,HTTP Module 应该是您正在寻找的。如果是这样,我会更新我的答案
    【解决方案2】:

    感谢@HonzaBrestan,他让我在 HTTP 模块的想法上走上了正轨,我想出了一个像这样的解决方案,我想分享它以防它对其他人有用。

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Web;
    
    public class ExpirationModule : IHttpModule {
    
        HttpApplication _context;
    
        #region static initialization for this example - this should be a config section
    
        static Dictionary<string, TimeSpan> ExpirationTimes;
        static TimeSpan DefaultExpiration = TimeSpan.FromMinutes(15);
        static CrlExpirationModule() {       
            ExpirationTimes = new Dictionary<string, TimeSpan>();
            ExpirationTimes["~/SOMEFOLDER/SOMEFILE.XYZ"] = TimeSpan.Parse("0.0:30");
            ExpirationTimes["~/ANOTHERFOLDER/ANOTHERFILE.XYZ"] = TimeSpan.Parse("1.1:00");
        }
    
        #endregion
    
        public void Init(HttpApplication context) {
            _context = context;
            _context.EndRequest += ContextEndRequest;
        }
    
        void ContextEndRequest(object sender, EventArgs e) {
            // don't use Path as it contains the application name
            string requestPath = _context.Request.AppRelativeCurrentExecutionFilePath;
            string expirationTimesKey = requestPath.ToUpperInvariant();
            if (!ExpirationTimes.ContainsKey(expirationTimesKey)) {
                // not a file we manage
                return;
            }
            string physicalPath = _context.Request.PhysicalPath;
            if (!File.Exists(physicalPath)) {
                // we do nothing and let IIS return a regular 404 response
                return;
            }
            FileInfo fileInfo = new FileInfo(physicalPath);
            DateTime expirationTime = fileInfo.LastWriteTimeUtc.Add(ExpirationTimes[expirationTimesKey]);
            if (expirationTime <= DateTime.UtcNow) {
                expirationTime = DateTime.UtcNow.Add(DefaultExpiration);
            }
            _context.Response.Cache.SetExpires(expirationTime);
        }
    
        public void Dispose() {
        }
    
    }
    

    然后你需要在 web config (IIS 7) 中添加模块:

    <system.webServer>
      <modules>
        <add name="ExpirationModule" type="ExpirationModule"/>
      </modules>
    </system.webServer>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 2012-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多