Problem downloading a 25MB file - the 8MB file downloads without problem (ASP.NET) - asp.net

I have two files at the same location but the big one, when is about to finish download, gives an error (both in IE and Firefox).
I use the following code:
public static void DownloadZipFile (string filename, bool notifyMe)
{
HttpContext context = HttpContext.Current;
HttpServerUtility server = context.Server;
bool ok = false;
try
{
string file = string.Format ("~/contents/licensing/members/downloads/{0}", filename);
string server_file = server.MapPath (file);
HttpResponse response = context.Response;
//response.BufferOutput = false;
response.ContentType = "application/zip";
string value = string.Format ("attachment; filename={0}", filename);
response.AppendHeader ("Content-Disposition", value);
FileInfo f = new FileInfo (server_file);
long size = f.Length;
response.TransmitFile (server_file, 0, size);
response.Flush ();
ok = true;
response.End ();
}
catch (Exception ex)
{
Utilities.Log (ex);
}
finally
{
if (ok && notifyMe)
NotifyDownload (filename);
}
}
Any ideas?

Response.End() calls Response.Flush(). Try removing the Flush call.

The solution to this problem is to add the line:
response.AddHeader("Content-Length",size.ToString());
before the call to TransmitFile ().
The credits go to Jim Schubert (see his comment above).

Related

HTTP POST receiving more than one HTTP Response

I have an http POST being actioned via a .NET System.Net.WebRequest as follows:
...
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has uri={0}, body={1}", uri, messageBodyAsString));
System.Net.WebRequest req = System.Net.WebRequest.Create(uri);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(messageBodyAsString);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
try
{
using (System.Net.WebResponse resp = req.GetResponse())
{
if (resp == null) return null;
System.IO.StreamReader sr =
new System.IO.StreamReader(resp.GetResponseStream());
string rs = sr.ReadToEnd().Trim();
sr.Close();
resp.Close();
XXXUtilities.Log.WriteLog(string.Format("XXXHTTPPost PostToUri has string response = {0}", rs));
MongoDB.Bson.BsonDocument doc2 = new BsonDocument();
doc2.Add("Response", rs);
return doc2;
}
}
catch (System.Net.WebException e)
{...
This all works fine most of the time. However, looking at the log files that this creates I spotted something strange. The suspect log entries look like this:
18:59:17.0608 HPSHTTPPost PostToUri has uri=https://salesforce.ringlead.com/cgi-bin/2848/3/dedup.pl, body=LastName=Doe&FirstName=Jon
18:59:17.5608 HPSHTTPPost PostToUri has string response = Success
18:59:18.0295 HPSHTTPPost PostToUri has string response = Success
It seems that the Http Response is being received twice. Is this even technically possible? i.e. is it possible for an Http POST to receive two Responses, one after the other? If so, is my code below then liable to be called twice, thus resulting in the observed log file entries? Many thanks.
Edit:
In response to the comment that the logging code may be broken, here is the logging code:
public class Log
{
public static void WriteLog(string commandText)
{
string clientDBName = "test";
string username = "test";
try
{
string filePath = "c:\\Data\\XXXLogs\\" + clientDBName + "logs\\";
string filename = System.DateTime.Now.ToString("yyyyMMdd_") + username + ".log";
DirectoryInfo dir = new DirectoryInfo(filePath);
if (!dir.Exists)
{
dir.Create();
}
System.IO.FileStream stream = new System.IO.FileStream(
filePath + filename
, System.IO.FileMode.Append); // Will create if not already exists
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(); // Writes a line terminator, thus separating entries by 1 blank line
writer.WriteLine(System.DateTime.Now.ToString("HH:mm:ss.ffff") + " " + commandText);
writer.Flush();
stream.Close();
}
catch { }
}
}

I can't open .pdf, .doc etc. file from other servers via SFTP using rebex

I have Two different servers as like below.
1. WebServer - Where is my application is locate
2. FileServer - where is my all uploaded files are locate in perticular location / Folder
Now in my web application I have created one page which display all uploaded files from FileServer (which i have uploaded).
But the issue is, when I try to open/read that file then I am not able. I have all rights of SFTP. and I am getting below issue in Try-catch block.
"Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack."
I have used REBEX for upload and download files.
Note : I can able to open simple text file (.txt) but not other formated files like (.PDF, .docx, .jpg etc.)
My file read code is like below.
protected void LinkButton1_Click(object sender, EventArgs e)
{
try
{
LinkButton lbtn = (LinkButton)sender;
using (Sftp _sftp = new Sftp())
{
_sftp.Connect(serverNm, 22);
_sftp.Login(username, password);
_sftp.ChangeDirectory(currentDirectory);
Stream stream = _sftp.GetStream(lbtn.ToolTip.ToString(), FileMode.Open, FileAccess.Read);
StreamReader sourceStream = new StreamReader(stream);
Byte[] buffer = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
Response.Buffer = true;
if (lbtn.ToolTip.IndexOf(".pdf") > 0)
{
Response.ContentType = "application/pdf";
}
else if (lbtn.ToolTip.IndexOf(".txt") > 0)
{
Response.ContentType = "text/plain";
}
else if (lbtn.ToolTip.IndexOf(".xls") > 0)
{
Response.ContentType = "application/ms-excel";
}
else if (lbtn.ToolTip.IndexOf(".doc") > 0)
{
Response.ContentType = "application/msword";
}
else if (lbtn.ToolTip.IndexOf(".jpeg") > 0)// || lbtn.ToolTip.IndexOf(".jpg") > 0)
{
Response.ContentType = "image/jpeg";
}
else if (lbtn.ToolTip.IndexOf(".jpg") > 0)
{
Response.ContentType = "image/jpg";
}
else if (lbtn.ToolTip.IndexOf(".bmp") > 0)
{
Response.ContentType = "image/png";
}
Response.AddHeader("Content-Length", "attachment;filename=" + buffer.Length.ToString());
Response.BinaryWrite(buffer);
Response.End();
}
}
catch (Exception ex)
{
}
}
So any one can help to fixe this issue.
I am using latest Mozila browser.
Thank you.
Would it be possible to post the complete stack trace of the exception here? You can get the stack trace by modifying the catch block like this:
try
{
//... your code
}
catch (Exception ex)
{
Response.ContentType = "text/plain";
Response.Write(ex.ToString());
Response.End();
}

Path issue with wkhtmltopdf.exe to convert HTML file to PDF

I am using wkhtmltopdf to convert HTML file into PDF document on a link Button
http://code.google.com/p/wkhtmltopdf/
When User Click on a link Button it runs the following code as shown below code in pass file path as an argument ProcessStartInfo. THis code works fine in Following Scenarios only
Taking Into consideration that website is hosted on Domain http://www.xyz.net/
When i mention path as http://demo.XYZ.net/ It works fine
When i mention path as http://www.XYZ.net/ It doesn't work
In-case of local-host it works fine if path is http://localhost:51005/XYZ/or http://web:8080/
For this to work properly we need to give the website full trust level & i am not sure why code doesn't run i give it the same domain path if i create put PrintArticle.aspx if i create a sub domain then it will work fine. I am nost sure if this is a security problem or what
Code Below
protected void lnkbtnDownload_Click(object sender, EventArgs e)
{
//ConvertURLToPDF();
try
{
string url = "PrintArticle.aspx?articleID=" + Request["articleID"] + "&download=yes&Language=" + Request["Language"];
//string args = string.Format("\"{0}\" - ", "http://demo.XYZ.net/" + url); //Works
//string args = string.Format("\"{0}\" - ", "http://www.xyz.net/" + url); Doesnt work
//string args = string.Format("\"{0}\" - ", url);
string args = string.Format("\"{0}\" - ", "http://localhost:51005/XYZ/" + url); //Works
var startInfo = new ProcessStartInfo(Server.MapPath("bin\\wkhtmltopdf.exe"), args)
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var proc = new Process { StartInfo = startInfo };
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
byte[] buffer = proc.StandardOutput.CurrentEncoding.GetBytes(output);
proc.WaitForExit();
proc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=download.pdf");
Response.BinaryWrite(buffer);
Response.End();
}
catch (Exception ex)
{
throw ex;
}
}
Error Message in case file is on same domain
Server Error in '/' Application. The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make sure
that it is spelled correctly.
Requested URL: /PrintArticle.aspx
Version Information: Microsoft .NET Framework Version:4.0.30319;
ASP.NET Version:4.0.30319.272
I resolved this issue by using the following statement
var url = Request.Url.GetLeftPart(UriPartial.Authority) + "/PrintArticle.aspx?articleID=" + Request["articleID"] + "&download=yes&Language=" + Request["Language"];
Now it is working fine i am not sure what it doesn't work when i specify the file path.
output variable contains empty string
my code as follows:
try
{
string url=Request.Url.GetLeftPart(UriPartial.Authority) +"/PrintQuickPrescription.aspx?DoctorId=" + DoctorID + "&DispnID=" + DispnID + "&ApptID=" + ApptID + "&PatientID=" + PatientID;
System.Diagnostics.Process process = new System.Diagnostics.Process();
string args = string.Format("\"{0}\" - ", "http://localhost:50013/DPMNewWeb/"+url);
//string args="http://localhost:50013/DPMNewWeb/PrintQuickPrescription.aspx";
var startInfo = new ProcessStartInfo(Server.MapPath("~\\Bin\\wkhtmltopdf.exe"), args)
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true
};
var proc = new Process { StartInfo = startInfo };
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
byte[] buffer = proc.StandardOutput.CurrentEncoding.GetBytes(output);
proc.WaitForExit();
proc.Close();
Response.ContentType = "application/pdf";
Response.BinaryWrite(buffer);
Response.End();
//byte[] fileContent = GeneratePDFFile();
//GeneratePDFFile();
//if (fileContent != null)
//{
// Response.Clear();
// Response.ContentType = "application/pdf";
// Response.AddHeader("content-length", fileContent.Length.ToString());
// Response.BinaryWrite(fileContent);
// Response.End();
//}
}
catch
{
}

Getting Error when using response.write()

I need to save a file as .csv in client machine. I am using the code below.
protected void btnGen_Click(object sender, EventArgs e)
{
try
{
string fileName = "test";
string attachment = "attachment; filename=" + fileName + ".csv";
List<string> lst1 = new List<string> { "wert", "fds", "hjgfh", "hgfhg" };
List<string> lst2 = new List<string> { "hgfds", "hdfg", "yretg", "treter" };
List<string> lst3 = new List<string> { "hgfdgf", "gfdg", "gfdgf", "ghfdg" };
List<List<string>> lst = new List<List<string>> { lst1, lst2, lst3 };
StringBuilder sb = new ExportFacade().GenerateStringBuilder(lst);
Response.ContentType = "text/csv" ;
lblProgress.ForeColor = System.Drawing.Color.Green;
lblProgress.Text = "File created and write successfully!";
HttpContext.Current.Response.AddHeader("content-disposition", attachment);
Response.Write(sb.ToString());
lblProgress.ForeColor = System.Drawing.Color.Green;
lblProgress.Text = "File created and write successfully!";
Response.Flush();
Response.End();
}
catch (Exception ex)
{
lblProgress.ForeColor = System.Drawing.Color.Red;
lblProgress.Text = "File Saving Failed!";
}
}
I am not using update panels.
When I click on the button I get the following error
Sys.WebForms.PageRequestManagerParserErrorException: The message
received from the server could not be parsed. Common causes for this
error are when the response is modified by calls to Response.Write(),
response filters, HttpModules, or server trace is enabled.
It will be a great help to me if you can help me to get rid of this problem.
thank you.
I solved it. Ajax script manager in the master page has created the problem. After removing it, the function worked properly. But labels are not being updated as response is not for the page.

Streaming a zip file over http in .net with SharpZipLib

I'm making a simple download service so a user can download all his images from out site.
To do that i just zip everything to the http stream.
However it seems everything is stored in memory, and the data isn't sent til zip file is complete and the output closed.
I want the service to start sending at once, and not use too much memory.
public void ProcessRequest(HttpContext context)
{
List<string> fileNames = GetFileNames();
context.Response.ContentType = "application/x-zip-compressed";
context.Response.AppendHeader("content-disposition", "attachment; filename=files.zip");
context.Response.ContentEncoding = Encoding.Default;
context.Response.Charset = "";
byte[] buffer = new byte[1024 * 8];
using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipOutput = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(context.Response.OutputStream))
{
foreach (string fileName in fileNames)
{
ICSharpCode.SharpZipLib.Zip.ZipEntry zipEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(fileName);
zipOutput.PutNextEntry(zipEntry);
using (var fread = System.IO.File.OpenRead(fileName))
{
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fread, zipOutput, buffer);
}
}
zipOutput.Finish();
}
context.Response.Flush();
context.Response.End();
}
I can see the the worker process memory growing while it makes the file, and then releases the memory when its done sending. How do i do this without using too much memory?
Disable response buffering with context.Response.BufferOutput = false; and remove the Flush call from the end of your code.
use Response.BufferOutput = false; at start of ProcessRequest and flush response after each file.
FYI. This is working code to recursively add an entire tree of files, with streaming to browser:
string path = #"c:\files";
Response.Clear();
Response.ContentType = "application/zip";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", "hive.zip"));
Response.BufferOutput = false;
byte[] buffer = new byte[1024 * 1024];
using (ZipOutputStream zo = new ZipOutputStream(Response.OutputStream, 1024 * 1024)) {
zo.SetLevel(0);
DirectoryInfo di = new DirectoryInfo(path);
foreach (string file in Directory.GetFiles(di.FullName, "*.*", SearchOption.AllDirectories)) {
string folder = Path.GetDirectoryName(file);
if (folder.Length > di.FullName.Length) {
folder = folder.Substring(di.FullName.Length).Trim('\\') + #"\";
} else {
folder = string.Empty;
}
zo.PutNextEntry(new ZipEntry(folder + Path.GetFileName(file)));
using (FileStream fs = File.OpenRead(file)) {
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fs, zo, buffer);
}
zo.Flush();
Response.Flush();
}
zo.Finish();
}
Response.Flush();

Resources