6

在将文件发送给用户进行下载后,我需要运行几种方法。发生的情况是,在我向用户发送文件后,响应被中止,之后我无法再做任何事情response.end()

例如,这是我的示例代码:

 Response.Clear();
 Response.AddHeader("content-disposition", "attachment;  filename=test.pdf");
 Response.ContentType = "application/pdf";
 byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
 Response.BinaryWrite(a);
 Response.End();
 StartNextMethod();
 Response.Redirect(URL);

所以,在这个例子中StartNextMethodResponse.Redirect没有执行。

我尝试的是使用以下代码创建了一个单独的处理程序(ashx):

public void ProcessRequest(HttpContext context)
        {
            context.Response.Clear();
            context.Response.AddHeader("content-disposition", "attachment;  filename=test.pdf");
            context.Response.ContentType = "application/pdf";
            byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
            context.Response.BinaryWrite(a);
            context.Response.End();
        }

并这样称呼它:

Download d = new Download();
d.ProcessRequest(HttpContext.Current);
StartNextMethod();
Response.Redirect(URL);

但同样的错误发生。我已经尝试用 CompleteRequest 替换 Response.End 但它没有帮助。

我想问题是我正在使用 HttpContext.Current 但应该使用单独的响应流。那是对的吗?我通常如何在单独的方法中执行此操作(假设我希望我的处理程序接受数据和内容类型的字节数组并且可以从单独的响应中下载。我真的不想使用单独的页面进行响应。

更新
我仍然没有找到一个好的解决方案。我想在用户下载文件后执行一些操作,但不使用单独的页面进行响应\请求。

4

8 回答 8

7

更新
既然你说没有第二页,那就这样做吧。向您的页面添加一个部分,用于检查查询字符串参数(例如 fileid 或路径等)。如果存在此值,则它将使用您现有的代码启动下载过程。如果此值不存在,则它会正常运行。

现在,当用户单击下载链接时,您执行回发(您已经在执行此操作)。在这篇回帖中,在页面上创建一个 iFrame,并使用添加的查询字符串参数(mypage.aspx?id=12664 或 ?download=true,类似的东西)将 iFrame 的 URL 设置为您的页面 URL。创建 iframe 后,执行您希望的任何其他数据绑定/等。

示例
- http://encosia.com/ajax-file-downloads-and-iframes/

上面链接的示例使用 iFrame 和更新面板,就像您在谈论的那样。

Original Post
Response.Flush 将允许您在将文件发送给用户后继续处理,或者只是不调用 Response.End (您也不需要)。

但是 Daniel A. White 是正确的,您在发送文件后实际上无法从代码中重定向,如果您尝试,您会收到错误消息。但是,如果需要,您可以继续执行其他服务器端操作。

其他答案与普遍共识一致,文件开始下载后您无法重定向:https ://stackoverflow.com/a/822732/328968 (PHP,但概念相同,因为它通常涉及 HTTP)。或下载文件后定向到新页面

于 2012-06-01T15:48:29.830 回答
5

Response.End()引发线程中止异常。它旨在结束您的回复。之后没有代码将在该线程中处理。

End 方法使 Web 服务器停止处理脚本并返回当前结果。不处理文件的其余内容。

你想达到什么目的?

如果您的目的是允许 pdf 下载然后将用户带到其他页面,那么一点 javascript 可以帮助您。

添加一个带有计时器的脚本,将 location.href 设置为您的重定向页面。

于 2012-05-28T05:08:10.760 回答
1

正如之前的答案所述 - 返回 PDF 文件意味着发送 HTTP 标头。之后您无法发送其他标头,并且 Response.Redirect() 仅表示发送 HTTP 302。

如果您不想有单独的页面,或者您不想使用 AJAX,为什么不尝试:

<head>
    <meta http-equiv="refresh" content="3; url=http://www.site.com/download.aspx?xxxx">
</head>

实际上,这将显示您想要向用户显示的所需页面,并在 3 秒后刷新页面,并带有下载 PDF 文件的 URL。

于 2012-06-01T21:13:29.493 回答
1

分块下载文件,如ASP.NET 中的文件下载和跟踪下载成功/失败状态或此问题的答案所示。当文件的最后一块被写入客户端时,您可以执行您需要的代码。(不必在最后,可以根据您的需要介于两者之间。)

于 2012-06-04T16:29:40.067 回答
0

用户点击下载按钮WebForm1.aspx开始下载文件。然后,在文件下载完成后(由 提供WebForm2.aspx),用户会被自动重定向。

WebForm1.aspx

<script type="text/javascript">
    $(document).ready(function () {
        $('#btnDL').click(function () {
            $('body').append('<iframe src="WebForm2.aspx" style="display:none;"></iframe>');
            return true;
        });
    });
</script>
<asp:Button runat="server" ID="btnDL" ClientIDMode="Static" Text="Download" OnClick="btnDL_Click" />

WebForm1.aspx.cs

protected void btnDL_Click(object sender, EventArgs e)
{
    var sent = Session["sent"];

    while (Session["sent"]==null)
    {// not sure if this is a bad idea or what but my cpu is NOT going nuts
    }

    StartNextMethod();
    Response.Redirect(URL);

}

WebForm2.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    Response.Clear();
    Response.AddHeader("content-disposition", "attachment;  filename=test.pdf");
    Response.ContentType = "application/pdf";
    byte[] a = System.Text.Encoding.UTF8.GetBytes("test");
    Response.BinaryWrite(a);
    Session["sent"] = true;
}

Global.asax.cs

protected void Session_Start(object sender, EventArgs e)
{
    Session["init"] = 0; // init and allocate session data storage
}

注意:确保不要使用 ashx(通用处理程序)来提供您的下载。出于某种原因,ashx 和 aspx 中的会话不会相互交谈,除非您实现this

于 2012-05-28T06:23:20.853 回答
0

只需删除,context.Response.End();因为无论如何您都在重定向...

问题是这里的逻辑有缺陷......你为什么要结束响应?

获取 PDF 并显示指向它的链接或使用META刷新重定向到 PDF 的位置,或者您也可以显示链接或使用这两种技术的组合。

于 2012-06-05T16:37:42.273 回答
0

我相信你正在尝试的不会奏效。

这就是我要做的:

  1. 将内容写入本地文件并为其分配唯一 ID
  2. 将用户发送到包含隐藏框架的下一页,该隐藏框架执行具有唯一 ID 的请求(javascript)
  3. 隐藏请求页面加载文件并推送内容流。

这与许多文件下载站点使用的行为相同。唯一的问题是如果隐藏框架无法执行请求(javascript 关闭),为什么如果自动请求失败,许多相同的站点都有可用的链接。

缺点:文件清理。

于 2012-06-06T21:16:28.233 回答
0

我推荐这个解决方案:

  1. 不要使用 response.End();

  2. 声明这个全局变量: bool isFileDownLoad;

  3. 就在您的 (Response.BinaryWrite(a);) set ==> isFileDownLoad = true; 之后

  4. 覆盖您的渲染,如:

    /// /// AEG : 处理线程中止异常非常重要 /// /// override protected void Render(HtmlTextWriter w) { if (!isFileDownLoad) base.Render(w); }

于 2014-01-16T15:18:39.593 回答