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

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();
}

Related

Stop file to be downloaded from direct link

I have this class in an asp web form and I am trying to allow the download from users only if they have the password and the link to the file that is sent to them.
protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
//Get the filename from the link and the password entered by the user
string savefilename = Request.QueryString["file"];
string password = txtPassword.Text.Trim();
//Make sure that the password maches for the requested file
if (BLCustomerFile.IsUserAuthenticated(savefilename, password))
{
//Check if the file still exists on the server
string filename = savefilename.Substring(32);
string fileserverpath = Server.MapPath("~/uploads/" + savefilename);
if (File.Exists(fileserverpath))
{
//Response back with the file -- file download
FileInfo fileInfo = new FileInfo(fileserverpath);
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename);
Response.AppendHeader("Content-Length", fileInfo.Length.ToString());
Response.WriteFile(fileInfo.FullName);
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
{
lblMessage.Text = "File No longer exists on the server.";
}
}
else
{
lblMessage.Text = "You are not authorized to download this file.";
}
}
catch (Exception ex)
{
lblMessage.Text = "Some error occurred. Please try again later.";
}
}
The problem: The link I give to the user is url+filename+extension, when it is pasted in the browser the file get downloaded immediately. Is there a way to stop this to happen and to force the above code to execute and therefore to check the password?
I know I can change the logic of the system but if there is a solution I would leave it in this way to avoid to have to give to the customer url, file name and password separately.

"server cannot append header after http headers have been sent"

i have application like email messaging system. here i adjust one solution to download all file that are in table from particular post.
this is my code:
protected void lbu_download_all_Click(object sender, EventArgs e)
{
if (rpt_file_list.Items.Count > 0)
{
using (DataClassesDataContext db = new DataClassesDataContext())
{
var query = from f in db.Files
where f.Post_History_id == int.Parse(post_id.Value.ToString())
select new
{
FileName = f.File_name,
File_ext= f.File_ext
};
foreach (var item in query)
{
System.IO.FileInfo objFile = new FileInfo(Server.MapPath("~/PostFiles/" + item.FileName.ToString() + item.File_ext.ToString()));
if (objFile.Exists)
{
Response.Clear();
string strFileName = item.FileName.ToString() + item.File_ext.ToString();
Response.AddHeader("Content-Disposition", "attachment; filename=" + strFileName);
Response.AddHeader("Content-Length", objFile.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(objFile.FullName);
Response.BufferOutput = true;
Response.Flush();
}
}
}
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("<script type = 'text/javascript'>");
sb.Append(" No files found to download');");
sb.Append("</script>");
ClientScript.RegisterStartupScript(this.GetType(), "script", sb.ToString());
}
}
i don't know what is problm please help me..
You won't be able to download multiple files like that, I imagine what is happening is that the loop goes through once and on the second iteration it then throws the exception.
What you really should be doing is zipping all the files into one file to download, this question should give you an idea of what I mean.
By zipping the file you'll also get the benefit of compression (less bandwidth, faster transfer) and the user (in your current scenario) won't be presented with multiple 'Save As' dialog windows (much more professional!).
This link may also help you with some other potential ideas (like having a 'Download' page with URL parameters to identify the file). I'm more a fan of a zipped single file option though!
Do you have Response.BufferOutput = true; set properly? If not, the page will be sent as it is generated, which means the Response.Clear() won't do what you want :)

Download all types of files from server using ASP.NET

I have a file in server .
I want download this file .
I use this code
try
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.BufferOutput = true;
if (File.Exists(Server.MapPath("~/Upload/" + file)))
{
Response.AddHeader("Content-Disposition", "attachment; filename=" + file);
Response.ContentType = "application/octet-stream";
Response.WriteFile(("~/Upload/" + file));
Response.End();
HttpContext.Current.ApplicationInstance.CompleteRequest();
}
else
{
if (Request.UrlReferrer != null)
{
Type csType = GetType();
string jsScript = "alert('File Not Found');";
ScriptManager.RegisterClientScriptBlock(Page, csType, "popup", jsScript, true);
}
}
}
catch (Exception ex)
{
string errorMsg = ex.Message;
ScriptManager.RegisterClientScriptBlock(Page, GetType(), "popup", errorMsg, true);
}
But when i use this, I get error
Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
in code
Response.End();
How to download all types of files?
Is this Web Forms, MVC, or a custom IHttpHandler?
In any event, you don't need to call Response.End() or HttpContext.Current.ApplicationInstance.CompleteRequest(), just return from your function and ensure nothing else is written to the response.
Have you tried :
Response.TransmitFile(Server.MapPath("~/Upload/" + file));
instead of :
Response.WriteFile(("~/Upload/" + file));
You should also remove the BufferOutput (bad idea with Response.End() without Response.Flush())

Problem downloading a 25MB file - the 8MB file downloads without problem (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).

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