HttpHandler 在下载时不保留文件名
HttpHandler not retaining filenames on download
我正在使用 HttpHandler 在我的 ASP.NET 网络应用程序中提供文档。我可以让它正常工作,但有一个我不太清楚的问题 -- 文件名未保留。
例如,如果我尝试提供一个名为 "New Patient Information Form.docx" 的文档,而我的处理程序名为 "GetDocument.ashx",则文件将下载为 "GetDocument.docx" 和 "GetDocument(1).docx","GetDocument(2).docx"等我每次下载文件。
出于安全原因,我想使用处理程序而不是直接链接到文件。我将实际文档保存在 App_Data 文件夹中,因此无法直接浏览它们。
这是我正在使用的代码。我已经在 "attachment" 和 "inline" 之间切换了内容配置,但似乎都没有对更正此问题产生任何影响。
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();
}
我的代码中的 "document" 对象是 class 具有与文档元数据相关的属性(例如文件名、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"。我开始怀疑浏览器是否应该受到指责,因为我记得最后一次这项工作是在五月份。
尝试用双引号括起文件名,如下所示:
context.Response.AppendHeader("Content-Dispositon", $"attachment; filename=\"{document.Filename}\"");
我发现了问题,这完全解释了为什么所有浏览器的行为方式都相同。我有点惊讶没有其他人发现这个但它是:
我把 "Content-Disposition" 拼成了 "Content-Dispositon"。它忽略了文件名,因为 header 名称不正确。
我将需要检查所有其他处理程序并确保它也拼写正确!
我正在使用 HttpHandler 在我的 ASP.NET 网络应用程序中提供文档。我可以让它正常工作,但有一个我不太清楚的问题 -- 文件名未保留。
例如,如果我尝试提供一个名为 "New Patient Information Form.docx" 的文档,而我的处理程序名为 "GetDocument.ashx",则文件将下载为 "GetDocument.docx" 和 "GetDocument(1).docx","GetDocument(2).docx"等我每次下载文件。
出于安全原因,我想使用处理程序而不是直接链接到文件。我将实际文档保存在 App_Data 文件夹中,因此无法直接浏览它们。
这是我正在使用的代码。我已经在 "attachment" 和 "inline" 之间切换了内容配置,但似乎都没有对更正此问题产生任何影响。
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();
}
我的代码中的 "document" 对象是 class 具有与文档元数据相关的属性(例如文件名、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"。我开始怀疑浏览器是否应该受到指责,因为我记得最后一次这项工作是在五月份。
尝试用双引号括起文件名,如下所示:
context.Response.AppendHeader("Content-Dispositon", $"attachment; filename=\"{document.Filename}\"");
我发现了问题,这完全解释了为什么所有浏览器的行为方式都相同。我有点惊讶没有其他人发现这个但它是:
我把 "Content-Disposition" 拼成了 "Content-Dispositon"。它忽略了文件名,因为 header 名称不正确。
我将需要检查所有其他处理程序并确保它也拼写正确!