C# send file to ftp with user and port - c#

How can I send a file to an ftp with C# ?
The only informations I have are :
FTP IP address
FTP port
FTP user
I've try this :
public void SendFile(string filePath)
{
String user = "UserID";
String IPAddr = "XXX.XXX.XXX.XXX";
int port = 9999;
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(user, null);
Uri address = new Uri("ftp://" + IPAddr);
byte[] rawResponse = client.UploadFile(address, "STOR", filePath);
string response = System.Text.Encoding.ASCII.GetString(rawResponse);
// check response
}
}
But it doesn't work and it doesn't use the port (Error "unable to connect").

You can specify port in the address if you use an FtpWebRequest this is what i use and it works with specific port.
internal class FTPManager
{
private const string FTPAddress = "ftp://www.example.com:9211/";
private const string Username = "Yummy";
private const string Password = "Nachos";
public byte[] DownloadFile(string relativePath)
{
var fileData = new byte[0];
try
{
// parse the path
relativePath = ParseRelativePath(relativePath);
using (var request = new WebClient())
{
request.Credentials = new NetworkCredential(Username, Password);
fileData = request.DownloadData(FTPAddress + relativePath);
}
}
catch { }
return fileData;
}
public bool DoesFileExist(string relativePath)
{
var fileExist = false;
var request = WebRequest.Create(FTPAddress + ParseRelativePath(relativePath));
request.Method = WebRequestMethods.Ftp.GetFileSize;
request.Credentials = new NetworkCredential(Username, Password);
try
{
using (var response = request.GetResponse())
{
fileExist = true;
}
}
catch { }
return fileExist;
}
// upload file and handle everything
public void UploadFile(string relativePath, byte[] fileBinary)
{
// parse the path
relativePath = ParseRelativePath(relativePath);
// create the folder before writing the file
CreateFolders(relativePath);
// delete the file
DeleteFile(relativePath);
// upload the file
SendFile(relativePath, fileBinary);
}
private void SendFile(string relativePath, byte[] fileBinary)
{
try
{
var request = (FtpWebRequest)WebRequest.Create(FTPAddress + relativePath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(Username, Password);
var stream = request.GetRequestStream();
var sourceStream = new MemoryStream(fileBinary);
var length = 1024;
var buffer = new byte[length];
var bytesRead = 0;
do
{
bytesRead = sourceStream.Read(buffer, 0, length);
stream.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
sourceStream.Close();
stream.Close();
}
catch
{
}
}
private void DeleteFile(string relativePath)
{
try
{
WebRequest ftpRequest = WebRequest.Create(FTPAddress + relativePath);
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
ftpRequest.Credentials = new NetworkCredential(Username, Password);
ftpRequest.GetResponse();
}
catch { }
}
// parse the relative path for strange slashes
private string ParseRelativePath(string relativePath)
{
// split to remove all slashes and duplicates
var split = relativePath.Split(new string[] { "\\", "/" }, StringSplitOptions.RemoveEmptyEntries);
// join the string back with valid slash
var result = String.Join("/", split);
return result;
}
// Check if the relative path need folders to be created
private void CreateFolders(string relativePath)
{
if (relativePath.IndexOf("/") > 0)
{
var folders = relativePath.Split(new[] { "/" }, StringSplitOptions.None).ToList();
var folderToCreate = FTPAddress.Substring(0, FTPAddress.Length - 1);
for (int i = 0; i < folders.Count - 1; i++)
{
folderToCreate += ("/" + folders[i]);
CreateFolder(folderToCreate);
}
}
}
// create a single folder on the FTP
private void CreateFolder(string folderPath)
{
try
{
WebRequest ftpRequest = WebRequest.Create(folderPath);
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
ftpRequest.Credentials = new NetworkCredential(Username, Password);
ftpRequest.GetResponse();
}
catch { } // create folder will fail if it already exist
}
}

My problem was undefined port. To set the port, just do :
Uri address = new Uri($"ftp://{IPAddr}:{port}");
byte[] rawResponse = client.UploadFile(address, "STOR", filePath);

Related

Uploading files to FTP server works on localhost, but not when deployed

I've been spending all day trying to figure this one out, but with no luck.
Basically I have a bunch of files and folders, that I want to upload to a FTP server, and everything works great on localhost. But when I deploy it to azure, it stops working. In my head it makes no sense, and my initial thought was it had to do with a firewall, upload timeout or something else.
Do you see anything I am missing in my code, or do I need to do some configuration on azure or my ftp server ?
Edit: I forgot to include the error message:
"The underlying connection was closed: An unexpected error occurred on a receive
Problem Id:System.Net.WebException at simplecms.Models.FtpConn.UploadFile"
public class FtpConn
{
public string UploadCms(string address, string username, string password, string host, bool userftp, string guid)
{
CreateFileUID(guid);
string location;
if (userftp)
{
location = address + "/simplecms/";
host = host + "/simplecms/";
}
else
{
location = address + "/simplecms" + guid + "/";
host = host + "/simplecms" + guid + "/";
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(location);
request.Credentials = new NetworkCredential(username, password);
//request.Timeout = -1;
request.UsePassive = true;
request.UseBinary = true;
request.Timeout = 1000000000;
request.KeepAlive = false;
request.ReadWriteTimeout = 1000000000;
request.Method = WebRequestMethods.Ftp.MakeDirectory;
using (var resp = (FtpWebResponse)request.GetResponse())
{
Console.WriteLine(resp.StatusCode);
}
string cmsFolder = "wwwroot/dist/";
string[] cmsFiles = Directory.GetFiles(cmsFolder);
foreach (string file in cmsFiles)
{
string path = Path.GetFullPath(file);
string name = Path.GetFileName(file);
UploadFile(username, password, location, path, name);
}
string[] staticFiles = Directory.GetDirectories(cmsFolder);
string[] subs = Directory.GetDirectories(cmsFolder + "static/");
foreach (string file in staticFiles)
{
CreateDirectory(username, password, location + "/" + Path.GetFileName(file));
}
foreach (string folder in subs)
{
CreateDirectory(username, password, location + "/static/" + Path.GetFileName(folder));
foreach (string subfile in Directory.GetFiles(folder))
{
string path = Path.GetFullPath(subfile);
string name = Path.GetFileName(subfile);
UploadFile(username, password, location + "/static/" + Path.GetFileName(folder) + "/" + Path.GetFileName(subfile), path, "");
}
}
return host;
}
private void UploadFile(string username, string password, string location, string filePath, string fileName)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(location + fileName);
request.Credentials = new NetworkCredential(username, password);
//request.Timeout = -1;
request.UsePassive = true;
request.UseBinary = true;
request.Timeout = 1000000000;
request.KeepAlive = false;
request.ReadWriteTimeout = 1000000000;
request.Method = WebRequestMethods.Ftp.UploadFile;
FileStream stream = File.OpenRead(filePath);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
Stream reqStream = request.GetRequestStream();
reqStream.Write(buffer, 0, buffer.Length);
reqStream.Close();
}
private void CreateDirectory(string username, string password, string newDirectory)
{
try
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(newDirectory);
ftpRequest.Credentials = new NetworkCredential(username, password);
//ftpRequest.Timeout = -1;
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = false;
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex); }
return;
}
private void CreateFileUID(string uid)
{
string folderName = "wwwroot/dist/";
string[] txtList = Directory.GetFiles(folderName, "*.txt");
foreach (string f in txtList)
{
File.Delete(f);
}
string fileName = "uid.txt";
string pathString = Path.Combine(folderName, fileName);
using (FileStream fs = File.Create(pathString))
{
byte[] SimpleCmsUID = new UTF8Encoding(true).GetBytes(uid);
fs.Write(SimpleCmsUID, 0, SimpleCmsUID.Length);
}
}
}

How to download ftp server folders and files in windows application c#

In my application, I have a FTP server containing some folders and those folders contain number of files and some are empty folders. I need to download all the folders as well as files into my local folder. How can I download them to my local folder?
I used the code below and got an exception:
public void DownloadFtpDirectory(string url, NetworkCredential credentials, string localPath)
{
FtpWebRequest listRequest = (FtpWebRequest)WebRequest.Create(url);
listRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
listRequest.Credentials = credentials;
List<string> lines = new List<string>();
using (FtpWebResponse listResponse = (FtpWebResponse)listRequest.GetResponse())
using (Stream listStream = listResponse.GetResponseStream())
using (StreamReader listReader = new StreamReader(listStream))
{
while (!listReader.EndOfStream)
{
lines.Add(listReader.ReadLine());
}
}
foreach (string line in lines)
{
string[] tokens =
line.Split(new[] { ' ' }, 9, StringSplitOptions.RemoveEmptyEntries);
string name = tokens[8];
string permissions = tokens[0];
string localFilePath = Path.Combine(localPath, name);
string fileUrl = url + name;
if (permissions[0] == 'c')
{
if (!Directory.Exists(localFilePath))
{
Directory.CreateDirectory(localFilePath);
}
DownloadFtpDirectory(fileUrl + "/", credentials, localFilePath);
}
else
{
FtpWebRequest downloadRequest = (FtpWebRequest)WebRequest.Create(fileUrl);
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
downloadRequest.Credentials = credentials;
using (FtpWebResponse downloadResponse = (FtpWebResponse)downloadRequest.GetResponse())
using (Stream sourceStream = downloadResponse.GetResponseStream())
using (Stream targetStream = File.Create(localFilePath))
{
byte[] buffer = new byte[10240];
int read;
while ((read = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
{
targetStream.Write(buffer, 0, read);
}
}
}
}
}
Exception

File Upload to Ftp Server From Local System

The Below is my program in c# to connect to Ftp Server.While Uploading the .txt file from local system to ftp server i am getting the error "The remote server returned an error: (404) Not Found". Please help me on this so that I can resolve my error.
The below is the free ftp server what i am using to up-load the file with username and password
Location: http://demo.wftpserver.com/
Username: demo-user
Password: demo-user
public static void Main(string[] args)
{
Ftp testConnec = new Ftp();
testConnec.CheckFTPConnection("http://demo.wftpserver.com/");
testConnec.uploadFileToFTP(#"C:\TestFtpConnection", "test_new.txt", "upload", "http://demo.wftpserver.com");
}
public class Ftp
{
#region checkFTPConnection
public bool CheckFTPConnection(string URL)
{
// Uri myUri = new Uri("http://demo.wftpserver.com/");
Uri myUri = new Uri(URL);
// WebRequest myRequest = WebRequest.Create(myUri);
//FtpWebRequest myRequest = (FtpWebRequest)WebRequest.Create(myUri);
WebRequest myRequest = WebRequest.Create(myUri);
myRequest.Credentials = new NetworkCredential("demo-admin", "demo-admin");
myRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp;
try
{
WebResponse myResponse = myRequest.GetResponse();
long i = myResponse.ContentLength;
return true;
myResponse.Close();
}
// catch (Exception ex)
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
return true;
}
else
{
return false;
}
}
}
#endregion
public bool uploadFileToFTP(string LocalFilePath, string FileName, string Directory,string URL)
{
try
{
Uri myUri = new Uri(URL);
WebRequest myRequest = WebRequest.Create(myUri);
WebRequest ftpClient = WebRequest.Create(myUri + Directory + "/" + FileName);
ftpClient.Credentials = new NetworkCredential("demo-admin", "demo-admin");
ftpClient.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
System.IO.FileInfo fi = new System.IO.FileInfo(LocalFilePath + "/" + FileName);
ftpClient.ContentLength = fi.Length;
byte[] buffer = new byte[4097];
int bytes = 0;
int total_bytes = (int)fi.Length;
System.IO.FileStream fs = fi.OpenRead();
System.IO.Stream rs = ftpClient.GetRequestStream();
while (total_bytes > 0)
{
bytes = fs.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
//fs.Flush();
fs.Close();
rs.Close();
WebResponse uploadResponse = ftpClient.GetResponse();
// string value = uploadResponse.StatusDescription;
uploadResponse.Close();
return true;
}
catch (Exception ex)
{
return false;
}
}

How to Download file from one FTP and then Upload file to different FTP?

I am trying to download a file from one FTP server, and then upload it to a different FTP. I only figured out how to upload local files and download XML via FTP so far.
Here is my method to upload local file to FTP:
private void UploadLocalFile(string sourceFileLocation, string targetFileName)
{
try
{
string ftpServerIP = "ftp://testing.com/ContentManagementSystem/"+ Company +"/Prod";
string ftpUserID = Username;
string ftpPassword = Password;
string filename = "ftp://" + ftpServerIP + "/" + targetFileName;
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
ftpReq.UseBinary = true;
ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
ftpReq.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
ftpReq.Proxy = null;
byte[] b = File.ReadAllBytes(sourceFileLocation);
ftpReq.ContentLength = b.Length;
using (Stream s = ftpReq.GetRequestStream())
{
s.Write(b, 0, b.Length);
}
}
catch (WebException ex)
{
String status = ((FtpWebResponse)ex.Response).StatusDescription;
Console.WriteLine(status);
}
}
And here is my method for downloading XML from FTP:
private static XmlDocument DownloadFtpXml(string uri, int retryLimit)
{
var returnDocument = new XmlDocument();
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(uri);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(Username, Password);
request.UsePassive = true;
request.Proxy = new WebProxy();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
using (Stream responseStream = response.GetResponseStream())
{
returnDocument.Load(responseStream);
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
FtpWebResponse response = (FtpWebResponse)ex.Response;
if (response.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
{
}
}
}
return returnDocument;
}
I'm unsure exactly how to do it, but I'm trying to create a method that will download something (content will be a video or image) from one FTP and then turn around and upload what I've just downloaded (that I'll have held in memory) to a different FTP.
Please help!
You were so close! Use a stream to convert your download into a byte array for upload.
I recently made a program to do just this! This will currently copy all files from one FTP directory to another so long as there is not a file in the target directory with the same name. It would be easy to change if you only wanted to copy one file, just use the copyFile, toByteArray and upload functions:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
namespace Copy_From_FTP
{
class Program
{
public static void Main(string[] args)
{
List<FileName> sourceFileList = new List<FileName>();
List<FileName> targetFileList = new List<FileName>();
//string targetURI = ftp://www.target.com
//string targetUser = userName
//string targetPass = passWord
//string sourceURI = ftp://www.source.com
//string sourceUser = userName
//string sourcePass = passWord
getFileLists(sourceURI, sourceUser, sourcePass, sourceFileList, targetURI, targetUser, targetPass, targetFileList);
Console.WriteLine(sourceFileList.Count + " files found!");
CheckLists(sourceFileList, targetFileList);
targetFileList.Sort();
Console.WriteLine(sourceFileList.Count + " unique files on sourceURI"+Environment.NewLine+"Attempting to move them.");
foreach(var file in sourceFileList)
{
try
{
CopyFile(file.fName, sourceURI, sourceUser, sourcePass, targetURI, targetUser, targetPass);
}
catch
{
Console.WriteLine("There was move error with : "+file.fName);
}
}
}
public class FileName : IComparable<FileName>
{
public string fName { get; set; }
public int CompareTo(FileName other)
{
return fName.CompareTo(other.fName);
}
}
public static void CheckLists(List<FileName> sourceFileList, List<FileName> targetFileList)
{
for (int i = 0; i < sourceFileList.Count;i++ )
{
if (targetFileList.BinarySearch(sourceFileList[i]) > 0)
{
sourceFileList.RemoveAt(i);
i--;
}
}
}
public static void getFileLists(string sourceURI, string sourceUser, string sourcePass, List<FileName> sourceFileList,string targetURI, string targetUser, string targetPass, List<FileName> targetFileList)
{
string line = "";
/////////Source FileList
FtpWebRequest sourceRequest;
sourceRequest = (FtpWebRequest)WebRequest.Create(sourceURI);
sourceRequest.Credentials = new NetworkCredential(sourceUser, sourcePass);
sourceRequest.Method = WebRequestMethods.Ftp.ListDirectory;
sourceRequest.UseBinary = true;
sourceRequest.KeepAlive = false;
sourceRequest.Timeout = -1;
sourceRequest.UsePassive = true;
FtpWebResponse sourceRespone = (FtpWebResponse)sourceRequest.GetResponse();
//Creates a list(fileList) of the file names
using (Stream responseStream = sourceRespone.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
line = reader.ReadLine();
while (line != null)
{
var fileName = new FileName
{
fName = line
};
sourceFileList.Add(fileName);
line = reader.ReadLine();
}
}
}
/////////////Target FileList
FtpWebRequest targetRequest;
targetRequest = (FtpWebRequest)WebRequest.Create(targetURI);
targetRequest.Credentials = new NetworkCredential(targetUser, targetPass);
targetRequest.Method = WebRequestMethods.Ftp.ListDirectory;
targetRequest.UseBinary = true;
targetRequest.KeepAlive = false;
targetRequest.Timeout = -1;
targetRequest.UsePassive = true;
FtpWebResponse targetResponse = (FtpWebResponse)targetRequest.GetResponse();
//Creates a list(fileList) of the file names
using (Stream responseStream = targetResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(responseStream))
{
line = reader.ReadLine();
while (line != null)
{
var fileName = new FileName
{
fName = line
};
targetFileList.Add(fileName);
line = reader.ReadLine();
}
}
}
}
public static void CopyFile(string fileName, string sourceURI, string sourceUser, string sourcePass,string targetURI, string targetUser, string targetPass )
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sourceURI + fileName);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(sourceUser, sourcePass);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
Upload(fileName, ToByteArray(responseStream),targetURI,targetUser, targetPass);
responseStream.Close();
}
catch
{
Console.WriteLine("There was an error with :" + fileName);
}
}
public static Byte[] ToByteArray(Stream stream)
{
MemoryStream ms = new MemoryStream();
byte[] chunk = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(chunk, 0, chunk.Length)) > 0)
{
ms.Write(chunk, 0, bytesRead);
}
return ms.ToArray();
}
public static bool Upload(string FileName, byte[] Image, string targetURI,string targetUser, string targetPass)
{
try
{
FtpWebRequest clsRequest = (FtpWebRequest)WebRequest.Create(targetURI+FileName);
clsRequest.Credentials = new NetworkCredential(targetUser, targetPass);
clsRequest.Method = WebRequestMethods.Ftp.UploadFile;
Stream clsStream = clsRequest.GetRequestStream();
clsStream.Write(Image, 0, Image.Length);
clsStream.Close();
clsStream.Dispose();
return true;
}
catch
{
return false;
}
}
}
}
You may run into issues if you are using things that have special encoding, like text documents. That can be changed by the way the upload function is used. If you're doing text files, use:
System.Text.Encoding.UTF8.GetBytes(responseStream)
instead of
ToByteArray(responseStream)
You could do a simple extension check of your file before executing the upload.

Connecting ftp server with credentials

I'm writing a program that uses an ftp server with credentials. I'm trying to retrieve the directory list from the server but when I get to the line:
string line = reader.ReadLine();
the string that I get contains only : "Can't open \"host:/lib1\"."
If I try to get another line, the next exception is thrown: The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
I know for sure (using another ftp application) that 'lib1' directory exists on the ftp server and my credentials (username and password) are correct.
Here is my code:
public class FTPClient
{
public string UserName { get; set; }
public string Password { get; set; }
public string IpAddress { get; set; }
public int Port { get; set; }
public FTPClient(string _userName, string _password, string _address, int _port)
{
UserName = _userName;
Password = _password;
IpAddress = _address;
Port = _port;
}
public void GetDirectoriesList(string _path)
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(new Uri("ftp://" +
IpAddress + _path));
request.UseBinary = true;
request.Method = WebRequestMethods.Ftp.ListDirectory;
request.Credentials = new NetworkCredential(UserName, Password);
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string line = reader.ReadLine();
while (line!=null)
{
... //do something with line
line = reader.ReadLine();
}
...
reader.Close();
response.Close();
}
And I use it as follows:
FTPClient ftpClient = new FTPClient("user1", "pass1", "192.168.2.110", 21);
string dirList = ftpClient.GetDirectoriesList("/lib1");
Can anyone spot the problem?
My solution:
public string[] GetDirectory()
{
StringBuilder result = new StringBuilder();
FtpWebRequest requestDir = (FtpWebRequest)WebRequest.Create("ftp://urserverip/");
requestDir.Method = WebRequestMethods.Ftp.ListDirectory;
requestDir.Credentials = new NetworkCredential("username", "password");
FtpWebResponse responseDir = (FtpWebResponse)requestDir.GetResponse();
StreamReader readerDir = new StreamReader(responseDir.GetResponseStream());
string line = readerDir.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = readerDir.ReadLine();
}
result.Remove(result.ToString().LastIndexOf('\n'), 1);
responseDir.Close();
return result.ToString().Split('\n');
}
Some refinements to Abdul Waheed's answer:
Added using blocks to clean up the FtpWebResponse and StreamReader objects;
Reduced string manipulation:
private static string[] GetDirectoryListing()
{
FtpWebRequest directoryListRequest = (FtpWebRequest)WebRequest.Create("ftp://urserverip/");
directoryListRequest.Method = WebRequestMethods.Ftp.ListDirectory;
directoryListRequest.Credentials = new NetworkCredential("username", "password");
using (FtpWebResponse directoryListResponse = (FtpWebResponse)directoryListRequest.GetResponse())
{
using (StreamReader directoryListResponseReader = new StreamReader(directoryListResponse.GetResponseStream()))
{
string responseString = directoryListResponseReader.ReadToEnd();
string[] results = responseString.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
return results;
}
}
}

Categories