FTP transfer via ASP.net page - c#

I'm rather new to development and I have a problem which I haven't sound a solution for. I can't seem to find if it is possible or not to solve, anyway..
I want to create an asp page which would allow a user to download a whole folder from an ftp server. The ftp server itself is not on the same physical server as the asp site. To further complicate the issue is that I want to use either explicit or implicit transfer which I can't seem to work in a browser.
The webpage acts as an intermediary between the client and the ftp server, and is meant to be as user friendly as possible. eg. the user just have to press download and it automatically downloads from the ftp server without the use of an installed local client.
client -> asp page -> ftp server
client <- ftp server
My problem is that the asp page does not have the permission to create files on the client system. I have managed to connect to the ftp and try to download all files in a folder but the files do not appear on the client in the target folder.
I might just be searching for the wrong terms but I would appreciate any feedback.

when you say "client" I assume you are referring to the asp.net server. In that case you need to check what user the app pool for your website is running under. Then you need to make sure that user has write permissions to the folder you are storing the ftp files in.
The user is most likely network service.

Your ASP site will not be able to write directly to the end user's system. Just think, would you want any website to have direct access to your file system?
You could download the files to a temporary folder on the Web Server, and then use write it in a response to prompt the user to download it.
Here is a SO question regarding downloading files in ASP.NET

From our question's comment discussion, looks like you are looking to provide user with a option to download file which you have collected on server side from ftp server
//Connect to your file
FileStream sourceFile = new FileStream(Server.MapPath(#"FileName"), FileMode.Open);
float FileSize= sourceFile.Length;
//Write the file content to a byte Array
byte[] getContent = new byte[(int)FileSize];
sourceFile.Read(getContent, 0, (int)sourceFile.Length);
sourceFile.Close();
//Build HTTP Response object
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Length", getContent.Length.ToString());
Response.AddHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.BinaryWrite(getContent);
Response.Flush();
Response.End();
Please see if the above code helps.
Also, check out HTTP Response file Attachment Discussion

Related

C# - Read local download path on file download

For a c# web application, we would like to create the possibility to download a file. If User 1 downloads file MyFileToDownload.txt, we would like to show the local saving directory on our website. For instance if he downloads MyFileToDownload.txt we want to show a message like: "File MyFileToDownload.txt is locked by User 1 in directory 'Downloads'".
So my question now: Is it possible to read the local saving location from a user? Or is the File anyway always saved in the directory Downloads on the most common operating systems such like "Windows and MacOs"
Our File download Code:
Response.ContentType = "text/html";
Response.AppendHeader("Content-Disposition", "attachment; filename=MyFileToDownload.txt");
Response.TransmitFile(#"C:\Users\Administrator\MyFileToDownload.txt");
Response.End();
The browser won't supply that information to you as it would represent a security risk to the user.
Whilst there are default download locations (on most recent version of Windows it's the Downloads folder in the user folder, for instance), all browsers allow users to choose another location should they wish to.

Get last modified date of a remote file

I have an app with which at startup it downloads a file from a remote location (through the net) and parses it's contents.
I am trying to speed up the process of startup as the bigger the file gets the slower the app starts.
As a way to speed up the process I thought of getting the last modified date of the file and if it is newer from the file on the user's pc then and only then download it.
I have found many ways to do it online but none of them are in C# (for windows store apps). Does anybody here know of a way of doing this without the need to download the file? If I am to download the file then the process is sped up at all.
My C# code for downloading the file currently is this
const string fileLocation = "link to dropbox";
var uri = new Uri(fileLocation);
var downloader = new BackgroundDownloader();
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("feedlist.txt",CreationCollisionOption.ReplaceExisting);
DownloadOperation download = downloader.CreateDownload(uri, file);
await download.StartAsync();
If it helps the file is stored in dropbox but if any of you guys have a suggestion for another free file hosting service I am open to suggestions
Generally, you can check the file time by sending HEAD request and parsing/looking HTTP header response for a Last-Modified filed. The remote server should support it and DropBox does not support this feature for direct links (only via API). But DropBox have another feature, the headers have the etag field. You should store it and check in the next request. If it changed - the file has been changed too. You can use this tool to check the remote file headers.

If I create a file in Codebehind where does the physical file acually exist?

protected void Page_Load(object sender, EventArgs e)
{
System.IO.File.WriteAllText(#"C:\CallInformation.txt", "Some data");
}
is CallInformation.txt on the Server? Or the client? If it's the server, other than specifying a computer name (#"\Workstation\c$\CallInformation.txt") how can I get it to save the file client side?
It is built on the server. It would be a major security vulnerability if you could create a file on a client without them physically accepting it. You could always send the data to them as a stream and allow them to choose where to save it.
It's on the server. The code behind executes in the context of the web server.
To get a file to download, there are a few ways. One way is to do something along these lines:
Response.ContentType = "image/jpeg";
Response.AppendHeader("Content-Disposition","attachment; filename=SailBig.jpg");
Response.TransmitFile( Server.MapPath("~/images/sailbig.jpg") );
Response.End();
If you are writing a web application, you should understand that the code runs on the server.
So the file is saved on the server.
To send it to the client, you have to write the contents of the file to the response stream.
The file would be create on the server. To write it locally, you would need a client framework other than just the W3C DOM compliant browser, such as Silverlight and (maybe) Flash - and even then the user would be prompted to allow it to happen.
Here's a post that explains how it can be done:
http://www.c-sharpcorner.com/uploadfile/dpatra/read-and-write-file-to-local-file-system-in-silverlight-4/
Hope it helps.

Creating download link to a file on a file server

I'm looking for a way to (easily, by preference ;)) create a download link to a file on a separate file server.
The situation is as follows: the application I'm developing (asp.net 2.0 in vb.net but I have a similar issue in c#, either solution works for me) will be run internally for a company.
As is good practice, the file storage and web application are on two separate servers.
I basically need to be able to create a download link to a file, the only available URL i have to access the file is \servername\folder1\folder2\folder3\file.txt (can be any sort of file)
Weblinks simply don't work. This is how it's currently set up:
tablerowfield.Text = String.Format(
"<a href=""\\servername\folder1\folder2\folder3\{0}""
target=""_blank"">Click me</a>",
filename)
Which doesn't work for obvious reasons. It used to be set up to write that file to the application path itself and that worked perfectly, but it isn't good practice and that's why I'm changing it (or trying to).
I read solutions about creating a download page and then having a table in your DB which holds the links and returns the proper web URL for download but the time constraint I am faced with unfortunately doesn't allow me to develop that.
Assuming I can provide a string with the full filepath to the file like the above, what is the easiest way to just create a link that, when clicked, downloads the document?
Note: I have 0 admin rights in this environment. That really isn't helping me. Let's assume I am given the correct link like above and have the appropriate file access rights and such.
UPDATE:
The above example does work in IE, but not in Firefox and Chrome. IE converts it to a file://servername/... link which does what it's supposed to, but FF and Chrome both actively decided that this is unsafe and have disabled it from their browsers.
You can use ASHX file (say, downloadfile.ashx) and use the following code (not tested, but it will be something like that) in it:
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=abc.txt");
Response.WriteFile(Server.MapPath("\\servername\folder1\folder2\folder3\abc.txt"));
Response.End();
and then use this in your anchor tag like:
Click me
Note: You can also pass parameters for downloading different files like:
Click me
and then, in ashx file, use the file name to download the appropriate file.
this piece of code will create a file in download folder with name=hi.txt and content as "thanks god, finally file got downloaded."
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=hi.txt");
Response.Write("thanks god, finally file got downloaded.");
Response.End();
If your file is already there on server then you can use this code in your download button click event like this
protected void downloadpdf_Click(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=""downloadName.pdf""");
Response.WriteFile(Server.MapPath(#"~/path of pdf/actualfile.pdf"));
Response.End();
}
\\servername\folder1\folder2\folder3\... is an UNC path which cannot be used from a browser. Because the file(s) are on a separate server, you need an href attribute of the form http://server-name/folder1/folder2/file.txt.
If the server-name is unresolvable by the clients, then you need to first get the IP address of the server and then formulate the href of the form: http://10.1.1.30/folder1/folder2/file.txt
Here is how you get the IP address from server-name:
IPAddress[] host;
host = Dns.GetHostAddresses("server-name");
string ip = host[0].ToString();
EDIT:
I basically need to be able to create a download link to a file
With the ashx solution your application would be reading the file from the server and relaying it to the clients rather than just providing the clients a link to download the file directly from the file server.

Upload and rename multiple files to FTP using asp.net

We are creating CMS, in which we want to have the option to upload multiple files to FTP server. The steps are
Open FTP connection
Click browse - Select multiple files - Click upload to FTP
Create a folder on the FTP server
Rename the selected files and upload them to the folder
Close the connection
It will be good if it shows the status of the upload.
We are using asp.net with C#. Any sample code will help. Is there any good components available. I can spend max of $150 to buy a component.
Please help. Thanks in advance.
First of all, you should use an open source CMS and improve the code to your needs, don't try to reinvent the wheel!
Second, there is no need to spend money, plenty of solutions out there ...
you can use, for example Uploadify to pass user files to your server, then using any FTP Example upload the files to the FTP and delete them from the server upon success.
if you don't want to have the "middle men", just upload directly to the FTP
string name = Path.GetFileName(UploadControl.FileName);
byte[] data = UploadControl.FileBytes;
using (WebClient client = new WebClient()) {
client.UploadData("ftp://my.ftp.server.com/myfolder/" + name, data);
}

Categories