【发布时间】:2019-01-13 19:41:10
【问题描述】:
我正在使用 HttpHandler 在我的 ASP.NET Web 应用程序中提供文档。我可以让它很好地解决一个我无法弄清楚的问题——文件名没有保留。
例如,如果我尝试提供一个名为“New Patient Information Form.docx”的文档,并且我的处理程序名为“GetDocument.ashx”,则该文件将作为“GetDocument.docx”和“GetDocument(1)”下载。 docx”、“GetDocument(2).docx”等每次下载文件时。
出于安全原因,我想使用处理程序而不是直接链接到文件。我将实际文档保存在 App_Data 文件夹中,因此无法直接浏览它们。
这是我正在使用的代码。我已经在“附件”和“内联”之间切换了内容配置,但似乎对纠正这个问题没有任何影响。
public void ProcessRequest(HttpContext context)
{
if (!int.TryParse(context.Request.QueryString["ID"], out var id))
throw new Exception($"Invalid DocumentID value ({id}).");
var document = DocumentsHelper.GetByID(id);
if (document == null)
throw new Exception($"Invalid DocumentID value ({id}).");
var documentDownloadDirectory = AppSettingsHelper.DocumentDownloadDirectory(); // "App_Data"
var filePath = Path.Combine(documentDownloadDirectory, document.Filename);
var fileBytes = File.ReadAllBytes(filePath);
// A content disposition of "attachment" will force a "Save or Open" dialog to appear when
// navigating directly to this URL, and "inline" will just show open the file in the default viewer
context.Response.AppendHeader("Content-Dispositon", $"attachment; filename={document.Filename}");
context.Response.AppendHeader("Content-Length", fileBytes.Length.ToString());
context.Response.ContentType = document.ContentType;
context.Response.BinaryWrite(fileBytes);
context.Response.Flush();
}
我的代码中的“文档”对象是一个具有与文档元数据相关的属性(例如文件名、ID 等)的类
我同时使用 Chrome 和 Edge 作为浏览器,并且都表现出相同的行为。有没有办法让 HttpHandler 保留原始文件名?
更新:我用简化的代码创建了一个新项目,试图缩小问题的原因。代码如下:
public class DownloadFile : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var fileName = "NoSpaces.docx";
var basePath = context.Request.MapPath("~/App_Data");
var filePath = Path.Combine(basePath, fileName);
var fileBytes = File.ReadAllBytes(filePath);
context.Response.AppendHeader("Content-Dispositon", $"attachment; filename={fileName}");
context.Response.AppendHeader("Content-Length", fileBytes.Length.ToString());
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
context.Response.BinaryWrite(fileBytes);
context.Response.Flush();
}
public bool IsReusable
{
get
{
return false;
}
}
文件名不包含空格,浏览器尝试将文件保存为“DownloadFile.ashx”而不是“NoSpaces.docx”。我开始怀疑浏览器是否应该受到指责,因为我最后一次记得这项工作是在 5 月。
【问题讨论】:
-
对不起,“文件名没有保留”是什么意思?由谁保留?你期望会发生什么?你看到发生了什么?
-
document.Filename的计算结果是什么? -
@Flydog57 - 下载的文件与处理程序命名相同,而不是文件名。如果我有一个包含大量指向不同文档的链接的页面,并且用户尝试下载它们,它们的名称都相同。
-
@Griswald - document.Filename 评估为磁盘上文件的名称
-
抱歉,这个感觉很眼熟,不过是旧工作(所以我不能看笔记)。你玩过Content-Type吗?我很确定您只能使用“附件”的内容配置来使用它
标签: c# asp.net download httphandler