如何让IIS从WebApi 2返回自定义缓存控制头,IIS 10每次都返回private



**更新2021年1月27日**我一直在与微软合作解决这个问题,我们进行了请求跟踪,查看了FREB日志,并确认代码输出了正确的标头,但在END_request处理程序中,它们被缓存控制专用程序取代。在从头开始构建了几个虚拟机之后,我们了解到,开箱即用,这个问题不会发生。然而,当我们安装最新版本的STACKIFY AGENT(4.29.29(时,一旦我们将代理置于这种行为上,就会发生这种情况。旧版本的Stackify代理(RETRACE探查器和APM(不能做到这一点,但到目前为止,这是不可逆转的:一旦我们安装了4.29.29的Stackfy,卸载或安装旧版本并不能解决这个问题,环境就会以某种方式被永久修改。

STACKIFY给出了一个有效的解决方案(但表明卸载后留下了一些东西(:设置环境变量STACKIFY_ENABLERUM=false。。我们尝试了这个方法,IIS返回了正确的头,而没有用缓存控制替换它:private。


我想使用CloudFront CDN将流量缓存到我的API,以便将请求卸载到内容交付网络。

我正试图将Cache Control标头设置为返回:Cache Control:";公开,最大年龄=10";。当我在Visual Studio 2019中运行代码进行调试时,我会得到正确的头。然而,当我将其部署到IIS时,我总是会返回:

缓存控制:私有

我正在运行IIS版本为10.0.17763.1的Windows Server 2019。我使用ASP.NET MVC和Web API 2来操作REST API。

在我的代码中,我创建了这个属性:

代码:

public class CacheControlAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public int MaxAge { get; set; }
public CacheControlAttribute()
{
MaxAge = 0;
}
public override void OnActionExecuted(HttpActionExecutedContext context)
{
// Don't set the cache header if there was an error or if there was no content in the response
if (context.Response != null && context.Response.IsSuccessStatusCode)
{
context.Response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue
{
Private = false,
Public = true,
MaxAge = TimeSpan.FromSeconds(MaxAge)
};                
}
base.OnActionExecuted(context);
}
}

然后我用这个属性装饰我的方法:

[CacheControl(MaxAge = 10)]

我读了几篇关于StackOverflow的文章,但没能解决这个问题。我还尝试将其添加到web.config:

这也于事无补。

我在一台IIS服务器上成功地完成了这项工作,它是相同版本的IIS,但是我代码的旧版本。我在新的IIS服务器上设置它时遇到了问题,我认为这是IIS配置问题,但我不确定。也许它在我的web.config中。

谢谢你在这方面的帮助。

缓存控制分为请求指令和响应指令。我猜您在讨论响应中的缓存控制,因为不能在IIS中设置请求缓存控制。

出于安全原因,IIS默认情况下会将缓存控制设置为私有,因此您将遇到此问题。当没有用于请求的输出缓存(并且已启用输出缓存(时,这是.NET的默认行为。如果在web.config中将sendCacheControlHeader设置为false,则不会获得Cache-Control:private标头。

因此,一个简单的方法是将sendCacheControlHeader设置为false,并添加缓存控制将删除private。您也不需要在MVC中自定义缓存控制过滤器。

<system.web>
<httpRuntime sendCacheControlHeader="false" /> 
</system.web>

<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Cache-Control" value="max-age=30,public" />
</customHeaders>
</httpProtocol>

另一个想法是为每个动作或控制器添加缓存的输出。NET有一个定义的过滤器来控制maxage,您不需要自己定义它。您可以使用[OutputCache(Duration = 0)]

OutputCache

您需要在现有的输出缓存之上实现自己的缓存,如

public static class MyCustomCacheConfig
{
public static int Duration = 600; //whatever time you want
}
public class CdnCacheCacheAttribute : OutputCacheAttribute
{
public CdnCacheCacheAttribute()
{
this.Duration = MyCustomCacheConfig.Duration;
}
}
[CdnCacheCacheAttribute(Duration = 100, VaryByParam = "none")]
public ActionResult YourActions()
{
return View();
}

Microsoft输出缓存中的VaryByParm。。它控制HttpCaching

// Get the current VaryByParam.
String varyByParamValue =  outputCacheProfile.VaryByParam;
// Set the VaryByParam.outputCacheProfile.VaryByParam = string.Empty;

最新更新