Asp.Net MVC 4 API:在IE8中下载docx失败

我将文档存储在数据库中,并有一个用于下载文档的API。

docx和xlsx的下载在IE9,Chrome和FF中运行良好但在真正的IE8中失败。(IE8模式下的IE 9也可以)

我得到的错误消息如下:

无法从idler2下载393。

无法打开此Internet站点。 请求的网站不可用或无法找到。 请稍后再试。

使用以下响应头:HTTP / 1.1 200 OK Cache-Control:no-cache Pragma:no-cache

Content-Length: 10255 Content-Type: application/octet-stream Expires: -1 Server: Microsoft-IIS/7.5 Content-Disposition: attachment; filename=document.docx X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Sat, 23 Mar 2013 11:30:41 GMT 

这是我的api方法:

 public HttpResponseMessage GetDocumentContent(int id) { Document document = Repository.StorageFor().GetDocument(id); HttpResponseMessage response = Request.CreateResponse(System.Net.HttpStatusCode.OK); response.Content = new ByteArrayContent(document.GetBuffer()); response.Content.Headers.ContentLength = document.GetBuffer().Length; response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { //FileName = document.GetFileName(), FileName = "document.docx", DispositionType = "attachment" }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return response; } 

我在内容配置和内容标题上尝试了很多变化,但没有运气..

我假设您在SSL下遇到此问题。 如果是这样,那么这是一个已知问题 。 本文讨论Office文档,但此问题适用于所有文件类型。

该文的解决方案是删除无缓存标头,但还有更多内容。 当IE8通过SSL与Web站点通信时,IE8会强制执行任何无缓存请求。 如果存在标头或标头,则IE8不会缓存该文件。 因此无法打开文件。 所有这些都是IE5到IE8特有的。

在MVC Web API中,它实际上需要另一步。 由于您要创建新的HttpResponseMessage,因此还必须在消息的标题上创建CacheControlHeaderValue。 您不必设置任何标头属性,只需实例化一个新属性。 标题将默认为所需内容,因此您不必更改属性。

 public HttpResponseMessage GetDocumentContent(int id) { Document document = Repository.StorageFor().GetDocument(id); HttpResponseMessage response = Request.CreateResponse(System.Net.HttpStatusCode.OK); response.Headers.CacheControl = new CacheControlHeaderValue(); // REQUIRED response.Content = new ByteArrayContent(document.GetBuffer()); response.Content.Headers.ContentLength = document.GetBuffer().Length; response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "document.docx" }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return response; } 

我有确切的问题,但这解决了它。

到目前为止,我找到的唯一解决方法是将文件存储在临时文件夹中并返回下载URL。 然后(javascript)客户端可以打开一个新窗口。

不是很好,但似乎MVC 4 API带来了一些限制。