Move files from Azure Storage blob to an Ftp server - c#

I need to upload a few files from Azure Storage to an external Ftp server.
Is there any way with Azure to uplodad these files directly without download them before ?

You will need to use two classes/libraries and create two methods here:
WebClient class to download the file from the blob storage to your local drive
FTP library such WinSCP to move the file
WebClient Class:
You need to supply the URI parameter with the format: https://[accountname].blob.core.windows.net/[containername]/[filetodownloadincludingextension]
The download location must then be a variable as the origin location of the file to be uploaded to your FTP server.
string uri = "https://[accountname].blob.core.windows.net/[containername]/[filetodownloadincludingextension]/";
string file = "file1.txt";
string downloadLocation = #"C:\";
WebClient webClient = new WebClient();
Log("Downloading File from web...");
try
{
webClient.DownloadFile(new Uri(uri+file), downloadLocation);
Log("Download from web complete");
webClient.Dispose();
}
catch (Exception ex)
{
Log("Error Occurred in downloading file. See below for exception details");
Log(ex.Message);
webClient.Dispose();
}
return downloadLocation + file;
Once downloaded in your local drive, you need to upload it to your FTP/SFTP server. You may use the library of WinSCP for this:
string absPathSource = downloadLocation + file;
string destination = "/root/folder"; //this basically is your FTP path
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = ConfigurationManager.AppSettings["scpurl"],
UserName = ConfigurationManager.AppSettings["scpuser"],
Password = ConfigurationManager.AppSettings["scppass"].Trim(),
SshHostKeyFingerprint = ConfigurationManager.AppSettings["scprsa"].Trim()
};
using (Session session = new Session())
{
//disable version checking
session.DisableVersionCheck = true;
// Connect
session.Open(sessionOptions);
// Upload files
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
TransferOperationResult transferResult;
transferResult = session.PutFiles(absPathSource, destination, false, transferOptions);
// Throw on any error
transferResult.Check();
// Print results
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
//Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
}
}
You may include a File.Delete code at the end of the upload to FTP code if you want to delete the file from your local hard drive after the upload.

Related

Check if any file with an extension exists on SFTP server using WinSCP .NET assembly

What is the C# code to check if any .xls files are in a remote SFTP folder using WinSCP .NET assembly? The xls files have different names, I only know the files I want will have am xls file extension.
string strFileRemote = #"/folder/*.xls";
// Set up session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = sftpHost,
UserName = sftpUsername,
SshHostKeyFingerprint = "value for finger print",
SshPrivateKeyPath = #"\\file server\.ppk",
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Upload files
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
TransferOperationResult transferResult;
// Download
transferResult =
session.GetFiles(strFileRemote, strFileLocal, false, transferOptions);
// Throw on any error
transferResult.Check();
if (transferResult.IsSuccess == false)
{
strStatus = "Error: " + transferResult.ToString();
}
}
As suggested by WinSCP article on Checking file existence, use Session.EnumerateRemoteFiles to check, if any file matching a mask exists on am SFTP server:
bool anyXmlExists =
session.EnumerateRemoteFiles("/folder", "*.xml", EnumerationOptions.None).Any();

FTPS using fingerpring

I have to communicate to an FTP server with SSL.
I've received an example on how to do that that uses, I believe, the WinScp command:
open ftpes://SomeUser:SomePass#SomeDomain.com/ -certificate="xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
The question is how to use the -certificate part in an application? Do I have to save the string in a file or...?
For example if we use C#'s FtpWebRequest:
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(downlaodLocation);
how can we use this fingerprint?
X509Certificate class has a constructor that accepts byte[].
byte[] toBytes = Encoding.ASCII.GetBytes("xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx");
ftp.ClientCertificates.Add(new X509Certificate(toBytes));
Is this the right way to use the certificate fingerprint?
Eventually I took a different approach for uploading the file and used WinScp for c# lib for that.
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = ConfigurationManager.AppSettings["FTP.HOSTNAME"],
UserName = ConfigurationManager.AppSettings["FTP.USERNAME"],
Password = ConfigurationManager.AppSettings["FTP.PASSWORD"],
};
if (port.HasValue)
{
sessionOptions.PortNumber = port.Value;
}
sessionOptions.SshHostKeyFingerprint = ConfigurationManager.AppSettings["FTP.CERT.FINGERPRINT"].Trim();
using (Session session = new Session())
{
if (!string.IsNullOrWhiteSpace(ConfigurationManager.AppSettings["LOG.PATH"]))
{
session.SessionLogPath = ConfigurationManager.AppSettings["LOG.PATH"];
}
session.Open(sessionOptions);
TransferOptions transferOptions = new TransferOptions
{
TransferMode = TransferMode.Binary
};
TransferOperationResult transferResult = session.PutFiles(ConfigurationManager.AppSettings["FILE.TO.UPLOAD"], ConfigurationManager.AppSettings["FILE.DESTINATION.NAME"], true, transferOptions);
transferResult.Check();
StringBuilder result = new StringBuilder();
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
result.Append(string.Format("Upload of {0} : {1}", transfer.FileName, transfer.Error));
}
Console.WriteLine(result.ToString());
}

Upload all files matching wildcard to SFTP

I am using Tamir SharpSSH for transferring files from remote to local and vice versa with no issues.
But, when trying to upload multiple XML files via SFTP but I am receiving an error:
Illegal characters in path.
If I try to upload using the exact file name it transfers the file without any issues.
Every time I try to upload two XML files:
KDO_E2D_A21_AA769_20170124_143123.xml
KDO_E2D_A21_AA776_20170130_143010.xml
string ftpURL = "11.11.11.1";
string userName = "Aaaaaa"; //User Name of the SFTP server
string password = "hah4444"; //Password of the SFTP server
int port = 22; //Port No of the SFTP server (if any)
//The directory in SFTP server where the files will be uploaded
string ftpDirectory = "/home/A21sftp/kadoe/";
//Local directory from where the files will be uploaded
string localDirectory = "E:\\Zatpark\\*.xml";
Sftp Connection = new Sftp(ftpURL, userName, password);
Connection.Connect(port);
Connection.Put(localDirectory, ftpDirectory);
Connection.Close();
Do not use Tamir.SharpSSH, it's a dead project. Use some up to date SSH/SFTP implementation.
If you switch to library like SSH.NET that does not support wildcards, you have to use the Directory.GetFiles method to find files to upload:
SftpClient client = new SftpClient("example.com", "username", "password");
client.Connect();
string localDirectory = #"E:\Zatpark upload";
string localPattern = "*.xml";
string ftpDirectory = "/dv/inbound/";
string[] files = Directory.GetFiles(localDirectory, localPattern);
foreach (string file in files)
{
using (Stream inputStream = new FileStream(file, FileMode.Open))
{
client.UploadFile(inputStream, ftpDirectory + Path.GetFileName(file));
}
}
Or use a library that does support wildcards.
For example with WinSCP .NET assembly (what is not a pure .NET assembly though), you can do:
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "example.com",
UserName = "username",
Password = "password",
SshHostKeyFingerprint = "ssh-dss ...",
};
using (Session session = new Session())
{
session.Open(sessionOptions);
string ftpDirectory = "/dv/inbound/";
string localDirectory = #"E:\Zatpark upload\*.xml";
session.PutFiles(localDirectory, ftpDirectory).Check();
}
You can have a code template generated in WinSCP GUI.
(I'm the author of WinSCP)
To explain, why your code does not work: Check the ChannelSftp.glob_local method. Its implementation is strange, if not broken. It basically supports only masks consisting completely of * and ?'s.

error copying images from local to network shared folder

I am trying to copy images from a external device to a folder which is on network but the problem with my code is its creating a folder in local drive(c:) and coping the images. but I have this folder on network.
It should just create a folder with today's date ans copy the images on the network.
string _ftpURL = #"00.000.00.0"; //Host URL or address of the SFTP server
//string _ftpURL = #"0.0.0.0";
string _UserName = "root"; //User Name of the SFTP server
string _Password = "3p1"; //Password of the SFTP server
int _Port = 2222; //Port No of the SFTP server (if any)
string _ftpDirectory = "/opt/prassel/data/snap/*.jpg"; //The directory in SFTP server where the files will be uploaded
var LocalDirectory = string.Format("\\ws4.lboro.ac.uk\\SY0-1ticketPhotofolder\\TICKET PHOTO'S\\{0:yyyy-MM-dd}", DateTime.Now);
System.IO.Directory.CreateDirectory(LocalDirectory);
Sftp Connection = new Sftp(_ftpURL, _UserName, _Password);
Connection.Connect(_Port);
Connection.Get(_ftpDirectory, LocalDirectory);
Connection.Close();
Remote UNC pats start with two slashes. Assuming ws4.lboro.ac.uk is the server name:
var LocalDirectory = string.Format("\\\\ws4.lboro.ac.uk\\SY0-1ticketPhotofolder\\TICKET PHOTO'S\\{0:yyyy-MM-dd}", DateTime.Now);
or just
var LocalDirectory = string.Format(#"\\ws4.lboro.ac.uk\SY0-1ticketPhotofolder\TICKET PHOTO'S\{0:yyyy-MM-dd}", DateTime.Now);

“Can't get attributes of file” error when downloading file using WinSCP .NET assembly

I am working with WinSCP .NET library to transfer files from Linux to Windows.
I have a code but files are not getting downloaded.
Can someone look into this code and see what am I doing wrong.
In my view some problem is occurring in code line beginning with transferResult.
My Code :
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "sj1slm612",
UserName = "username",
Password = "password",
SshHostKeyFingerprint = "ssh-rsa 2048 fa:e9:58:24:1b:41:a3:15:63:0d:c0:72:41:5d:51:7a"
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Download Files
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
TransferOperationResult transferResult;
transferResult = session.GetFiles("/apps/instances/sj1slm612/express_13000/configuration/standalone-full.xml", "C:\\Users\\karansha\\Desktop\\sj1slm612\\express_13000", false, transferOptions);
transferResult = session.GetFiles("/apps/instances/sj1slm612/query_13100/configuration/standalone-full.xml", "C:\\Users\\karansha\\Desktop\\sj1slm612\\query_13100", false, transferOptions);
transferResult = session.GetFiles("/apps/instances/sj1slm612/wppapi_13200/configuration/standalone-full.xml", "C:\\Users\\karansha\\Desktop\\sj1slm612\\wppapi_13200", false, transferOptions);
transferResult = session.GetFiles("/apps/instances/sj1slm612/wppgui_13300/configuration/standalone-full.xml", "C:\\Users\\karansha\\Desktop\\sj1slm612\\wppgui_13300", false, transferOptions);
// Throw Error
transferResult.Check();
Console.WriteLine("All Files Downloaded");
Console.ReadLine();
}
Error message is:
Can't get attributes of file '/apps/instances/sj1slm612/wppgui_13300/configuration/standalone-full.xml'.

Resources