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;
}
}
Related
I have this method:
public async Task CopyFileToOurFTP(FtpCredentialModel model)
{
foreach (var fileName in model.FileNames)
{
try
{
string uri = model.Host + "/" + fileName;
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return;
}
FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(model.Username, model.Password);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream("D:\\Dev" + "\\" + fileName, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = await responseStream.ReadAsync(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = await responseStream.ReadAsync(buffer, 0, Length);
}
writeStream.Close();
response.Close();
}
catch (WebException wEx)
{
_logger.Error($"{wEx.Message} >>> {wEx.StackTrace}");
}
catch (Exception ex)
{
_logger.Error($"{ex.Message} >>> {ex.StackTrace}");
}
}
}
My credential model class:
public class FtpCredentialModel
{
public string Host { get; set; }
public string FileMask { get; set; }
public List<string> FileNames { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public FtpCredentialModel()
{
FileNames = new List<string>();
}
}
and json
{
"host": "ftp://ftp.com:21",
"fileMask": ".txt",
"fileNames": [
"test.txt",
"test_01.txt"
],
"username": "guest",
"password": "guest"
}
and I want make it async and return count of download files.
As far as I understand, I need to make FtpWebResponse asynchronous, but I don't understand how. Who can help me?
The FtpWebRequest class implements both GetResponseAsync and GetRequestStreamAsync which you can use to make your request async
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(model.Username, model.Password);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = await reqFTP.GetResponseAsync();
Stream responseStream = await response.GetRequestStreamAsync();
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);
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);
}
}
}
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.
The problem with this code is that the file, once it is uploaded, is not the correct format. I'm trying to upload a .zip file.
public string HttpPost(string uri, string parameter)
{
WebRequest webRequest = WebRequest.Create(uri);
NetworkCredential credentials = new NetworkCredential("username", "password");
webRequest.Credentials = credentials;
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(parameter);
Stream os = null;
try
{ // send the Post
webRequest.ContentLength = bytes.Length; //Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Send it
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Request error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (os != null)
{
os.Close();
}
}
try
{ // get the response
WebResponse webResponse = webRequest.GetResponse();
if (webResponse == null)
{ return null; }
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
return sr.ReadToEnd().Trim();
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Response error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return null;
}
This example how to upload file in MyBucket
private const string KeyId = "Your KeyId";
private const string AccessKey = "Your AccessKey";
private const string S3Url = "https://s3.amazonaws.com/";
private static void UploadFile()
{
var fileData = File.ReadAllBytes(#"C:\123.zip");
string timeStamp = string.Format("{0:r}", DateTime.UtcNow);
string stringToConvert = "PUT\n" + //Http verb
"\n" + //content-md5
"application/octet-stream\n" + //content-type
"\n" + //date
"x-amz-acl:public-read"+"\n" + //date
"x-amz-date:" + timeStamp + "\n" + //optionall
"/MyBucket/123.zip"; //resource
var ae = new UTF8Encoding();
var signature = new HMACSHA1 {Key = ae.GetBytes(AccessKey)};
var bytes = ae.GetBytes(stringToConvert);
var moreBytes = signature.ComputeHash(bytes);
var encodedCanonical = Convert.ToBase64String(moreBytes);
var url = "https://MyBucket.s3.amazonaws.com/123.zip";
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "PUT";
request.Headers["x-amz-date"] = timeStamp;
request.Headers["x-amz-acl"] = "public-read";
request.ContentType = "application/octet-stream";
request.ContentLength = fileData.Length;
request.Headers["Authorization"] = "AWS " + KeyId + ":" + encodedCanonical;
var requestStream = request.GetRequestStream();
requestStream.Write(fileData, 0, fileData.Length);
requestStream.Close();
using (var response = request.GetResponse() as HttpWebResponse)
{
var reader = new StreamReader(response.GetResponseStream());
var data = reader.ReadToEnd();
}
}
Take a look on Amazon S3 REST API