【问题标题】:Error handling when downloading file from ASP.NET Web Handler (.ashx)从 ASP.NET Web 处理程序 (.ashx) 下载文件时的错误处理
【发布时间】:2013-01-30 16:54:32
【问题描述】:

我有一个网页,用户可以通过 ASP.NET Web 处理程序 (.ashx) 下载 PDF 文件。它的实现方式与此 question 中的答案类似。我遇到的问题是,当我在我的 JavaScript 中这样做 window.top.location.href = url; 时,如果处理程序中抛出异常,我无法真正控制会发生什么。当一切正常时,用户体验是他们基本上停留在他们所在的页面上,并且浏览器告诉他们可以下载 PDF 文件。但是,当处理程序中抛出异常时,它们将被重定向到处理程序的 URL 并显示一个空白页面。

下面是一些示例代码,以使其更清晰:

JavaScript:

function openPDF() {
    var url = GeneratePDFUrl();
    window.top.location.href = url;
}

处理程序:

public override void Process(HttpContext context)
{
    byte[] pdfdata = GetPDFData();
    context.Response.ContentType = "application/pdf";
    context.Response.AddHeader("content-disposition", "attachment; filename=\"" + GetPDFFileName() + "\"");
    context.Response.AddHeader("content-length", pdfdata.Length.ToString());
    context.Response.BinaryWrite(pdfdata);
}

当 GetPDFData() 抛出异常时会出现问题。我们正在尽我们所能防止 GetPDFData() 抛出异常,但它是从用户输入生成的,因此我们也在此处处理它,以防出现我们无法/无法预测哪些情况会产生错误。

这是我想出的一种解决方案,但它显示了用户错误文本(而不是空白页)

public override void Process(HttpContext context)
{
    try
    {
        byte[] pdfdata = GetPDFData();
        WritePDF(pdfdata, GetPDFFileName()); // Executes code in example above
    }
    catch (Exception e)
    {
        context.Response.Clear();
        context.Response.Write(GetErrorMessage(e));
    }
}

理想情况下,我想向用户显示一个弹出窗口,以便他们留在原来的页面上。

【问题讨论】:

  • 如果您已经准备好将标题作为 PDF 发送,那么除了发送一页错误代码(如 -page not found-)之外很难给出消息,但如果您没有将标题发送为pdf和文件名标题,然后您可以像以前一样编写消息。现在在对话框中停留在页面上是不可能的,因为您已经准备好转到其他页面,第一页不再具有控制权。

标签: c# javascript asp.net download


【解决方案1】:

首先在this answer of mine 上,用户询问如何使用javascript 进行下载。但是,如果您有不需要将其添加到 javascript 的链接,您也可以使用常规下载链接添加它。

现在许多网站使用带有一些文字的页面,上面写着“现在您的下载将在几秒钟内开始。如果没有开始,请单击此处bla bla bla”。原因之一与您的类似,用户必须知道某些内容将在几秒钟内开始下载,如果没有,则用户理解存在问题而没有其他额外消息。

一般来说,当你要发送一个文件下载时,你不在页面中,你不能在下载过程中发送消息,或者当文件以 pdf 结尾时,那么可能不会去在网页上显示任何内容。因此,从我的角度来看,如果您确实遇到问题并抛出异常,您需要设计一些步骤来告知用户出现问题 - 比如通知用户 “现在你要接收文件 - 如果文件在几秒钟内没有开始下载,请执行此操作"

但是,当处理程序中抛出异常时,它们是 重定向到处理程序的 URL 并显示一个空白页面。

为避免出现该黑页,您可以在出错时返回该代码,并且用户会按原样留在页面上,但仍然没有收到任何错误消息。

Response.TrySkipIisCustomErrors = true;
Response.Status = "204 No Content";
Response.StatusCode = 204;
Response.End();

异常的替代方法,您可以尝试使用

将他重定向到错误页面
Response.Redirect("errorpage.aspx");

也许你可以在那里发送一些错误 ID。

您也可以尝试将简单的消息显示为

context.Response.ContentType = "text/html";
context.Response.Write("Error downloading file - Please contact with us");

【讨论】:

  • 感谢您的回复 - 您的 Response.Redirect 是我们的答案。
【解决方案2】:

如何不设置窗口的href,而是设置隐藏iframe的src。然后,您可以对隐藏 iframe 中的返回值做一些诡计,例如:

context.Response.Clear();
context.Response.Write("<script>alert('" + GetErrorMessage(e) + "');</script>");

这个粗略的例子只会提醒错误消息。如果您在同一个域中(我怀疑您是!),那么您可以更聪明地调用父级中的方法,而不是警告,例如

context.Response.Clear();
context.Response.Write("<script>window.parent.someFunction('" + GetErrorMessage(e) + "');</script>");

这是我在 SO 上找到的一个示例:Retrieving HTTP status code from loaded iframe with Javascript

是上传,不是下载,而是同一个概念。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 2010-10-11
    • 2015-12-08
    • 2011-11-16
    相关资源
    最近更新 更多