如何不中止http响应c#

在将文件发送给用户进行下载后,我需要运行几种方法。 发生的事情是,在我向用户发送文件后,响应被中止,我在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但应该使用单独的响应流。 那是对的吗? 我如何在一个单独的方法中一般地做到这一点(假设我希望我的处理程序接受数据和内容类型的字节数组,并可从单独的响应下载。我真的不想使用单独的页面进行响应。

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

更新
由于您没有说第二页,请改为执行此操作。 在页面中添加一个部分,用于检查查询字符串参数(类似于fileid或path等…)。 如果存在此值,则使用现有代码启动下载过程。 如果此值不存在则会像正常情况一样运行。

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


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

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

原帖
Response.Flush将允许您在将文件发送给用户后继续处理,或者只是不调用Response.End(您实际上并不需要)。

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

其他答案与普遍的共识一致,你不能在文件开始下载后重定向: https : //stackoverflow.com/a/822732/328968 (PHP,但相同的概念,因为它一般涉及HTTP)。 或下载文件后指向新页面 。

Response.End()抛出一个线程中止exception。 它旨在结束您的回复。 之后没有代码将在该线程中处理。

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

你想要达到的目标是什么?

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

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

正如之前的答案所述 – 返回PDF文件意味着发送HTTP标头。 之后您不能发送另一个标头,而Response.Redirect()只是意味着发送HTTP 302。

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

    

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

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

用户单击WebForm1.aspx上的下载按钮开始下载文件。 然后,在文件下载完成后(由WebForm2.aspx ),用户将自动重定向。

WebForm1.aspx

   

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中的会话不会相互通信,除非您实现此目的 。

只需删除context.Response.End(); 因为你正在重定向…

问题是这里的逻辑有缺陷……为什么你会结束回应?

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

我相信你的尝试是行不通的。

这就是我要做的:

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

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

缺点:文件清理。

我推荐这个解决方案:

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

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

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

  4. 覆盖您的渲染,如:

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