【问题标题】:Internet Explorer error using Asp MVC 4.0 FileResult使用 Asp MVC 4.0 FileResult 的 Internet Explorer 错误
【发布时间】:2012-04-03 15:19:10
【问题描述】:

我有以下代码,部署在 https Asp 站点上,使用 MVC 4.0 构建:

public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
 pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
 return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}

这将适用于 Chrome、Firefox 和 IE9(你们中的许多人可能已经猜到了)。但它会抛出一个:

---------------------------
Windows Internet Explorer
---------------------------
Internet Explorer cannot download someFileName from a_site.com.


Internet Explorer was not able to open this Internet site.  The requested site is either unavailable or cannot be found.  Please try again later.
---------------------------
OK   
---------------------------

在 IE6、7、8 上

非常感谢任何关于这个的想法或线索,因为我已经花了一天的时间在玩 html 标头。

编辑:

这是来自 IE7 的标题:

HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:43:50 GMT
Content-Length: 233324

以下是来自 IE9 的:

HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:42:14 GMT
Content-Length: 233324

谢谢,

【问题讨论】:

标签: asp.net-mvc-4 asp.net-mvc


【解决方案1】:

我想我也遇到了你的问题。

我还在运行 IIS 7.5 并通过对 HTTPS 请求的操作下载 PDF。由于我尚未隔离的原因,IIS 7.5 似乎将no-cache="Set-Cookie" 附加到我的Cache-Control 响应标头中,而不管我在响应上将缓存设置设置为什么。这导致了the fairly well documented no-cache issue on IE6, IE7, and IE8

为了解决这个问题,我在 FileContentResult 周围做了一个小包装,清除了标题,称为父级,然后将 Cacheability 设置为“私有”。这绕过了 IIS 7.5 坚持将no-cache="Set-Cookie" 添加到标题中,并且文件在我测试的所有浏览器中正确下载。如果你想模仿我所做的,首先,这是我的 FileContentResult 包装器。

public class PdfContentResult : FileContentResult {

    public PdfContentResult(byte[] data) : base(data, "application/pdf") { }

    public PdfContentResult(byte[] data, string fileName) : this(data) {
        if (fileName == null) {
            throw new ArgumentNullException("fileName");
        }

        this.FileDownloadName = fileName;
    }

    public override void ExecuteResult(ControllerContext context) {
        context.HttpContext.Response.ClearHeaders();

        base.ExecuteResult(context);

        context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
    }
}

然后我在ControllerExtensions 中添加了一个扩展方法,以便于查找:

public static class ControllerExtensions {

    public static PdfContentResult Pdf(this Controller controller, byte[] fileContents, string fileName) {
        return new PdfContentResult(fileContents, fileName);
    }

}

最后,在 Action 中,我做了同样的事情:

public ActionResult MyGeneratedPdf() {
    byte[] myPdfContentInByteStream = GetPdfFromModel();
    return this.Pdf(myPdfContentInByteStream, "MyFile.pdf");
}

显然,如果您要下载各种数据类型,您可能不希望将解决方法如此紧密地绑定到 PDF。

【讨论】:

  • 听起来很有希望,会试一试,让你知道进展如何
  • 我建议你不要做的一件事是从响应中清除标题!其原因如下。表单身份验证、Windows 身份基础等为您提供了一个 cookie,您可以通过该 cookie 来识别您自己。如果您支持滑动用户会话的概念,那么您发出一个新的 cookie/令牌,并通过“Set-Cookie”将其添加到响应标头中。下载文件时清除标题意味着这个新的 cookie 可能会丢失并且您的用户不再经过身份验证!这不是一件好事。
【解决方案2】:

我们通过在流式传输文件之前更改缓存控制标头解决了这个问题。

简化代码示例:

var browserInformation = Request.Browser;

//Set as private if current browser type is IE
Response.AppendHeader("cache-control", 
                    browserInformation.Browser == "IE" ? "private" : "no-cache");

return File(fileName, contentType, downloadFileName);

这行得通(耶).. 但我不清楚为什么我们必须为那个特定网站这样做。我们有四个网站在同一个机器上运行,都在 SSL 下,只有一个有这个标题问题。我比较了 web.config 文件并查看了 IIS 中的设置,但无法进一步说明为什么一个站点需要明确设置这些标头。

如果有人在上面添加更多内容(以增加清晰度),那就太好了。

【讨论】:

  • Web 服务器是否运行不同版本的 IIS?我的问题似乎是 IIS 7.5 特有的。
【解决方案3】:

在旧版本的 IE 中,如果用户尝试通过 HTTPS 连接下载文件,任何阻止缓存的响应标头都会导致文件下载过程失败。以下是导致问题的最常见标题:

  • Cache-Control 的值为 no-cache 或 no-store
  • 随任何值变化
  • 带有值 no-cache 的编译指示

您可以创建一个 ActionFilterAttribute,它会像这样为您清除缓存标头:

public class ClearCacheHeadersAttribute : FilterAttribute, IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        return;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContext.Current.Response.Headers.Remove("Cache-Control");
        HttpContext.Current.Response.Headers.Remove("Vary");
        HttpContext.Current.Response.Headers.Remove("Pragma");

        //Set the cache headers any way you like keeping in mind which values can brake the download
    }
}

并用它来装饰你的动作:

[ClearCacheHeaders]
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
    pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
    return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}

【讨论】:

  • 感谢您的回答,我昨天在搜索中确实尝试过,但没有成功
  • 由于某种原因它仍然会添加 Cache-Control 标头
  • 请检查您的 Web.config 或 IIS 配置文件中的 configuration/system.webServer/staticContent 节点。您也可以尝试自己将 Cache-Control 设置为某个允许的值,例如:HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
  • 不走运,检查了 web.config %windir%\Microsoft.NET\Framework\framework_version\CONFIG; %windir%\Microsoft.NET\Framework\framework_version\CONFIG; %windir%\system32\inetsrv\config
  • 试图更新到 HttpCacheability public 标头更新但下载仍然不起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 2020-03-18
  • 2014-01-07
  • 2018-08-10
  • 2012-12-28
相关资源
最近更新 更多