I've been looking for an answer for a week now and I give up.
I'm creating an excelfile and then let the user download it to his client with TransmitFile.
The thing is, this works perfectly most of the time, but in some cases (can be repeated), after the Response.End, the page reloads and page_load is called. The flag IsPostBack is false.
This behaviour interrupt the download and the whole application stop working, displaying connecting to server.
foreach (string filename in Directory.GetFiles(WebConfigurationManager.AppSettings.Get("EXCEL_PATH")))
{
if (File.GetLastWriteTime(filename) < (DateTime.Now.AddDays(-1)))
{
File.Delete(filename);
}
}
ClsOrderFormData ofData = new ClsOrderFormData(ddOrderTypes.SelectedValue, OF.Customer.CustomerCategory);
ClsExportOF xls = new ClsExportOF(OF.SizeDims, ofData, OF.Customer, Request.PhysicalApplicationPath, ClsPrintOrder.getOrderData().TheOrder.Articles);
string sFileName = xls.CreateExcelFile();
FileInfo OutFile = new FileInfo(WebConfigurationManager.AppSettings.Get("EXCEL_PATH") + sFileName);
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=Abacus_OF_" + ddOrderTypes.SelectedItem.Text + "_" + ddCustomer.SelectedItem.Text + "_" + DateTime.Now.ToShortDateString() + ".xls".Replace(',', '-'));
Response.ContentType = "application/vnd.ms-excel";
Response.TransmitFile(WebConfigurationManager.AppSettings.Get("EXCEL_PATH") + sFileName, 0, OutFile.Length);
Response.Flush();
Response.End();
In short. When it works no more code is executed after Response.End(), as expected. When it don't work it continue with page_load and so on, and the site hangs.
Any tips?
Trying using HttpApplication.CompleteRequest instead of Response.End. Response.End is probably throwing a ThreadAbortException which is messing up the process.
see...
http://ardalis.com/Use-HttpApplication.CompleteRequest-Instead-of-Response.End
http://weblogs.asp.net/hajan/archive/2010/09/26/why-not-to-use-httpresponse-close-and-httpresponse-end.aspx
Related
In my application I need to download a file, So I am using this piece of code:
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename =" + strFileName + ".xls");
Response.TransmitFile(strFilePath);
Response.End();
at Response.End() i am getting an error ThreadAbortException
To aviod this error I am trying to use httpApplication.CompleteRequest(),
but i m not able to use this too.
The code with httpApplication.CompleteRequest() is below,
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename =" + strFileName + ".xls");
Response.TransmitFile(strFilePath);
HttpApplication.CompleteRequest();
I m getting this error when i m using HttpApplication.CompleteRequest()
An object reference is required for the non-static field, method, or property 'System.Web.HttpApplication.CompleteRequest()'
I hope i m able to make my doubt clear...
help me out....
Response.End() is expected to throw a ThreadAbortException.
This is by design, so that the rest of the page response is not processed.
It is perfectly ok to get this exception, and it will ensure the page is not processed further.
Refer: HttpResponse.End
The CompleteRequest method does not raise an exception, and code after
the call to the CompleteRequest method might be executed. If your
intention is to avoid execution of subsequent code, and if the
performance penalty of End is acceptable, you can call End instead of
CompleteRequest.
Try this code:
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename =" + strFileName + ".xls");
Response.TransmitFile(strFilePath);
HttpContext.Current.ApplicationInstance.CompleteRequest();
The error occures because you are using a ASP update panel or any control using JavaScript. Try to use control native from ASP or HTML without JavaScript or ScriptManager or scripting.
I have experienced this problem and have solved it with the following code
ScriptManager sm = ScriptManager.GetCurrent(this.Page);
sm.RegisterPostBackControl(this.grid);
Just comment this line and you're good to go:
//Response.End();
It worked for me :)
So here is my problem: I have a code that use response to ExportFile, but the problem is after the response code. the succeeding code no longer executes or it is like being read but ignored. sorry for being noob. so here is my code:
fullFilePath = "" + rootPath + "" + Filename + ".xlsx";
string fileName = fullFilePath.Substring(fullFilePath.LastIndexOf('\\') + 1);
byte[] buffer;
using (FileStream fileStream = new FileStream(fullFilePath, FileMode.Open))
{
int fileSize = (int)fileStream.Length;
buffer = new byte[fileSize];
// Read file into buffer
fileStream.Read(buffer, 0, (int)fileSize);
}
Response.Clear();
Response.Buffer = true;
Response.BufferOutput = true;
Response.ContentType = "application/x-download";
Response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.CacheControl = "public";
// writes buffer to OutputStream
Response.OutputStream.Write(buffer, 0, buffer.Length);
newFile.Delete();
ClientScript.RegisterStartupScript(GetType(), "id", "EnableCtrl()", true);
after this has been executed the javascript "EnableCtrl()" is not being fired or triggered. And when I delete the part of code which is related to response and change it to something else the javascript is being triggered. So how could i run a javascript after a response code?
The script won't/can't be triggered this method because the browser has already been sent the response: which is the file, and not the markup from a post-back. One request. One response. And it wasn't the post-back markup.
Instead, I would suggest either:
Handling the "Client Click" of the initiating control in the browser as well (the action could be delayed with setTimeout). Browser won't actually refresh the page/DOM because of the attachment disposition in the response, which is why this works. However, there are no client-side events for if a download was accepted, has started, or has completed1
Change the design so the "download" is a separate action with no other side-effect.
Happy coding.
1 It's possible to contrive server-assisted setups that allow the client to query the progress of a download, much like an upload progress indicator. However, this is not trivial or standard and may still not accurately reflect the state.
I am writing a webapplication in ASP.net.
I am trying to make a file dialog box appear for downloading something off the server.
I have the appropriate file data stored in a variable called file.
File has fields:
FileType - The MIMEType of the file
FilePath - The server-side file path
Here's the code so far:
Response.Clear();
Response.ContentType = file.FileType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + GetFileName(file));
Response.TransmitFile(file.FilePath) ;
Response.End();
GetFileName is a function that gets me the filename from an attachment object. I only store the path.
The above code is in a function called "Download_Clicked" that is an event that triggers on click. The event is mapped to a LinkButton.
The problem is that when I run the above code, nothing happens. The standard dialog box does not appear.
I have attempted the standard trouble-shooting such as making sure the file exists, and ensuring the path is correct. They are both dead on the mark.
My guess is that because my machine is also the server, it may not be processing properly somehow.
Thanks in advance.
Edit 1: Attempted putting control onto another page, works fine.
Edit 2: Resolved issue by removing control from AJAX Update Panel.
I've found another to do this without removing the update panel. Place the code below in your page load and you'll now be able to use that button to trigger a download.
ScriptManager.GetCurrent(this.Page).RegisterPostBackControl(Button);
Use Response.WriteFile() instead.
Also, don't use Response.End()! This aborts the thread. Use Response.Flush(); Response.Close();
Try changing
Response.AppendHeader("Content-Disposition", "attachment; filename=" + GetFileName(file));
To
Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(GetFileName(file))));
If that doesn't work, you can always use Response.BinaryWrite or Resonse.Write to stream the file to the web browser
Here is how transmit the file using Response.Write or Response.BinaryWrite. Put these functions in a library somewhere then call them as needed
public void SendFileToBrowser(String FileName, String MIMEType, String FileData)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.ContentType = MIMEType;
Response.Buffer = true;
Response.Write(FileData);
Response.End();
}
public void SendFileToBrowser(String FileName, String MIMEType, Byte[] FileData)
{
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.ContentType = MIMEType;
Response.Buffer = true;
Response.BinaryWrite(FileData);
Response.End();
}
Then somewhere you call these functions like so
SendFileToBrowser("FileName.txt", "text/plain", "Don't try this from an Update Panel. MSAjax does not like it when you mess with the response stream.");
See edit on initial post.
Removed Ajax Update Panel to resolve the error. The panel was stopping the post back to the server.
For more info, see Cris Valenzuela's comment.
I export a datatable to word, when I pass a file name it doesn't seem to get the file name in Open/Save dialog box.
Here is what I am doing
public static void Convertword(DataTable dt, HttpResponse Response,string filename)
{
try
{
Response.Clear();
Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".doc");
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.word";
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
System.Web.UI.WebControls.GridView dg = new System.Web.UI.WebControls.GridView();
dg.DataSource = dt;
dg.DataBind();
dg.RenderControl(htmlWrite);
Response.Write(stringWrite.ToString());
Response.End();
}
catch(Exception err)
{
throw err;
}
}
When I pass filename "report(" + System.DateTime.Now.ToString("dd/MM/yyyy");
+ ")" it doesn't take the value as dd/MM/YYYY instead it shows file name as dd_MM_YYYY
Few remarks about your code:
You are setting the content type header to a word document but you are actually sending HTML contents by rendering a GridView
dd/MM/YYYY is not a valid filename because of the / character.
You don't need a try/catch block if in the catch statement you are only doing throw err
Calling Response.End at the end is not necessary.
Always use using statement when dealing with disposable objects such as streams and readers/writers to ensure that the Dispose method is invoked in all cases.
You should to use a filename like
String.Format("report{0:ddMMyyyy}.doc", DateTime.Now);
A filename cannot have "/".
That's most likely because / isn't a valid character for filenames. Your name must fulfill certain criteria, be sure not to use any of
* . " / \ [ ] : ; | = ,
If you have forward slashes in the filename, I would assume that this would break the URL to the file and hence the slashes are being replaced at some point?
The following code is implemented in Page_Load event to show SaveFileDialog to the user
string targetFileName = Request.PhysicalApplicationPath + "Reports\\TempReports\\FolderMasters" + Utility.GetRandomNumber() + ".pdf";
FileInfo file = new FileInfo(targetFileName);
// Clear the content of the response.
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = "application/pdf";
Response.TransmitFile(file.FullName);
Response.End();
How can I get the user response to SaveFileDialog, as I need to know user response to this dialog?
Also, is there something wrong with these lines of code, as I had the following exception
"Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack."
You can't get the user response to SaveFileDialog as all file-events have been blocked for browser-javascript as it could be a very big security-hole ...
I'm here again, as I got a solution for my second question.
For Response.End, call the HttpContext.Current.ApplicationInstance.CompleteRequest method instead of Response.End to bypass the code execution to the Application_EndRequest event.
Have look ...