How to not interrupt C # HTTP response

I need to run several methods after sending the file to the user for download. It happens that after sending the file to the user, the response is interrupted, and I can do nothing else after response.end() .

for example, this is my sample code:

  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); 

So, in this example, StartNextMethod and Response.Redirect not executed.

I tried to create a separate handler (ashx) with the following code:

 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(); } 

and name it as follows:

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

but the same error occurs. I tried replacing Response.End with CompleteRequest, but that does not help.

I think the problem is that I am using HttpContext.Current, but should use a separate response stream. It's right? how to do this in a separate method in the general case (suppose I want my handler to accept an array of data bytes and a content type and can be loaded from a separate answer. I really don't want to use a separate page for the response.

UPDATE
I still haven't found a good solution. I would like to do some actions after the user has downloaded the file, but not using a separate page for the answer \ request.

+6
source share
8 answers

Update
Since you did not specify a second page, do it instead. Add a section to your page that checks the query string parameter (something like fileid, or path, etc.). If this value is present, it initiates the boot process using existing code. If this value is missing, it works as usual.

Now, when the user clicks the download link, you are recording back (which you are already doing). In this post, create an iFrame on the page and set the iFrame URL to the URL of your pages with the query string parameter added (mypage.aspx? Id = 12664 or? Download = true, something like that). After creating the iframe, do some extra databinds / etc ... you want too.

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

The link example above uses the iFrame panel and update, as you say.

Original publication
Response.Flush will allow you to continue processing after sending the file to the user or simply does not call Response.End (you also do not need it).

However, Daniel A. White is right, you cannot redirect your code after sending the file, you will receive an error message if you try. BUT, you can continue to perform other server-side operations if you need to.

Other answers agree with the general consensus, you cannot redirect after downloading the file: fooobar.com/questions/101698 / ... (PHP, but the same concepts, since it includes HTTP in General). or Direction to a new page after downloading the file .

+7
source

Response.End () throws a thread interruption exception. It is intended to complete your response. After that, the code will not be processed in this thread.

The End method causes the web server to stop processing the script and return the current result. The remaining contents of the file are not processed.

What are you trying to achieve?

If your goal is to allow the download of a PDF file and then take the user to some other page, a little javascript can help you.

Add a timer script to set location.href for your redirect paged.

+5
source

As stated in previous answers - return PDF files to send HTTP headers. After that, you cannot send other headers, and Response.Redirect () just means send HTTP 302.

If you do not want to have a separate page or if you do not want to use AJAX, why not try:

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

In fact, this will show the desired page that you want to show to the user, and refresh the page after 3 seconds with the URL to download the PDF file.

+1
source

Upload the file to chunks, as shown in the image Uploading a file to ASP.NET and tracking the success / failure status of the upload, or answer this question . When the last fragment of the file was written to the client, you can execute the code that you need. (It’s not necessary to be at the end, maybe anywhere between you depending on your needs.)

+1
source

the user clicks the download button on WebForm1.aspx to start downloading the file. then, after the download of the file is completed (served by WebForm2.aspx ), the user is automatically redirected.

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 } 

Note: make sure you are not using ashx (generic handler) to download your download. for some reason, the session in ashx and aspx does not talk to each other unless you implement this .

0
source

Just remove context.Response.End(); because you are redirecting anyway ...

The problem is that there is erroneous logic ... Why would you end the answer?

Get a PDF file and display a link to it, or use the META update to redirect to the location of the PDF file, or you can also display the link or use a combination of both methods.

0
source

I believe that what you are trying will not work.

This is what I would do:

  • Write contents to a file locally and assign it a unique identifier
  • send the user to the next page containing a hidden frame that executes a request with a unique identifier (javascript)
  • a hidden request page downloads the file and clicks on the content stream.

This is the same behavior as many file upload sites. The only problem is that the hidden frame crashes (javascript is disabled) to execute the request, why many of the same sites have an available link if the automatic request does not work.

Disadvantage: file cleanup.

0
source

I recommend this solution:

  • Do not use response.End ();

  • Declare this global var: bool isFileDownLoad;

  • Right after your (Response.BinaryWrite (a);) set ==> isFileDownLoad = true;

  • Cancel your Render as:

    /// /// AEG: it is very important to handle the flow interruption exception /// /// override protected void Render (HtmlTextWriter w) {if (! IsFileDownLoad) base.Render (w); }

0
source

Source: https://habr.com/ru/post/916806/


All Articles