Download file from database asp.net - c#

I am reading PDF data from a database field (database field format is 'Data') and I have converted it into bytes using data reader GetBytes and I have it right because it's working fine in other operation.
I added a button on aspx page, and, on button click, I have the below code to download it:
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment;filename="test.pdf");
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite(byteArray);
Response.End();
But it's not doing any thing. I mean when I click the button I can step through it but after response.end() nothing happens.
Any idea what I am doing wrong?

Move your button outside of update panel. You also need to add postback trigger as Oguz Ozgul mentioned it. Additionally you should add ThreadAbortException catch also just to stay safe...

Related

Writing data to Response, but keeping the page active

I'm trying to have a user click a button on a web page to download a CSV file, but I'm having problems sending the correct data to the user. In addition, once the file has been downloaded, I'd like the page to remain "active" i.e. the page can continue to trigger events to the server, such as clicking the Download button again.
This is the code I'm currently using, pieced together from various SO questions:
var sb = new StringBuilder();
string fileName = "data.csv";
// Build CSV file...
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("filename={0}", fileName));
HttpContext.Current.Response.ContentType = "text/csv";
HttpContext.Current.Response.Write(sb.ToString());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
This works so far as presenting the user with an option to open or download the file, but the file also contains the entire markup of the aspx file after the requested data, and the page is left completely inactive.
I'm guessing the problem is with the last two lines of the above code. I've tried using ApplicationInstance.CompleteRequest instead of Response.End, but this doesn't seem to change the outcome. The page is still inactive and the file still has the markup at the end. Can anyone help?
In case it makes any difference in the behaviour of Response, the page is an WebPartPage in SharePoint 2010.
Set the line
HttpContext.Current.Response.AddHeader("content-disposition", "filename={0}", fileName));
to
HttpContext.Current.Response.AppendHeader("content-disposition", String.Format("attachment;filename={0}", fileName));
And set the following property on your button
downloadButton.OnClientClick = "_spFormOnSubmitCalled = false;";
_spFormOnSubmitCalled is a javascript variable that SharePoint uses to stop multiple form submits and it is being set to true when you click the download button.
try this
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
HttpContext.Current.Response.ContentType = "application/CSV";

disable button not working after download file asp.net

I have the following code to download a file from the server to the client, that occurs when the button btnSavetoDB_ExportToExcel is clicked, after that I want to have the button disable, how can I achieve that?
string fileName = newFN + ".xlsx";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
Response.TransmitFile(DestFile);
Response.End();
btnSavetoDB_ExportToExcel.Enabled = false;
I noticed that the button did not become disable when placed the above code (Response), cause I had another code there and the button became disable with it. So it must be something related with the Response.
EDIT:
The button is within a ModalPopupExtender in case it matters.
The reason for this is that if you disable the button with server code you need to return the response to the browser window.
Here you return a stream that is captured by the browser as a file instead of to the browser window so the current display is never updated.
To get around this you can implement a javascript line on the button in the html itself.
You can use Attribute.Add() in code at Page_Load, f.ex:
btnSavetoDB_ExportToExcel.Attribute.Add("onclick","this.disabled=true")
There at least two possible solutions.
1) Instead of writing a file to the response you can generate file in the temp directory on the server and give the user the link to this file (or redirect to this link).
2) If you want use writing to the response, you can create new Generate.aspx page that writes the file to the response in its Page_Load method.
if (Request.QueryString["ID"] != null)
{
//find file by its ID
...
Response.AddHeader("Content-disposition", "attachment; filename=" + fileName));
Response.ContentType = "application/octet-stream";
Response.WriteFile(fullFileName);
Response.End();
}
On page with your btnSavetoDB_ExportToExcel in Page_Load add this code:
var script = #"<script language=JavaScript>function Export(fileID)
{
var iframe = document.createElement('iframe');
iframe.src = 'Generate.aspx?ID='+ fileID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
</script>";
Page.RegisterStartupScript("Startup", script);
And then just call javascript Export method to send file to the user.
As mentioned in the other answer, the button should be disabled in client side (since you are using Response.End() in your code, ASP.NET will never render the page with the button having Enabled=False.
In your .aspx file add
<asp:Button ID="btnSavetoDB_ExportToExcel" OnClientClick="this.disabled=true;" [..] />
But also note that this might not be a good idea altogether - what if the user accidentally clicks "Cancel" from the file download window?
A better solution (understanding that you want to prevent the user from clicking the button multiple times) is to add a timer to re-enable the button:
<asp:Button ID="btnSavetoDB_ExportToExcel" OnClientClick="var a=this; a.disabled=true; window.setTimeout(function() { a.disabled=false; }, 5000)" [..] />
Value 5000 is the time in miliseconds after which the button will be re-enabled.
I have found the solution to my problem, credit goes to: Dave Ward (click here)
<asp:Button ID="btnSavetoDB_ExportToExcel" runat="server"
OnClientClick="this.disabled = true;"
UseSubmitBehavior="false"
Text="Save results to DB and export to Excel"
onclick="btnSavetoDB_ExportToExcel_Click" />
this does the trick:
OnClientClick="this.disabled = true;"
UseSubmitBehavior="false"

c# asp.net click button to "save as", but downloaded file becomes unintentionally modified

I have a method in my C# codebehind that connects to SQL and creates a CSV file based upon the SQL data. This method is called when the user clicks a particular button on the website. I am trying to get this same method to also prompt the user to "open" or "save as" after the CSV file is generated.
I have tried the following:
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.AddHeader("Content-Disposition", "attachment; filename=" + "C:\\temp\\report.csv" + ";");
Response.TransmitFile("C:\\temp\\report.csv");
The user does get prompted to "open or save as". In either case, the data in the CSV file also contains the entire source code of my Default.aspx. What do I need to do to my code to prevent that extra data from being appended onto my CSV? TIA...
You can call response.End() to prevent further processing by your page.
You need to clear the Response first - Response.Clear();
response.Clear();
...
response.AddHeader("Content-Disposition", "attachment; filename=" + "C:\\temp\\report.csv" + ";");
Response.TransmitFile("C:\\temp\\report.csv");

ASP.NET Response Methods not Executed when they are encapsulated in ASP.NET AJAX Update Panel

I have the following code
// This calls a procedure that takes time
byte[] bytes = Export.export_products(this.LanguageID);
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment; filename=\"WTC_Watches_"+DateTime.Now.Month+"_"+DateTime.Now.Year+".csv\"");
using (var stream = new MemoryStream(bytes))
{
Response.AddHeader("Content-Length", stream.Length.ToString());
stream.WriteTo(Response.OutputStream);
}
Response.End();
This code executes on clicking of a button.
When i use the button in a ASP.NET UPDATE PANEL so that i can show the animation, The procedure executes but i dont get the dialog on clicking of it i can download the file that i generated.
I think the Response methods are not working if the page is not reloaded or postback since i am using ASP.NET Update Panel
Any help is appreciated.

Show Response.Binarywrite in browser save dialog or open new window and close after save

My problem looks like this.
I have a grid with documents (Id's). Now when somebody clicks at a row I would like to allow him to download or show that document. But to make it esier let's say that I would do this on a button click. I tried two approaches but none of them worked form me.
I tried to response.binarywrite on the button click:
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/postscript mime";
Response.AddHeader("content-disposition", "attachment; filename=test.ps");
Response.AddHeader("content-length", _excuteGetDocumentResult.Length.ToString());
Response.ContentEncoding = new System.Text.UTF8Encoding();
Response.BinaryWrite(_excuteGetDocumentResult);
But nothing happens and when I try to modify this code I usually get some javascript errors saying sommething about changing the response...
The socond approach was opening new window and on page load adding the code above.
<asp:Button Text="ShowResult" OnClientClick="radopen('ShowResult.aspx','ShowDocumentDialog'); return false;"
runat="server" />
The socond approach works but my opened window still exists after saving or canceling the explorer saving file dialog window. I tried to add some javascript to close it but it only works where there is no response.binarywrite on the load page...
Any ideas how I can achive what I want?
In method 1.
try Response.End(); after Response.BinaryWrite(_excuteGetDocumentResult);

Categories