Kei*_*ith 9 asp.net-mvc https internet-explorer mime-types
我有一个MVC .Net应用程序,它具有返回报告文件的操作,通常.xslx:
byte[] data = GetReport();
return File(data,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"filename.xlsx");
Run Code Online (Sandbox Code Playgroud)
这在测试和所有浏览器中都很有用,但是当我们把它放在一个SSL站点上时,IE6,7和8(所有正确的浏览器仍能正常工作)失败,这个无用的错误:

这曾经用于此操作替换的遗留应用程序(非MVC).
我们无法告诉用户在本地更改任何内容 - 大约60%仍在IE6上!
我如何使用MVC解决这个问题?
进一步的挖掘表明,这是IE6-8中的一个根本性失败.根据Eric Law的IE internals博客,这是因为在SSL连接期间,IE将no-cache指令视为绝对规则.因此,它不考虑缓存副本,而是认为no-cache意味着即使在Content-Disposition:attachment显式提示下载位置时也不可能将副本保存到磁盘
.
显然这是错误的,但是当它在IE9中得到修复时,我们仍然坚持使用所有的IE6-8用户.
使用MVC的操作过滤器属性会生成以下标头:
Cache-Control:no-cache, no-store, must-revalidate
Pragma:no-cache
Run Code Online (Sandbox Code Playgroud)
使用Fiddler动态更改这些,我们可以验证需要返回的标头:
Cache-Control:no-store, no-cache, must-revalidate
Run Code Online (Sandbox Code Playgroud)
需要注意的顺序Cache-Control 必须有no-store 之前 no-cache与该Pragma指令必须被完全删除.
这是一个问题 - 我们广泛使用MVC的动作属性,我真的不想从头开始重写它们.即使我们尝试删除Pragma指令,IIS也会抛出异常.
你如何让微软的MVC和IIS返回微软的IE6-8可以在HTTPS下处理的无缓存指令?我不想允许私有缓存响应(根据这个类似的问题)或忽略MVC内置方法的覆盖(根据我自己的答案,这只是我目前最好的黑客).
I've come up with a workaround, but it's a definite hack - this is a new cache attribute to replace the built-in [OutputCache] one:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public sealed class IENoCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
if (filterContext.HttpContext.Request.IsSecureConnection &&
string.Equals(filterContext.HttpContext.Request.Browser.Browser, "IE", StringComparison.OrdinalIgnoreCase) &&
filterContext.HttpContext.Request.Browser.MajorVersion < 9)
{
filterContext.HttpContext.Response.ClearHeaders();
filterContext.HttpContext.Response.AddHeader("cache-control", "no-store, no-cache, must-revalidate");
}
else
{
filterContext.HttpContext.Response.Cache.SetNoStore();
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
}
base.OnResultExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)
It's a workaround at best though - what I really want is to extend the existing [OutputCache] and Response.Cache structures so that they have the desired output suitable for legacy IEs.