Please tell me how to upload a XML file using FTP in c#? Im currently using FtpWebRequest method and its giving me errors
my code is
//Create FTP request
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("ftp://www.itsthe1.com/profiles/nuwan/sample.txt");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(Username, Password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = false;
//Load the file
FileStream stream = File.OpenRead(#"C:\sample.txt");
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
stream.Close();
//Upload file
Stream reqStream = request.GetRequestStream();
reqStream.Write(buffer, 0, buffer.Length);
reqStream.Close();
Here is my successfully working code to upload any file through FTP (I've written it in VB.NET but hopefully you can convert it to C# using any of the online translators)
Public Function Upload(ByVal fi As FileInfo, Optional ByVal targetFilename As String = "") As Boolean
'copy the file specified to target file: target file can be full path or just filename (uses current dir)
'1. check target
Dim target As String
If targetFilename.Trim = "" Then
'Blank target: use source filename & current dir
target = GetCurrentUrl() & "/" & fi.Name
Else
'otherwise treat as filename only, use current directory
target = GetCurrentUrl() & "/" & targetFilename
End If
Dim URI As String = target 'GetCurrentUrl() & "/" & target
'perform copy
Dim ftp As Net.FtpWebRequest = GetRequest(URI)
'Set request to upload a file in binary
ftp.Method = Net.WebRequestMethods.Ftp.UploadFile
ftp.UseBinary = True
'Notify FTP of the expected size
ftp.ContentLength = fi.Length
'create byte array to store: ensure at least 1 byte!
Const BufferSize As Integer = 2048
Dim content(BufferSize - 1) As Byte, dataRead As Integer
'open file for reading
Using fs As FileStream = fi.OpenRead()
Try
'open request to send
Using rs As Stream = ftp.GetRequestStream
Dim totBytes As Long = 0
Do
dataRead = fs.Read(content, 0, BufferSize)
rs.Write(content, 0, dataRead)
totBytes += dataRead
RaiseEvent StatusChanged(totBytes.ToString() & " bytes sent...")
Loop Until dataRead < BufferSize
rs.Close()
RaiseEvent StatusChanged("File uploaded successfully")
End Using
Catch ex As Exception
RaiseEvent StatusChanged("Error: " & ex.Message)
Finally
'ensure file closed
fs.Close()
End Try
End Using
ftp = Nothing
Return True
End Function
Here is the link to the entire article about developing this FTP Client:
http://dot-net-talk.blogspot.com/2008/12/how-to-create-ftp-client-in-vbnet.html
protected void Button1_Click(object sender, EventArgs e)
{
string server = "-------"; //your ip address
string ftpPath = "ftp://" + server + "//Files//" +FileUpload1.FileName;
string uname = "-----";
string password = "----------";
string filePath = Server.MapPath("~") + "\\" + FileUpload1.FileName;
try
{
UploadToFTP(ftpPath,filePath,uname,password);
}
catch (Exception ex)
{
//logic here
}
}
`private bool UploadToFTP(string strFTPFilePath, string strLocalFilePath, string strUserName, string strPassword)
{
try
{
//Create a FTP Request Object and Specfiy a Complete Path
// System.Net.WebRequest.Create(strFTPFilePath);
FtpWebRequest reqObj = (FtpWebRequest)WebRequest.Create(strFTPFilePath);
//Call A FileUpload Method of FTP Request Object
reqObj.Method = WebRequestMethods.Ftp.UploadFile;
//If you want to access Resourse Protected,give UserName and PWD
reqObj.Credentials = new NetworkCredential(strUserName, strPassword);
// Copy the contents of the file to the byte array.
byte[] fileContents = File.ReadAllBytes(strLocalFilePath);
reqObj.ContentLength = fileContents.Length;
//Upload File to FTPServer
Stream requestStream = reqObj.GetRequestStream();
// Stream requestStream = response.GetResponseStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)reqObj.GetResponse();
response.Close();
Label1.Text = "File Transfered Completed" + response.StatusDescription;
}
catch (Exception Ex)
{
throw Ex;
}
return true;
} `
Related
While executing the below code I am getting the following error
(The underlying connection was closed The server committed a protocol
violation )
. Please help on this. I almost go throw every article about the error still not getting the solution.
Thanks in Advance.
private static void Upload()
{
string sourceFile = System.IO.Path.Combine(filepath, filename);
string ftpServerIP = "Hostname";
string ftpUserID = "UserName";
string ftpPassword = "Password";
FileInfo fileInf = new FileInfo(sourceFile);
string uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpServerIP + "/" + fileInf.Name));
// Provide the WebPermission Credintials
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
// By default KeepAlive is true, where the control connection is not closed
// after a command is executed.
reqFTP.KeepAlive = false;
// Specify the command to be executed.
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// Specify the data transfer type.
reqFTP.UseBinary = true;
// Notify the server about the size of the uploaded file
reqFTP.ContentLength = fileInf.Length;
// The buffer size is set to 2kb
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
FileStream fs = fileInf.OpenRead();
//try
//{
// Stream to which the file to be upload is written
Stream strm = reqFTP.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, buffLength);
// Until Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
//}
//catch (Exception ex)
//{
// Console.Write(ex.Message, "Upload Error");
//}
}
I found the answer for the problem. I was using SFTP server instead of FTP the code was entirely different.
So I changed the code.
using Renci.SshNet;
public static void UploadSFTPFile()
{
_SftpDetails = ReadIniFile(IniFilePath, "Sftp_Settings", SftpDetails);
string sourcefile = System.IO.Path.Combine(filepath, filename);
string destinationpath = _SftpDetails["SftpDestinationFolder"];
string host = _SftpDetails["Host"];
string username = _SftpDetails["UserName"];
string password = _SftpDetails["Password"];
int port = Convert.ToInt32(_SftpDetails["Port"]); //Port 22 is defaulted for SFTP upload
try
{
using (SftpClient client = new SftpClient(host, port, username, password))
{
client.Connect();
client.ChangeDirectory(destinationpath);
using (FileStream fs = new FileStream(sourcefile, FileMode.Open))
{
client.BufferSize = 4 * 1024;
client.UploadFile(fs, Path.GetFileName(sourcefile));
}
}
}
catch(Exception ex)
{
Console.Write(ex.Message);
return;
}
}
you have to install .sshNet from the NuGet Package Manager
I am trying to modify this FTP connection method to upload multiple files in a single connection.
As you can see I have got a while loop that iterates through a filename and filepath array, I have set the WebRequest to keep alive. I am not sure what I should move out of the loop to stop new connections from constantly opening up.
This is the error I am getting:
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).
Thanks in advance!
Public string FTPUploadMultipleFiles(string ftpURL, string Username, string Password, string[] filePaths, string[] fileNames)
{
string result = "OK";
try
{
int Counter = 0;
if (filePaths.Count() == fileNames.Count())
while (Counter <= filePaths.Count() - 1)
{
FileInfo fileInf = new FileInfo(filePaths[Counter]);
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpURL + "/" + fileNames[Counter]));
reqFTP.Credentials = new NetworkCredential(Username, Password);
reqFTP.KeepAlive = true;
// Specify the command to be executed.
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// Specify the data transfer type.
reqFTP.UsePassive = true;
reqFTP.UseBinary = true;
// Notify the server about the size of the uploaded file
reqFTP.ContentLength = fileInf.Length;
// The buffer size is set to 2kb
int buffLength = 204800;
byte[] buff = new byte[buffLength];
int contentLen;
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
FileStream fs = fileInf.OpenRead();
try
{
// Stream to which the file to be upload is written
Stream strm = reqFTP.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, Convert.ToInt32(buffLength));
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
Counter++;
}
catch (Exception ex)
{
result = ex.Message;
}
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
I have to upload some files on a FTP who use TLS with my C# application ( .net 3.5 )
With Filezila, no problems.
Now, with my C# code, i have a timeout exception and i really don't know why because all is ok with Filezila.
Here is my code :
public static bool AcceptAllCertificatePolicy(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public static string Upload_SSL(string filenameSrc)
{
ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertificatePolicy;
FileInfo fileInfSrc = new FileInfo(filenameSrc);
FtpWebRequest reqFTP;
// Create FtpWebRequest object from the Uri provided
if (strDirectory.Trim() != "")
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strHost.Trim() + "/" + strDirectory.Trim() + "/" + fileInfSrc.Name.Trim()));
}
else
{
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + strHost.Trim() + "/" + fileInfSrc.Name.Trim()));
}
reqFTP.EnableSsl = true;
// Provide the WebPermission Credintials
reqFTP.Credentials = new NetworkCredential(strUser.Trim(), strPass.Trim());
reqFTP.Proxy = null;
// By default KeepAlive is true, where the control connection is not closed
// after a command is executed.
reqFTP.KeepAlive = false;
// Specify the command to be executed.
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
// Specify the data transfer type.
reqFTP.UseBinary = true;
// Notify the server about the size of the uploaded file
reqFTP.ContentLength = fileInfSrc.Length;
// The buffer size is set to 8kb
int buffLength = 8192;
byte[] buff = new byte[buffLength];
int contentLen;
// Opens a file stream (System.IO.FileStream) to read the file to be uploaded
FileStream fs = fileInfSrc.OpenRead();
try
{
// Stream to which the file to be upload is written
Stream strm = reqFTP.GetRequestStream();
// Read from the file stream 2kb at a time
contentLen = fs.Read(buff, 0, buffLength);
// Till Stream content ends
while (contentLen != 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
// Close the file stream and the Request Stream
strm.Close();
fs.Close();
}
catch (Exception ex)
{
fs.Close();
return (ex.Message);
}
return "ok";
}
Now, the call :
myFtp.Class1.strHost = "ftp://XXXXXXXXXXXXX";
myFtp.Class1.strPass = "*****************";
myFtp.Class1.strUser = "*********";
myFtp.Class1.nPort = 21;
myFtp.Class1.Upload_SSL(#"D:\Test.txt");
As information, if i try to use my code in order to upload a file on a NON TLS/SLL server, all is ok. So the problem appear to be only for the TLS/SSL ftp.
Anyone have some ideas please ?
Thanks a lot,
I kept the FTP:// in the host, so the url was FTP://FTP:/xxxxx
I'm not sure why my file is corrupted. I'm not using StreamReader which has been a common problem that most have had. It uploads successfully I just can't seem to find the issue on why the file is corrupted even after searching through the various solved stack overflow questions.
public ActionResult UploadFtpFile(HttpPostedFileBase promoImgFile)
{
bool isSavedSuccessfully = true;
string fileName = null;
string completeDPath = "xxxxx";
string username = "xxxx";
string password = "xxxxx";
FtpWebRequest ftpClient;
FtpWebRequest ftpRequest;
List<string> directories = new List<string>();
try
{
foreach (string fileItemName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileItemName];
fileName = file.FileName;
if (file != null && file.ContentLength > 0)
{
//Create FtpWebRequest object
ftpClient = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + completeDPath + "/" + fileName));
//Set request method
ftpClient.Method = WebRequestMethods.Ftp.UploadFile;
//Set Credentials
ftpClient.Credentials = new NetworkCredential(username, password);
//Opens a file to read
Stream objFile = file.InputStream;
//By default KeepAlive is true, where the control connection is not closed after a command is executed.
ftpClient.KeepAlive = true;
//Set the data transfer type
ftpClient.UseBinary = true;
//Set content length
ftpClient.ContentLength = file.ContentLength;
//Get Stream of the file
Stream objStream = ftpClient.GetRequestStream();
byte[] buffer = new byte[objFile.Length];
//Write file content
objStream.Write(buffer, 0, buffer.Length);
objStream.Close();
objFile.Close();
}
}
}
catch(Exception ex)
{
throw ex;
isSavedSuccessfully = false;
}
//return Json(new { promoImgFile = directories });
return RedirectToAction("Index", "Home", new { promoImgFile = directories });
}
It's this line right here:
Stream objFile = file.InputStream;
Years of learning, I figured out one thing that works:
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
Then work off the MemoryStream.
Example (for text)
Docs: MSDN
The important part for your issue:
StreamReader sourceStream = new StreamReader("testfile.txt");
byte [] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
Example (for an image)
byte [] imageData = File.ReadAllBytes(imageSource);
request.ContentLength = imageData.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(imageData, 0, imageData.Length);
requestStream.Close();
Finding some problems copying a zip file from an FTP location. It is just copying and empty file so I think there is something wrong with my use of StreamReader or StreamWriter.
Here is the code:
//read through directory details response
string line = reader.ReadLine();
while (line != null)
{
if (line.EndsWith("zip")) //"d" = dir don't need "." or ".." dirs
{
FtpWebRequest downloadRequest = (FtpWebRequest)FtpWebRequest.Create("ftp://" + ftpHost + line); //new Uri("ftp://" + ftpServerIP + DestinationFolder + fileInf.Name));
downloadRequest.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FilesUser"], ConfigurationManager.AppSettings["FilesPass"]);
downloadRequest.KeepAlive = false;
downloadRequest.UseBinary = true;
downloadRequest.Method = WebRequestMethods.Ftp.DownloadFile;
string folderToWrite = HttpContext.Current.Server.MapPath("~/Routing/RoutingFiles/");
string folderToSave = HttpContext.Current.Server.MapPath("~/Routing/");
StreamReader downloadRequestReader = new StreamReader(downloadRequest.GetResponse().GetResponseStream());
DirectoryInfo downloadDirectory = new DirectoryInfo(folderToWrite);
FileInfo file = new FileInfo(Path.Combine(downloadDirectory.FullName, line));
if (!file.Exists)
{
StreamWriter writer = new StreamWriter(Path.Combine(folderToWrite, line), false);
writer.Write(downloadRequestReader.ReadToEnd());
using (var downloadResponseStream = response.GetResponseStream())
{
}
}
}
}
By the time it gets to the bottom of that section, the file has been copied but is empty so I don't think I'm reading the stream correctly for a zip file. Anyone any ideas? I've seen talk of FileStream being better for downloading Zip files, but I couldn't get that to work either.
Thanks.
Here is an example that downloads a file from an ftp.
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpAddr + "test.zip");
request.Credentials = new NetworkCredential(userName, password);
request.UseBinary = true; // Use binary to ensure correct dlv!
request.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writer = new FileStream("test.zip", FileMode.Create);
long length = response.ContentLength;
int bufferSize = 2048;
int readCount;
byte[] buffer = new byte[2048];
readCount = responseStream.Read(buffer, 0, bufferSize);
while (readCount > 0)
{
writer.Write(buffer, 0, readCount);
readCount = responseStream.Read(buffer, 0, bufferSize);
}
responseStream.Close();
response.Close();
writer.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Edit I'm sorry for the error in previous code.
When correcting my previous code I found the following resource useful: example