I have a problem with not getting a postback after Response.End();
So the scenario is that i will click a button, clean an xmlfile and generate a message (out msg), download the xml, and then show the message in a label on the webpage. The problem is that it doesn't do anything after Response.End().
protected void btnDoIt_Click(object sender, EventArgs e)
{
string xml = "exampleXml";
string fileName = "exampleName";
MemoryStream ms = new MemoryStream();
string msg;
var cleanXml = CleanXml(xml, out msg);
cleanXml.Save(ms);
byte[] bytes = ms.ToArray();
Response.Clear();
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.xml", fileName));
Response.ContentType = "text/xml";
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
lblFeedback.Text = msg;
lblFeedback.Visible = true;
}
I tried moving the code in front of response.End(), like below, but it didn't work as well for some reason.
protected void btnDoIt_Click(object sender, EventArgs e)
{
string xml = "exampleXml";
string fileName = "exampleName";
MemoryStream ms = new MemoryStream();
string msg;
var cleanXml = CleanXml(xml, out msg);
lblFeedback.Text = msg;
lblFeedback.Visible = true;
cleanXml.Save(ms);
byte[] bytes = ms.ToArray();
Response.Clear();
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.xml", fileName));
Response.ContentType = "text/xml";
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
I also tried to "Click" an invisible button to get the postback like below. Didn't work either.
protected void btnDoIt_Click(object sender, EventArgs e)
{
string xml = "exampleXml";
string fileName = "exampleName";
MemoryStream ms = new MemoryStream();
string msg;
var cleanXml = CleanXml(xml, out msg);
InvisibleButtonClick(msg)
cleanXml.Save(ms);
byte[] bytes = ms.ToArray();
Response.Clear();
Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.xml", fileName));
Response.ContentType = "text/xml";
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
private void InvisibleButtonClick(string msg)
{
lblXmlFeedback.Text = msg;
lblXmlFeedback.Visible = true;
InvisibleButton_OnClick(new object(), new EventArgs());
}
protected void InvisibleButton_OnClick(object sender, EventArgs e)
{
}
What am i missing here?
What you do not have understand is that the return from IIS to the browser can be one stream only.
In your case, you believe that you can send two.
What is actually happened?
A. You post back some data from the web page.
B. You return some file for download from the user.
C. There the stream end and close – nothing is going to the browser any more. So there is no way the page to refress, and there is no way the data on the page to change because you send nothing any more to the page.
How to solve this.
a) You can make a handler that download the file and you only give a link in the page, a link to the handler that download the data.
b) you can make some other page that you redirect him with the message that you like to send, and there automatically with some javascript you start downloading your file.
c) you can use ajax to download your extra data, and javascript to show any message
similar answers
What is the best way to download file from server
file download by calling .ashx page
Updating a page before initiating a download?
Related
I am trying to call a method to view a PDF
I am attempting to call the method from the URL eg. /Home.aspx/ViewPDF
The ViewPDF in the url is the method in the Home.aspx file.
I am new to ASP and this has stumped me, thanks if you can provide any help
EDIT 1:
I have an asp button with this in it's click method and it works:
protected void test12_Click(object sender, EventArgs e)
{
string FilePath = Server.MapPath("/Tasks/Content/54874/dummy.pdf");
WebClient User = new WebClient();
Byte[] FileBuffer = User.DownloadData(FilePath);
if (FileBuffer != null)
{
Response.ContentType = "application/pdf";
Response.AddHeader("content-length", FileBuffer.Length.ToString());
Response.BinaryWrite(FileBuffer);
}
}
How would I be able to make the same thing happen from visiting /Home.aspx/ViewPDF
with /ViewPDF being a method inside the code behind of Home.aspx
I believe the method needs to be static to be able to view it from the url is there any alternative for defining the file path as Server.MapPath is not static.
I have made a test method in Home.aspx:
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public static string test(object sender, EventArgs e)
{
return "test";
}
But when I visit /Home.aspx/test it just loads a version of the page with no images and slightly off css
Thanks for any help
Edit 2 / Solution:
After doing a bit of looking around on google you can easily implement MVC into web forms
https://www.davepaquette.com/archive/2013/12/30/so-you-inherited-an-asp-net-web-forms-application.aspx
From that I made a controller
public FileResult GetTaskAttatchment()
{
string ReportURL = Server.MapPath("/Tasks/Content/54874/dummy.pdf");
byte[] FileBytes = System.IO.File.ReadAllBytes(ReportURL);
return File(FileBytes, "application/pdf");
}
Which now works perfectly, Thanks again for all the help
//check your datatype for attachment shuld be varbinary...
protected void btnfinalupload_Click(object sender, EventArgs e)
{
string filename = "";
string filenameret = "";
using (DataSet ds = GetFormForDownload(id,finid))
{
if (ds.Tables[0].Rows.Count > 0)
{
filenameret = ds.Tables[0].Rows[0]["attachment"].ToString().Trim();
filename = ds.Tables[0].Rows[0]["filename"].ToString().Trim();
byte[] bytes;
string fileName, contentType;
bytes = (byte[])ds.Tables[0].Rows[0]["attachment"];
contentType = "application/pdf";
fileName = filename;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
Response.BinaryWrite(bytes);
Response.Flush();
Response.End();
}
}
}
I've been searching around the internet, but couldn't find any useful answer.
I have an ASP.NET web site, which is deployed on server.
The ASP.NET web site on the server can access a directory called W:/ .
The clients in the company can access the web site. The web site lists in a ListBox all the PDF files from the W:/ directory. The client should be able to select PDF files from the listbox and save them to it's local PC by selecting a location for it.
Something like save as file on web pages.
Could you provide me some solution or work around ?
Finally I've found an article, which Prompts a Save Dialog Box to Download a File from ASP.NET
I post it here, might help somebody else as well and save some time.
String FileName = "FileName.txt";
String FilePath = "C:/...."; //Replace this
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
This is an extension to user1734609's solution that gets a file locally.
To download a file from the server to client:
public void DownloadFile()
{
String FileName = "201604112318571964-sample2.txt";
String FilePath = AppDomain.CurrentDomain.BaseDirectory + "/App_Data/Uploads/" + FileName;
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
}
The correct keywords are "File Browser asp.net" to find a lot of examples with source code.
Here is one from codeproject:
http://www.codeproject.com/Articles/301328/ASP-NETUser-Control-File-Browser
Get file contents in byte[] from W drive and write it to local file.
byte[] data = File.ReadAllBytes(WDriveFilePath)
FileStream file = File.Create(HttpContext.Current.Server.MapPath(MyLocalFile));
file.Write(data, 0, data.Length);
file.Close();
I have done something like this to get the file .
protected void btnExportFile_Click(object sender, EventArgs e)
{
try
{
Thread newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
// try using threads as you will get a Current thread must be set to single thread apartment (STA) mode before OLE Exception .
}
catch (Exception ex)
{
}
}
static void ThreadMethod()
{
Stream myStream;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
// Code to write the stream goes here.
myStream.Close();
}
}
}
I have a very particular scenario where user can download a file from server by clicking on a button on the web page. I am achieving this through Response object. This is working fine.
But now I want to close the web page once the download completes. I have already tried the below code.
protected void btnDownloadFM_Click(object sender, EventArgs e)
{
bool isSucced = DownloadFile();
if (isSucced)
{
ClientScript.RegisterStartupScript(typeof(Page), "closePage", "window.close();", true);
}
}
The above code is not working. But if I comment out the file download code it is working fine(the web page close properly).
protected void btnDownloadFM_Click(object sender, EventArgs e)
{
//bool isSucced = DownloadFM();
bool isSucced = true;
if (isSucced)
{
ClientScript.RegisterStartupScript(typeof(Page), "closePage", "window.close();", true);
}
}
Below is the code block for downloading the file.
private bool DownloadFM()
{
try
{
//Get the file byte array from DB.
byte[] bytes = GetFileBytesFromDB();
string fileName = "DownloadedFile.txt";
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
string contentDisposition;
if (Request.Browser.Browser == "IE")
contentDisposition = "attachment; filename=" + Uri.EscapeDataString(templateName);
else
{
contentDisposition = "attachment; filename*=UTF-8''" + Uri.EscapeDataString(templateName);
}
Response.AddHeader("Content-Disposition", contentDisposition);
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.AddHeader("X-Download-Options", "noopen");
Response.ContentType = "application/octet-stream";
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.Flush();
Response.Close();
return true;
}
catch (Exception ex)
{
//Log error message to DB
return false;
}
}
Am I doing anything wrong here?
Try registering window close before close (Not tested)
Just found similar solution here
closing a window after Response.End
....
....
ClientScript.RegisterStartupScript(typeof(Page), "closePage", "window.close();", true);
Response.Flush();
Response.Close();
OR
Response.Clear();
Response.Write("<script>window.close();</script>");
Response.Flush();
Response.End();
after flushing file you have to return and no need to close window after flushing content it's close automatically
protected void btnDownloadFM_Click(object sender, EventArgs e)
{
DownloadFile();
Return;
}
try this hope it helps you
From a file .aspx I need to have a redirect to a webpage, open it then download a file. Following my code:
page Source.aspx
<script runat="server">
protected override void OnLoad(EventArgs e)
{
Response.Redirect("Dest.aspx?download=true");
base.OnLoad(e);
}
</script>
page Dest.aspx
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
string download= (string)Request.QueryString["download"];
if (download == "true")
{
string url = "myurl/myfile.exe";
System.Net.HttpWebRequest objRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
System.Net.HttpWebResponse objResponse = (System.Net.HttpWebResponse)objRequest.GetResponse();
int bufferSize = 1;
Response.ClearHeaders();
Response.ClearContent();
Response.AppendHeader("content-disposition:", #"attachment;filename=""myFileName.exe""");
Response.AppendHeader("Content-Length", objResponse.ContentLength.ToString());
Response.ContentType = "application/download";
byte[] byteBuffer = new byte[bufferSize + 1];
System.IO.MemoryStream memStrm = new System.IO.MemoryStream(byteBuffer, true);
System.IO.Stream strm = objRequest.GetResponse().GetResponseStream();
byte[] bytes = new byte[bufferSize + 1];
while (strm.Read(byteBuffer, 0, byteBuffer.Length) > 0)
{
Response.BinaryWrite(memStrm.ToArray());
Response.Flush();
}
Response.Close();
Response.End();
memStrm.Close();
memStrm.Dispose();
strm.Dispose();
}
}
</script>
Two problems now:
Calling the page "Source.aspx" the download is automacally started but the page Dest.aspx is not shown in the browser
The downloaded file is called "Dest.aspx" instead of "myFileName.exe" ads I've set with
Response.AppendHeader("content-disposition:", #"attachment;filename=""myFileName.exe""");
For your second problem Issue Try something like that
string attachment = string.Format(CultureInfo.InvariantCulture, "attachment; filename=" + sfilename + "", fi.Name);
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", attachment);
Hope it works for you.
RIght, what you need to be doing is split the process in two:
Display your page and set a redirect value in the header to automatically redirect to your download.
download your file.
the important thing to note is that you can either respond with a web page, OR with a file, not both at once.
I've been searching around the internet, but couldn't find any useful answer.
I have an ASP.NET web site, which is deployed on server.
The ASP.NET web site on the server can access a directory called W:/ .
The clients in the company can access the web site. The web site lists in a ListBox all the PDF files from the W:/ directory. The client should be able to select PDF files from the listbox and save them to it's local PC by selecting a location for it.
Something like save as file on web pages.
Could you provide me some solution or work around ?
Finally I've found an article, which Prompts a Save Dialog Box to Download a File from ASP.NET
I post it here, might help somebody else as well and save some time.
String FileName = "FileName.txt";
String FilePath = "C:/...."; //Replace this
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
This is an extension to user1734609's solution that gets a file locally.
To download a file from the server to client:
public void DownloadFile()
{
String FileName = "201604112318571964-sample2.txt";
String FilePath = AppDomain.CurrentDomain.BaseDirectory + "/App_Data/Uploads/" + FileName;
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
response.ClearContent();
response.Clear();
response.ContentType = "text/plain";
response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
response.TransmitFile(FilePath);
response.Flush();
response.End();
}
The correct keywords are "File Browser asp.net" to find a lot of examples with source code.
Here is one from codeproject:
http://www.codeproject.com/Articles/301328/ASP-NETUser-Control-File-Browser
Get file contents in byte[] from W drive and write it to local file.
byte[] data = File.ReadAllBytes(WDriveFilePath)
FileStream file = File.Create(HttpContext.Current.Server.MapPath(MyLocalFile));
file.Write(data, 0, data.Length);
file.Close();
I have done something like this to get the file .
protected void btnExportFile_Click(object sender, EventArgs e)
{
try
{
Thread newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
// try using threads as you will get a Current thread must be set to single thread apartment (STA) mode before OLE Exception .
}
catch (Exception ex)
{
}
}
static void ThreadMethod()
{
Stream myStream;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
// Code to write the stream goes here.
myStream.Close();
}
}
}