Download file from SQL Server and save to fix folder using c# - c#

I developed a web application using C#, I upload file to SQL Server. I need to auto-download it to a folder.
Here is my code for that:
string sql = "select * from tblFiles where ID = " + ID ;
DataTable dt = dbs.MNTSQLSelect(sql);
if (dt.Rows.Count > 0)
{
Response.Clear();
Response.Buffer = true;
Response.ContentType = dt.Rows[0]["contentType"].ToString();
Response.AddHeader("content-disposition", "attachment;filename=" + dt.Rows[0]["fileName"].ToString());
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.BinaryWrite((byte[])dt.Rows[0]["filedata"]);
Response.End();
}

Unfortantly the download location as a genreal rule is controlled by the "end user" browser settings.
For up-loading, then you ONLY ever get just the file name, and information about the client side computer is "hands off". If you could set/pick/choose a file name, then while you come to my site to view a picture of a cute cat?
Then I could start rummanging around on your hard drive. Steal your emails, or how about files in a folder called "banking". or how aobut looking for a Excel sheet called passwords?
It turns out that while file up-loads don't allow ANY kind of path information, or even exposing path names to your web server?
You can try passing a path name + file name when sending a file to a client computer. But, then again, this might be an adroid phone, iPad, and as such, things like drive letters don't even exist!
So, I have found that I can supply a path name - Edge seems to accept the path name, but at the end of the day, it the end users browser settings that has and will control where a file location is downloaded to
(in most cases - it defaults to the folder called "downloads").
so, you really don't have much choice in this matter - the end user computer + browser settings will ultimately control the location of such downloads, and once again, if any old location could be set, then I might as well download some .exe program into your windows startup folder or whatever - and again that would be a security risk beyond anything that any user would allow or tolerate.
You can't mess around with my computer JUST because I decide to visit your site, and as noted, no end user would use a browser or the internet if this was possible.

Related

How to create a (cross browser compatible) hyperlink that opens a file on a network drive?

I want to open Documents from Shared Folder on network using ASP.NET with C#.
My situation as follow:
My Web Server Name is “WebServer1” use IIS 7
My DC Server Name is “DC1”
My File Server Name “FileServer1”
My Files Path
\\FileServer1\A\B\C\MyDoc.docx and \\FileServer1\A\B\C\MyPDF.pdf
I tried the following
1- I Created Hyper Link
link to file
The files open on some machines that uses Internet Explorer version 8 but on any other version or Chrome, Fire Fox, or any other web browser it doesn't work when I click on the hyper link no action happens and no errors, but if I copied the link address and pasted it into the web browser the file opens
I gave the path in the file server full control permission for “everyone”
2- I also tried to create a button with the following code
Response.ContentType =
"application/vnd.openxmlformats- officedocument.wordprocessingml.document";
Response.AppendHeader("Content-Disposition", "attachment; filename=5401-1-2289.docx");
Response.Redirect("file:///// FileServer1\A\B\C\MyDoc.docx");
Response.Flush();
First of all, the URL is incorrect. It should be #"file://\\FileServer1\A\B\C\MyDoc.docx" instead of "file:///// FileServer1\A\B\C\MyDoc.docx" (I have a hard time thinking this actually compiles, because you didn't escape \...)
Second, you are combining both sending content, as redirecting, as pointed out by Luaan in a comment. This won't work.
You could transmit the file directly. This also prevents you to expose your network drive to external users:
Response.TransmitFile(#"\\FileServer1\A\B\C\MyDoc.docx");

Need to create Excel file and save in local path. in C# MVC

I Have this Code...but it ask for save file or open file option in one dialog box.
string attachment = "attachment; filename=XYZ.xls";
Response.ClearContent();
Response.ContentType = "application/ms-excel";
Response.AddHeader("Content-disposition", attachment);
.....
.....
i want to generate excel dynamic using my code and save in local folder in my drive.
What you are trying to do is not allowed, for good reasons. First of all when you try to save a file from a web application on someone else's computer you have no idea whether the folder in which you try to save the file exists and whether the user has access to this folder. Also the webapplication does not know if the computer that is being used is a Windows computer, Mac, Linux or maybe a telephone, for which all filesystems work different. Second, and more importantly, it is a huge risk if a website was able to save a file to any folder, for example your start-up folder. A malicious website would be able to install viruses/keylogger/etc. on your computer without you knowing it.
So if you want to save an Excel file to a specific folder you must make a console application or a Windows application.

Could not find a part of the path error on file download

I've taken on an asp/c# web app to fix originally done by the previous developer at my workplace. The code shows a Gridview populated by results from a query showing a list of files, one column is made up of 'command fields' that when clicked download a file. Everything seems to go smoothly until it reaches the file download as it can't seem to find the file on the server. My C# really isn't strong so bear with me and if you need further info that I've missed out please do say so.
Here is the specific part of code that causes problems:
//strSuppDocName - is already declared elsewhere
string path = System.IO.Path.Combine(Server.MapPath("~/Documents/"), strSuppDocName);
if (!Directory.Exists(path)){
System.Windows.Forms.MessageBox.Show(path + " - file path doesn't exist");
}
else {
System.Net.WebClient client = new System.Net.WebClient();
Byte[] buffer = client.DownloadData(path);
if (buffer != null)
{
Response.ClearContent();
Response.ClearHeaders();
FileInfo file = new FileInfo(path);
Response.Clear();
Response.AddHeader("Content-Disposition", "Attachment;FileName:" + file.Name);
Response.AddHeader("Content-Length", file.Length.ToString());
Response.ContentType = ReturnExtension(strExtSuppDoc.ToLower());
Response.WriteFile(file.FullName);
Response.End();
}
}
What happens when I run the code is that the grid view populates okay, I click the file to download and it enters the first branch of the if statement showing the path. Before I added in the if statement it was showing the following error: "could not find a part of the path". I've tried fiddling with the path such as setting it absolutely:
string path = System.IO.Path.Combine(#"E:\web\Attestation\Documents\", strSuppDocName);
And without using the Combine method above and using standard string concatenation with '+'. Any help or guidance is most appreciated, thanks!
You're mixing a handful of technologies here. First of all, this doesn't belong in a web application:
System.Windows.Forms.MessageBox.Show(path + " - file path doesn't exist");
Web applications aren't Windows Forms applications. This won't display anything to someone using the web application, because there's no concept of a "message box" over HTTP.
More to the point, however, you're using path in two very different ways. Here:
Byte[] buffer = client.DownloadData(path);
and here:
FileInfo file = new FileInfo(path);
Is path a URL on the network or a file on the file system? It can't be both. The first line is treating it as a URL, trying to download it from a web server. The second line is treating it as a local file, trying to read it from the file system.
What is path and how are you looking to access it? If it's a URL, download it with the WebClient and stream it to the user. If it's a file, read it from the file system and stream it to the user. You can't do both at the same time.
If you are interacting with a path on a network (aka UNC path), you have to use Server.MapPath to turn a UNC path or virtual path into a physical path that .NET can understand. So anytime you're opening files, creating, updating and deleting files, opening directories and deleting directories on a network path, use Server.MapPath.
Example:
System.IO.Directory.CreateDirectory(Server.MapPath("\\server\path"));
The answer in short is that the file name was incorrect.
Strangely or mistakenly the author of the code, when uploading a given file, added an extra extension so a file would be something like 'image.png' to start off with then when uploaded would become image.png.png. Why didn't I notice this before you may ask? Simply because the whole path wasn't shown in Windows XP (don't ask why I was using XP) when viewing it through the explorer window and I dismissed this issue long before - a big mistake! After trying to find the file by typing the address of the file into the windows explorer address bar and receiving an error that the file doesn't exist, yet I could plainly see it did, a colleague looked at for the file remotely using Windows 7 and we saw that the file was shown as 'image.png.png'. Thereafter the path to the file worked correctly.

asp.net folder access

I'm trying to read a file that's just been uploaded to the server, in a newly created folder (folder name is the session id)
Exception Details: System.UnauthorizedAccessException: Access to the
path '...\UploadFiles\jeiqw1qxya33e3r00idwlceo' is denied.
I'm not sure what user to give access to, looking on the net it says to add the identity that the Application Pool runs under, which for me looks to me ApplicationPoolIdentity... but I can't find this user to add to the folder permissions. So I added "everyone" and gave full control... just to experiment mind, and I still get the error above.
This is related to my last question here...
StreamReader with tab delimited text file
using the 'File.ReadAllLines()' method, this is the line that has the exception.
It is not practical to give read access to a folder created dynamically - as you said folder name is session id.
However, you can stream the file back to a user like this.
HttpResponse response = HttpContext.Current.Response;
response.Clear();
response.Charset = "utf-8";
response.ContentType = "text/xls";
response.AddHeader("content-disposition",
string.Format("attachment; filename={0}", fileName));
response.BinaryWrite(File.ReadAllBytes(filePath));
response.End();
If you're running IIS 7.5 or higher the user which your app pool runs with is usually "IIS APPPool{POOL NAME}" where {POOL NAME} is the name of the pool/site.
If you're using IIS 7 with application pool identity I think it's still 'NETWORK SERVICE' that your site runs with.
Btw you can directly see the user that yoru apppool(w3wp.exe) is running in a tool like task manager/process explorer.
Another way to find out which specific account the application is running under is in code: System.Security.Principal.WindowsIdentity.GetCurrent().Name
But if you have given that account, or everyone, full control and you are still getting access denied errors, is it possible that the newly uploaded file is locked? Are you saving the uploaded file to a location that's inside a virtual directory? Sometimes IIS can temporarily lock a file if it's saved to a browsable location. Virus scanners can also sometimes cause file locking.
I'd like to thank everyone for their responses.
When I looked at the code this morning with fresh eyes, I noticed a mistake in my code...
I had...
var records = File.ReadAllLines(Server.MapPath("~/UploadFiles/") + Session.SessionID).ToList();
which points to the folder, and not a target file.
I changed to...
var records = File.ReadAllLines(Server.MapPath("~/UploadFiles/") + Session.SessionID + "/ediFile.txt").ToList();
This now works! It's no wonder this confused me as the permission set up is correct after all! :)

download file to a specific location with Response.BinaryWrite and Server.Mappath possible?

I have varbinary data associated with a file in the DB. This is the code I'm using to download this file on clicking a link -
//a is my attachment object
var r = context.Response;
r.AddHeader("Content-Disposition", "attachment; filename=" + a.FileName);
r.Charset = "";
r.ContentType = a.MIME;
r.BinaryWrite(a.Content.ToArray());
Currently, this file gets downloaded to the Downloads folder. Is there any way to create a new folder in the users system and have this file download there? I read that server.mappath can be used with r.WriteFile, but I'm not quite sure. Can this be done?
No, this is not possible. Otherwise, people could maliciously write all manner of files into specific system directories. Once you send the file down to the user, the control is now out of your hands.

Categories

Resources