Problem with postback after Response.Write

R

Russ

My web app writes some binary data to a file at the client site via
Response.Write and Response.BinaryWrite. This action is accomplished
in response to a button click, with C# code behind as follows:

private void SubmitButton_Click (object sender, System.EventArgs e)
{
// Set up the response to write the print file to the client
Response.Clear ();
Response.AppendHeader ("Content-Disposition",
"filename=WebPrint.prn");
Response.ContentType = "application/octet-stream";

int len = CalcLength ()
Response.AppendHeader ("Content-Length", len.ToString ());

Response.Write (s); // Write some string data
Response.BinaryWrite (buf); // Write binary data
Response.End ();
}


This works fine. But my problem is that after the browser puts up the
File Download box and the user saves the file, the page does not get
posted back. After the file is downloaded I need to transfer control
to another page, and I can find no way to do it.

I've tried replacing Response.End with Response.Redirect with no
effect. Adding Server.Transfer after Response.End, or even in place
of it has no effect - I can trace the code and the function is called,
but the page is never posted back so the action does not happen.

Help???

Thanks, Russ
 
P

Patrice

I don't see how to proceed as you can only transmit the content of the file
to the browser.

I would open the download page in another window... (a href target)

Patrice
 
R

Russ

Patrice, thanks for the answer but I don't understand. First, why can
I "only transmit the content of the file to the browser"? Normally
when I click on a button in an asmx page, I can change the page and
transmit it back so that on postback the changed page is displayed.
All I am adding here is the file download. It seems like after the
file is downloaded I should be able to trigger some action??? I've
spent a lot of time exploring help files and searching with google but
have been unable to find anything to explain this behavior. Can you
point me to a suitable reference?

Second, I don't understand why or how using an href target will help.
If I do the download in a different page, won't I have the same
problem - namely that when the download is done, the browser will just
sit there in that new window and I have no way to make it go back to
the original window.

Also, I would like to execute some script before or after the new
window is launched. I can accomplish this with session variables, but
that will only work if I can cause the new aspx page to be loaded.

Thanks for any additional help.

Russ
 
G

Guest

See if this works for you.

Response.AppendHeader("Refresh", "1020;URL=anotherpage.aspx")

To answer your question, you have issued the Response.End() to signal the
end of transmission of the file. It is not possible to perform a postback or
for that matter any action after that. Remember that HTTP is a stateless
protocol.
 
P

Patrice

What do you mean by "posting back" ?

My understanding is that you want to stream a file in response to a request.
As you send a file, you have to send only the file content, no more, no
less. Though you can still perform some code after sending the file,
response.redirect would write an additonnal header to the response. The
supplemental header suggested by someone else could work as it is to be
written before.

The usual download scheme is rather to have a link on page and when you
click this link, the download page is just called in a "new" window. As this
is not HTML content, the browser doesn't open a new HTML window but instead
will open the usual file download dialog and the user just handles then the
"download in progress" window. You could immedialty display something in the
"parent" window (without waiting for the download to be completed).

What is this special thing you want to display aftert the download ? The
user could as well choose to close the browser and to keep just the currenly
download window (and would never see then waht you want to display). Apart a
header, a trick could be perhaps to trigger the download using a child
element (such as iframe ?). As the DOM allows to test for child element to
be completed it could perhaps work (IMO too tricky ).

Finally I would first check if the usual "download from a link and it opens
the browser download dialog" scheme that is the usual scheme is really not
applicable here...

Note that performing some code server side is not the problme. The problem
is that you want to display something to the user once the download is
completed...

Patrice

--
 
R

Russ

STech, thanks for your suggestion. It does not work though.. But it
brings up a question. How does one know about what headers and
options are available and what they do? I have searched the VS.NET
documentation and not been able to find much on the subject. The only
thing I could find about Refresh was:
REFRESH (46)
Obsolete. Maintained for legacy application compatibility only.

But it does not say what has replaced it, or give any list of values
that can be used with any of the headers.

I realize that some of my questions may be simple for an experienced
web programmer, but I have never worked with Web programming or HTML
before and all the various pieces seem far flung and sparsely
documented.

Thanks, Russ
 
R

Russ

What do you mean by "posting back" ?

Well, I believe I have the terminology right, but maybe not. Im my
mind, postback is when a runat=server control is used. The browser
connects to the server - the server executes some code and generates a
new copy of the web page (or possibly transfers control to a different
page), and sends the changed page back to the browser which displays
it. So the posting back is two steps - the browser posts back to the
server and then the server posts back to the browser. In my case, the
problem seems to be that there seems to be no way to post back to the
server after the download dialog has completed.
My understanding is that you want to stream a file in response to a request.
As you send a file, you have to send only the file content, no more, no
less. Though you can still perform some code after sending the file,
response.redirect would write an additonnal header to the response. The
supplemental header suggested by someone else could work as it is to be
written before.

It didn't work. The problem is that I am not really downloading a
file. The data being written to the file is assembled 'on the fly' by
the server and sent to the browser via the Response.Write calls. The
browser allows the user to save the data as a file and then an ActiveX
control is supposed to be run. (The Activex control parses the file
and sends the various sections of it to the printer as separate
reports.) This should be as transparent to the user as possible. It
is asking a lot of the user to have to click the button that says
"print these reports", then go though the download dialog to save a
file, and then click another button to say "now REALLY print them".

My alternative is to make the button that says "print these reports"
instead say "download these reports". Then supply a separate button
to say "print the downloaded reports". That would not be so bad, but
I would want the 'print' button to be disabled until after the
download is complete. (Otherwise the user could click the print
button before the file was downloaded, and might print some reports
from the last time instead of what he wanted.) Since I cannot get
control after the download is complete, there is also no way to enable
the print button - unless you or someone comes up with a magic bullet
that will do this.
...Note that performing some code server side is not the problme. The problem
is that you want to display something to the user once the download is
completed...

That's exactly right. This is a Web Business application and the same
rules that apply for casual web browsing do not work too well.
Microsoft has been touting ASP.NET applications for business use, but
it seems like a lot of needed functionality is either missing or hard
to find. I've been thinking about trying the new version but someone
said it would not be ready for production use for another year and I
cannot wait that long. Hopefully there exists work-arounds for some
of the issues I am facing.

Thanks for all your help.

Regards, Russ
 
P

Patrice

Ok, I believe the correct terminology is :
- the browser makes a request to the server (GET to get the page)
- the user enter values and click the submit button
- the browser POST those data to the original page (post back)
- the server could then resend the page or somewhere else

It's always better to have the whole picture. What is this ActiveX control ?
From where can it get its data ?

If this is under control I would do something like :
- the file content could be passed to the activeX control as a PARAM tag

If there is a size limit for this tag, it could be likely stored inside the
document. You can then tell the ActiveX control the id of the page element
that holds the data (likely not familiar with controls hosted in a page but
I assume they can access the surrounding HTML page). Or thorugh it's
progamming model, you could have some JavaScript that transfer the data.

You could also have perhaps the ActiveXControl contacting the server to get
the data.

Also could you deliver this file as a single PDF file and let the user print
it ??

Patrice
--
 
R

Russ

Ok, I believe the correct terminology is :
- the browser makes a request to the server (GET to get the page)
- the user enter values and click the submit button
- the browser POST those data to the original page (post back)
- the server could then resend the page or somewhere else

It's always better to have the whole picture. What is this ActiveX control ?
From where can it get its data ?

It's one I wrote myself. It expects only a filename as input. It
must be a file on the client machine. The file consists of multiple
reports and header data for each report. The control reads each set
of header and report data and spools them to the printer specified by
the header.
If this is under control I would do something like :
- the file content could be passed to the activeX control as a PARAM tag

I think that would be impractical because of the size of the
combination of all the reports. At times there will be up to 10 or 12
reports to be printed at once. The way it works now is that the web
server reads each separate report from a back end server via a web
service running on that back end server. It then sends it to the
browser, one report at a time using Response.Write and
Response.BinaryWrite. One thing I am not yet clear on is if the calls
to Response.Write buffer all the data up and send it to the browser
at once, or if it sends each section as it is generated. I call
Response.Flush after each section so I hope that pushes the data out
to the browser each time. If not, I may have to play with turning off
caching.

I could build the file on the web server and then use
Response.WriteFile, but I think that is a reduction in security. If
someone hacks into the webserver they could get that file. I'd like
to keep all the sensitive data either behind the dual firewalls in the
back end server, or in the XML and encrypted data stream between the
web server and the client's browser. Perhaps you have some input on
those thoughts.
You could also have perhaps the ActiveXControl contacting the server to get
the data.

That is something I have thought about, but I cannot see how to do it.
The Activex control would have to somehow access the SSL channel
between the client and the web server. If there is a way to do that,
I have not seen any documentation about it. Or maybe it could set up
and independent SSL channel to the web server. That would be better
but I suspect I will have to deal with multiple SSL user prompts for
each channel - a real pain for the user. I have not yet set up the
SSL and certificates in my testing so that is a whole 'nother project,
yet to do.
Also could you deliver this file as a single PDF file and let the user print
it ??

No, because the file contains binary data (printer codes, raster data
for signatures, and logo's, and font data for printing MICR data on
checks) that must be sent to the printer, interspersed with the actual
text. Also, the user may have multiple printers and different reports
must go to different printers. The Active-X control handles this.

Thanks, Russ
 
R

Russ

Patrice, I am leaving this morning, for a 1 week trip. But I will
read any response you may have to my last post when I get back.

Thanks again, Russ
 
P

Patrice

Ok so basically the goal is to download several files. For some reason you
have to download these files each in turn before processing them rather than
all in one chunk ?

With IE, you have the usual request/response model. I would rather embed
this in the ActiveX control. The ActiveX control can likely use the
"WinInet" API to get in touch with its originating server (also
http://msdn.microsoft.com/library/default.asp?url=/workshop/components/activex/buildax.asp
mentions an "Internet Client SDK"). It doesn't have to be a file. It can be
an ASPX page that build its content on the fly.

Patrice

--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top