第一次在这里提问,如果我做错了请告诉我...
我的 C# MVC5 应用程序允许用户下载 pdf 文件。除了在我的安卓手机上,它工作得很好。我正在使用 chrome 并让操作系统处理 PDF。它看起来像是在使用 Google 云端硬盘应用程序内置的 PDF 查看器。
当我使用指向文件的直接链接时,它工作正常,但是当我通过 Controller 操作下载它时,它失败并显示“文件格式无效”。我已将其简化为该问题的测试用例。
所以这是我的操作方法:
public ActionResult IndirectTestFile()
{
string filename = "document.pdf";
var disposition = new System.Net.Mime.ContentDisposition("inline") { FileName = filename };
Response.AppendHeader("Content-Disposition", disposition.ToString());
string serverFilename = Server.MapPath("~/files/direct/" + filename);
return File(serverFilename, "application/pdf");
}
和我的 HTML:
//This fails:
<a href="/report/indirectTestFile">Indirect link to file</a>
//This works:
<a href="/Files/direct/Document.pdf">Direct link to file</a>
我正在使用 Windows(桌面)Chrome 获取这些请求的 header 。
这是直接链接的响应 header :
HTTP/1.1 200 OK
Content-Type: application/pdf
Last-Modified: Thu, 07 Jul 2016 11:46:47 GMT
Accept-Ranges: bytes
ETag: "b8a3dd3d45d8d11:0"
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Thu, 07 Jul 2016 12:33:05 GMT
Content-Length: 51793
以及链接到 MVC 操作的响应 header :
HTTP/1.1 200 OK
Cache-Control: private, s-maxage=0
Content-Type: application/pdf
Server: Microsoft-IIS/10.0
Content-Disposition: inline; filename=document.pdf
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Thu, 07 Jul 2016 12:34:09 GMT
Content-Length: 51793
我没有看到那里有任何巨大差异,但一个可靠地工作,另一个可靠地失败。
这不是损坏的下载。如果我在 Windows 上下载“错误的”PDF 并将其复制到 Android 手机,同样的查看器很乐意显示它!
有人看过这个吗?感谢您的帮助。
最佳答案
对于 future 的搜索者:
我还没有解决这个问题,但我确实找到了确切的原因。查看我的日志,看起来是 google drive/docs 应用程序正在处理下载而不是浏览器。该请求通过浏览器的不同用户代理传递。
这意味着它发生在不同的 session 中。该 session 未登录到网站,因此它没有下载 PDF,而是被重定向到登录页面并下载,并提示它不是有效的 PDF 文件!这就是它发生的原因。
我通过从 Controller 中删除身份验证来测试它,因此不会重定向请求,并且 pdf 下载并显示正常。
我不明白为什么 chrome 自己处理直接下载,但将 Controller 链接传递给谷歌应用程序。我更改了我的服务器,以便两个请求都传回相同的 header ,所以我忘记了 chrome 如何区分两者之间的区别并以不同的方式对待它们,但它确实如此。
我要么需要弄清楚这个问题,要么重新组织我的应用程序来解决这个问题,但也许这是针对不同的问题。
感谢 Fran 的想法。
更新: 我不记得这个问题的确切解决方案(很伤心,只是几周前......),但我认为这是因为我正在重定向到我的 Controller 操作。例如我会有这样的 Action (简化)
public ActionResult MakePDF(string id)
{
// code to create the file removed for clarity.
return RedirectToAction("IndirectTestFile");
}
这将生成 PDF 文件并重定向到将其返回给用户的操作。
所以我像这样删除了重定向
public ActionResult MakePDF(string id)
{
// code to create the file removed for clarity.
return IndirectTestFile();
}
这似乎是解决方案 - 无论如何我都在使用这种方法并且它对我有用。
关于c# mvc pdf 下载在 android chrome 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38245708/