HttpHandler在下载时不保留文件名

时间:2018-08-06 19:34:39

标签: c# asp.net download httphandler

我正在使用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月。

2 个答案:

答案 0 :(得分:0)

尝试将文件名包装在双引号中,如下所示:

context.Response.AppendHeader("Content-Dispositon", $"attachment; filename=\"{document.Filename}\"");

答案 1 :(得分:0)

我发现了问题,为什么所有浏览器的行为方式都完全一样。我有点惊讶没有其他人发现,但这是:

我将“ Content-Disposition”拼写为“ Content-Dispositon”。因为标题名称不正确,所以它忽略了文件名。

我将需要检查所有其他处理程序,并确保它在那里也正确拼写了!