我正在使用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月。
答案 0 :(得分:0)
尝试将文件名包装在双引号中,如下所示:
context.Response.AppendHeader("Content-Dispositon", $"attachment; filename=\"{document.Filename}\"");
答案 1 :(得分:0)
我发现了问题,为什么所有浏览器的行为方式都完全一样。我有点惊讶没有其他人发现,但这是:
我将“ Content-Disposition”拼写为“ Content-Dispositon”。因为标题名称不正确,所以它忽略了文件名。
我将需要检查所有其他处理程序,并确保它在那里也正确拼写了!