Stop file to be downloaded from direct link - asp.net

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.

Related

How to store image in solution using ASP.NET?

I have an upload image function that uploads images to the server but I am only able to add images into the server until the session ends. Once the session ends , I noticed that the images uploaded are not stored into my local solution and after some research I found out that we could make uploaded files be stored into our solution even when the session ends but I am unsure of how to implement it. I am very new to this and would appreciate all help given.
For now this is the code I have that allows me to upload my image:
protected void btnConfirm_Click(object sender, EventArgs e)
{
string uploadedPhoto = "";
if (uploadImage.HasFile)
{
string savePath;
//Find the filename extension of the file to be uploaded.
string fileExt = Path.GetExtension(uploadImage.FileName);
//rename the uploaded file with name
uploadedPhoto = txtName.Text + fileExt;
savePath = MapPath("~/Images/profile pictures/" + uploadedPhoto);
try
{
uploadImage.SaveAs(savePath);
lblMsg.Text = "Image uploaded!";
imgprw.ImageUrl = "~/Images/profile pictures/" + uploadedPhoto;
}
catch (IOException)
{
lblMsg.Text = "Image upload failed!";
}
catch (Exception ex)
{
lblMsg.Text = ex.Message;
}
}
}
I see your code is right because I used same way to upload and store image into folder like you.
string path = Server.MapPath("~/Photos/" + f.FileName);
f.SaveAs(path);
May I see your full code ?

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

"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 :)

Upload and Delete file by using File Upload Control asp.net

I am developing a complaint form. In this this form, I must make a function that uploads a file and then delete the file that was uploaded. I can upload a file to the server, but I can't take a link of the file I upload to the server in order to delete it. Please help me. Here is my code:
public string FilePath;
protected void btAdd_Click(object sender, EventArgs e)
{
if (AttachFile.HasFile)
{
try
{
string[] sizes = {"B", "KB", "MB", "GB"};
double sizeinbytes = AttachFile.FileBytes.Length;
string filename = Path.GetFileNameWithoutExtension(AttachFile.FileName);
string fileextension = Path.GetExtension(AttachFile.FileName);
int order = 0;
while (sizeinbytes >= 1024 && order + 1 < sizes.Length)
{
order++;
sizeinbytes = sizeinbytes/1024;
}
string result = String.Format("{0:0.##} {1}", sizeinbytes, sizes[order]);
string encryptionFileName = EncrytionString(10);
FilePath = "Path" + encryptionFileName.Trim() + AttachFile.FileName.Trim();
AttachFile.SaveAs(FilePath);
}
catch (Exception ex)
{
lbMessage.Visible = true;
lbMessage.Text = ex.Message;
}
}
}
protected void btDelete_Click(object sender, EventArgs e)
{
try
{
File file = new FileInfo(FilePath);
if (file.Exists)
{
File.Delete(FilePath);
}
}
catch (FileNotFoundException fe)
{
lbMessage.Text = fe.Message;
}
catch (Exception ex)
{
lbMessage.Text = ex.Message;
}
}
Each request in asp.net creates a new object of your Page.
If you set variables during one request, they will not be available on the next request.
Your delete logic seems to depend upon FilePath being set during upload. If you want the page to remember that, keep it in the ViewState. The ViewState is maintained across requests to the same page and that would allow you to use the variable FilePath during delete.
This can be easily achieved by making FilePath a property and getting it from the ViewState.
public string FilePath
{
get
{
return (string) ViewState["FilePath"];
}
set
{
ViewState["FilePath"] = value;
}
}
YOU SHOULD DO IT IN THIS WAY.
if (imgUpload.HasFile)
{
String strFileName = imgUpload.PostedFile.FileName;
imgUpload.PostedFile.SaveAs(Server.MapPath("\\DesktopModules\\Indies\\FormPost\\img\\") + strFileName);
SqlCommand cmd01 = new SqlCommand("insert into img (FeaturedImg) Values (#img)", cn01);
cmd01.Parameters.AddWithValue("#img", ("\\DesktopModules\\Indies\\FormPost\\img\\") + strFileName);
}
With this code you can upload file in a particular location in your sites root directory.
and the path will be stored in database as string.
so you can access the file just by using the path stored in database.
If you cant understand anything. or wanna know more u can contact me or ask me here in comments.

how to create a hyperlink for file download in asp.net?

I have some files stored on my machine. When a user wants to generate a link the page should generate a hyperlink. This hyperlink can be used by any other user so as to download the file
Have a LinkButton and for the click event do the following
your aspx file will have the following
<asp:LinkButton runat="server" OnClick="btnDownload_Click" Text="Download"/>
Your code behind will have the following
protected void btnDownload_Click(object sender, EventArgs e)
{
try
{
var fileInBytes = Encoding.UTF8.GetBytes("Your file text");
using (var stream = new MemoryStream(fileInBytes))
{
long dataLengthToRead = stream.Length;
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.BufferOutput = true;
Response.ContentType = "text/xml"; /// if it is text or xml
Response.AddHeader("Content-Disposition", "attachment; filename=" + "yourfilename");
Response.AddHeader("Content-Length", dataLengthToRead.ToString());
stream.WriteTo(Response.OutputStream);
Response.Flush();
Response.Close();
}
Response.End();
}
}
catch (Exception)
{
}
}
you can direct link the hyperlink with the file if you know the address but this is limited by the browser. eg. if pdf reader is installed on the client then the pdf will not be downloaded instead it will be shown. A good solution would be to have a seperate page for downloading files. just pass filename in querystring and in the pageload event just outpit the file in response stream.This way you can use url say dwnld.aspx?filename.ext
Now you can generate urls via the above logic.

Resources