I've created an application that uploads files to a remote FTP server. If the credentials (address, username, password, etc.) are wrong I want to to throw an error. As of right now it never does. What is wrong with my code? When the credentials are correct it does successfully upload.
here is the class I am using:
public void upload(string remoteFile, string localFile)
{
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remoteFile);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpStream = ftpRequest.GetRequestStream();
FileStream localFileStream = File.OpenRead(localFile);
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return;
}
and where I'm calling the upload function in the form:
On button click =
ftp ftpClient = new ftp(#"ftp://weburl.com/", "user", "password");
UploadToFTP("testing/file.txt" , #"C:\file.txt");
void UploadToFTP(string FTPfolder, string LocalFolder)
{
try
{
ftpClient.upload(FTPfolder, LocalFolder);
Messagebox.Show("Uploaded Successfully!");
}
catch (Exception ex)
{
Messagebox.Show(ex.ToString());
}
}
From my comment if there is an error, its spitting it to the console, but isn't waiting for readkey, so the console is disappearing, you never catch another exception in your call because the catch in the function is handling the error. Inside the function replace Console.WriteLine with Messagebox.Show to see the caught errors
public void upload(string remoteFile, string localFile)
{
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + remoteFile);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpStream = ftpRequest.GetRequestStream();
FileStream localFileStream = File.OpenRead(localFile);
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { Messagebox.Show(ex.ToString()); }
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex) { Messagebox.Show(ex.ToString()); }
return;
}
Rewrite your upload function is eating the exception.
I would rewrite your catch block this way:
try
{
// ....
}
catch (WebException webEx)
{
string message = string.Empty;
if (webEx.Response.GetType() == typeof(FtpWebResponse))
{
FtpWebResponse response = (FtpWebResponse)webEx.Response;
message = string.Format("{0} - {1}", response.StatusCode, response.StatusDescription);
} else
{
message = webEx.Message;
}
throw new Exception(message);
}
Related
I am trying to file download from remote machine with FTP in c# but it doesn't work. when i came GetResponse Method with f10, threw the exception. its says:"unable to connect to remote server", it looks like about connection problem but its not.
when i create request in the code ContentType and PreAuthenticate is threw an exception and said:"System.NotSupportedException"
How can i fix this? Any ideas?
Here's the Connection Info for FTP.
private static string host = #"ftp://XXX.XX.XXX.XX/";
private static string user = "XXXXXXXX";
private static string pass = "XXXXXXXX";
private static string localfile = #"E:/Files/Attachment";
private static string remoteFile = #"D:/log/stdlog.6.txt";
And then FTP class
public class FtpServer
{
private string host = null;
private string user = null;
private string pass = null;
private FtpWebRequest ftpRequest = null;
private FtpWebResponse ftpResponse = null;
private Stream ftpStream = null;
private int bufferSize = 2048;
/* Construct Object */
public FtpServer(string hostIP, string userName, string password) { host = hostIP; user = userName; pass = password; }
public void Download(string remoteFile, string localFile)
{
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host+remoteFile);
ftpRequest.Credentials = new NetworkCredential(user,pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return;
}
}
Unable to connect to remote server could be several reasons.
1) you could be mistakenly typing the server address and pointing to a non-existing address.
2) The server is temporarily shut or down and you cannot access it.
3) You typed in wrong credentials for the server.
Either way, I suggest you to implement using statement in your code rather then using close() on every stream:
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
using (ftpResponse = (FtpWebResponse)ftpRequest.GetResponse())
{
using (ftpStream = ftpResponse.GetResponseStream())
{
using (FileStream localFileStream = new FileStream(localFile, FileMode.Create))
{
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
ftpRequest = null;
I need to create file or directory on ftp via C# (in Unity engine). I tried to upload the file this way:
public void upload(string remoteFile, string file_content)
{
try
{
string address = host + #"/текст.txt";
Debug.Log(address); // gives a normal address in Unicode
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(address);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.ContentLength = file_content.Length;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
byte[] byteBuffer = System.Text.Encoding.Unicode.GetBytes(file_content);
try
{
using (ftpStream = ftpRequest.GetRequestStream())
{
ftpStream.Write(byteBuffer, 0, byteBuffer.Length);
Debug.Log(Convert.ToString(byteBuffer));
}
}
catch (Exception ex)
{
ErrorScene.error = "Local Error: 1. " + ex.ToString(); SceneManager.LoadScene("ErrorScene", LoadSceneMode.Single);
}
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex)
{
ErrorScene.error = "Local Error: 2. " + ex.ToString(); SceneManager.LoadScene("ErrorScene", LoadSceneMode.Single);
}
return;
}
And after this function call in ftp creates a file named ?????.txt.
Similarly with directories.
Is there a way to do this?
Thanks in advance.
I am using this code to connect my server and downloading the files. It is working fine.
public void downloadFile(object args)
{
writeStream = null;
response = null;
reader = null;
int dataLength = 0;
try
{
Array argArray = new object[3];
argArray = (Array)args;
ProgressBar progressBar1 = (ProgressBar)argArray.GetValue(0);
Label lbProgress = (Label)argArray.GetValue(1);
FTPInfo ftpInfo = (FTPInfo)argArray.GetValue(2);
string ipAddress = ftpInfo.IpAddress;
string path = ftpInfo.Path;
string fileName = ftpInfo.FileName;
path = Regex.Replace(path, "_.", "_e");
fileName = Regex.Replace(fileName, "_.", "_e");
string uri = null;
if (path.Equals(""))
{
uri = ipAddress + fileName;
}
else
{
uri = ipAddress + path + "/" + fileName;
}
string[] temp = ipAddress.Split('/');
string ip = "mchmultimedia.com";
string userName = ftpInfo.UserName;
string password = ftpInfo.Password;
downloadedData = new byte[0];
ftp = new FTPClass(path);
ftp.FtpServer = ip;
ftp.FtpUsername = userName;
ftp.FtpPassword = password;
ftp.FtpLogin();
dataLength = (int)ftp.GetFileSize(fileName);
Logger.LogDebugMessage("DataLength :" + dataLength.ToString());
ftp.CloseConnection();
FtpWebRequest request = FtpWebRequest.Create(uri) as FtpWebRequest;
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(userName, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
//Set up progress bar
UpdateProgressBarValue(progressBar1, 0);
SetProgressBarMaxValue(progressBar1, dataLength);
response = request.GetResponse() as FtpWebResponse;
reader = response.GetResponseStream();
if (!Directory.Exists(GlobalClass.ZIPPED_FOLDER))
Directory.CreateDirectory(GlobalClass.ZIPPED_FOLDER);
writeStream = new FileStream(GlobalClass.ZIPPED_FOLDER + "\\" + fileName, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = 0;
Logger.LogDebugMessage("Before while :" + dataLength.ToString());
while (true)
{
Application.DoEvents();
bytesRead = reader.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("reader close if bytesRead ==00", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("response close if bytesRead ==00", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream close if bytesRead ==00", ex);
}
}
catch (Exception ex)
{
}
UpdateProgressBarValue(progressBar1, progressBar1.Maximum);
Application.DoEvents();
break;
}
else
{
writeStream.Write(buffer, 0, bytesRead);
if (progressBar1.Value + bytesRead <= progressBar1.Maximum)
{
totalBytesRead = progressBar1.Value + bytesRead;
int percentage = (int)((double)totalBytesRead / dataLength * 100);
UpdateProgressBarValue(progressBar1, totalBytesRead);
SetText(lbProgress, "File download " + percentage.ToString() + " % completed");
if (percentage == 100)
{
if (totalBytesRead == dataLength)
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("reader close if percentage==100", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("response close if percentage==100", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream close if percentage==100", ex);
}
}
catch (Exception ex)
{
}
SetText(lbProgress, "File download successfully completed,Please wait...");
unzipFile(fileName);
}
}
RefreshProgressBar(progressBar1);
Application.DoEvents();
}
}
}
}
catch (System.Threading.ThreadAbortException ex)
{
if (thread != null)
{
thread.Abort();
}
Logger.LogErrorMessage("ThreadAbortException", ex);
}
catch (Exception ex)
{
Logger.LogErrorMessage("Exception there was an error connecting", ex);
Logger.ReportBug("There was an error connecting to the FTP Server.", ex);
}
finally
{
try
{
try
{
reader.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("read finally", ex);
}
try
{
response.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("resonse finally", ex);
}
try
{
writeStream.Close();
}
catch (Exception ex)
{
Logger.LogErrorMessage("writeStream finally", ex);
}
}
catch (Exception ex)
{
}
}
}
But client needs it to be secure FTP. So I tried by setting
request.EnableSsl = true;
as specified in Differences between SFTP and "FTP over SSH"
And it throws:
The remote server returned an error: (500) Syntax error, command unrecognized.
You are obviously required to use the SFTP protocol.
The FtpWebRequest class does not support the SFTP protocol. There's no support at all for SFTP in standard .NET libraries. See SFTP Libraries for .NET.
You current code is trying to connect with the FTP over TLS protocol to the FTP server. That is an another way of securing "file transfer" session. But this particular FTP server does not support it (hence the "500 Syntax error, command unrecognized" error).
So you have to rewrite your code to use the SFTP protocol.
That's unfortunately a completely different code.
I am trying to create a small console application that downloads files from a ftp server through Explicit FTP over TLS. I have create these applications before but i am getting an error with this one. I keep Getting this error:
The Remote Server returned an error: 150 Opening BINARY mode data connection fro "filename" <2000 bytes>.
I cant seem to figure out that to do, can anyone help me?
this is my code:
public void DownloadFiles(string fileName)
{
uri.Scheme = "ftp";
uri.Host = ftpUrl;
uri.Port = 21;
uri.UserName = username;
uri.Password = password;
uri.Path = "out";
try
{
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri.ToString() + "/" + fileName));
reqFTP.EnableSsl = true;
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response;
response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(localFolder + fileName, FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
Byte[] buffer = new Byte[bufferSize];
int readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writeStream.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
AppendLogFile(response, "Downloading Files: ", fileName);
writeStream.Close();
responseStream.Close();
response.Close();
reqFTP.Abort();
}
catch (Exception ex)
{
Console.WriteLine("Error in DownloadFileByFileName method!! " + ex.Message);
}
}
thanks!
I could not find the solution for this so i when over to use Chillkat for this application. works fine. But needed to buy a year license.
this is my code:
public void Connect(string fileName)
{
bool success;
success = ftp.UnlockComponent("license");
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.IdleTimeoutMs = 10000;
ftp.AuthTls = true;
ftp.Ssl = false;
ftp.Hostname = ftpUrl;
ftp.Port = 21;
ftp.Username = username;
ftp.Password = password;
ftp.KeepSessionLog = true;
success = ftp.Connect();
if (success != true)
{
Console.WriteLine(ftp.LastErrorText);
return;
}
ftp.ClearControlChannel();
bool sucess = ftp.GetFile("out/" + fileName, localFolder + fileName);
if (!success)
{
Console.WriteLine(ftp.LastErrorText);
AppendErrorLogFile("Error in downloading file", "Download file method", fileName);
return;
}
else
{
AppendLogFile("Download Success", "Download File Method", fileName);
ftp.DeleteRemoteFile("out/" + fileName);
}
}
long length = response.ContentLength;
Is at fault here I believe, if you use this to download a file that already exists, your request will close before you can get a response from the server and throw the 150 error.
When I want to get the size of a file on my ftp server I gets nothing.
Anyone see a problem in the code?
it seems to me that method is good
the class :
public string getFileSize(string fileName)
{
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(host + "/" + fileName);
ftpRequest.Credentials = new NetworkCredential(user, pass);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream);
string fileInfo = null;
try { while (ftpReader.Peek() != -1) { fileInfo = ftpReader.ReadToEnd(); } }
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
return fileInfo;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return "";
}
the process :
ftp ftpClientCheckFile = new ftp(#"ftp://******.******.fr", "***********", "********");
string ftpfileSize = ftpClientCheckFile.getFileSize(fileName);
if (ftpfileSize == localfilesize)
{
this.Invoke(new Action(() => { MessageBox.Show(this, "*********", "***", MessageBoxButtons.OK, MessageBoxIcon.Information); }));
ftpClientCheckFile = null;
}
else
{
this.Invoke(new Action(() => { MessageBox.Show(this, "***** ", "*******", MessageBoxButtons.OK, MessageBoxIcon.Information); }));
}
Thanks for help.
You need to use the ContentLength property to get the file size
Console.WriteLine(ftpResponse.ContentLength.ToString());
Some ftp servers don't support getfilesize so you will have to use ListDirectoryDetails