【发布时间】:2012-01-26 20:25:32
【问题描述】:
我们有一些文件存储在 sql 数据库中。在 ASP.NET MVC3 表单上,我们显示 2 个链接:
查看此文件 |下载这个文件
这些链接指向这些相应的操作方法。下载按预期进行——单击链接会强制在浏览器中出现保存对话框。但是,显示会导致向浏览器发送重复的 Content-Disposition 标头,从而导致 Chrome 出现错误,并导致 Firefox 出现空白页面。
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
Response.AddHeader("Content-Disposition",
string.Format("inline; filename={0}", file.Name));
return File(file.Content, file.MimeType, file.Name);
}
}
[ActionName("download-file")]
public virtual ActionResult DownloadFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
return File(file.Content, file.MimeType, file.Name);
}
}
以下是发送到浏览器以进行显示操作的 2 个标头:
Content-Disposition: inline; filename=name-of-my-file.pdf
Content-Disposition: attachment; filename="name-of-my-file.pdf"
我尝试更改我的自定义内容处置标头以将文件名包含在双引号中,但它仍然向浏览器发送了 2 个标头。我还尝试在添加自定义标头之前删除 Content-Disposition 标头,但似乎在返回 FileContentResult 后正在添加附件标头。
这段代码曾经有效。我昨天进行了一次测试,发现它不再在 Chrome 或 Firefox 中工作。这可能是由于浏览器中的更新所致。 IE8 和 Safari 仍然可以正确打开文件。
更新
再次感谢达林,你是对的。由于another question you answered,我们实际上使用了这种方法。
关于我们最终如何解决这个问题的更多信息,我们有一个显示文件链接的自定义路由:
context.MapRoute(null,
"path/to/display-file-attachment/{fileId}/{fileName}",
new
{
area = "AreaName",
controller = "ControllerName",
action = "DisplayFile",
}
);
页面上的超链接通过route参数将文件名传递给action方法,所以它已经是URL的一部分了。因此,当用户决定下载文件时(通过单击浏览器 PDF 查看器中的保存图标),我们不需要添加自定义内容处置标题以使文件名与系统匹配。所以我们只使用了这个:
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
// no custom content-disposition header, and no 3rd fileName argument
return File(file.Content, file.MimeType);
}
}
【问题讨论】:
-
Firefox 和 Chrome 在处理 Content-Disposition 标头方面确实变得更加严格。
-
@JulianReschke,您能否详细说明非 ASCII 字符?我们尚未使用文件名中的 unicode 字符对此进行测试。
-
为了让 C-D 文件名中的非 ASCII 在所有浏览器中“工作”,服务器当前需要进行用户代理嗅探。请参阅 greenbytes.de/tech/tc2231 和 greenbytes.de/tech/webdav/rfc6266.html。我怀疑 ASP.net 是否正确,但我很想知道其他情况。
标签: asp.net-mvc-3 download content-disposition