在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页面处理程序不提供它们。
答案 0 :(得分:7)
您可以使用 Response.Cache
以编程方式设置缓存。
Here's 一个很好看的教程。
基本上,您希望将缓存策略设置为Public
(clientside + proxies)并设置到期标头。有些方法的命名相当笨拙,但这个方法很容易。
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
HttpContext.Current.Response.Cache.SetExpires(yourCalculatedDateTime);
(ASP.NET设计人员不喜欢Demeter法则,是吗?)
或者,您可以通过Response.Headers
集合访问heareds,您可以在其中明确更改它们。
这两种方式都可以在所有ASP.NET处理程序(aspx,asmx)中访问,并且可以在任何可以访问当前HttpContext的地方进行更改。
答案 1 :(得分:6)
感谢@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配置(IIS 7)中添加模块:
<system.webServer>
<modules>
<add name="ExpirationModule" type="ExpirationModule"/>
</modules>
</system.webServer>