Thursday, March 9, 2023

Connect SFTP server using x++


 Connect SFTP server using x++.


For this, we need to create a C# project and we need to write code in C#. After that DLL file, I need to add it as a reference for my D365 project.

We need to download Renci.ssh.Net from the NuGet package.

We can download SSH from the below link:

https://github.com/sshnet/SSH.NET/releases/tag/2020.0.1

or

https://www.dllme.com./dll/files/renci_sshnet

Please follow this blog for Renci. Link


C# Code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Renci.SshNet;
namespace SFTPConnect
{
    public class sftpConnection
    {
        public SftpClient sftpClient;
 
        public SftpClient OpenSFTPConnection(string host, int port, string username, string password)
        {
            if (this.sftpClient == null)
            {
                this.sftpClient = new Renci.SshNet.SftpClient(host, port, username, password);
				
		--------------or-------------------------
		List<AuthenticationMethod> 	methods = new List<AuthenticationMethod>
		{
		    new PasswordAuthenticationMethod(username, password)
		};

		var connectionInfo = new ConnectionInfo(host, port, username, methods.ToArray());
						
		this.sftpClient = new SftpClient(connectionInfo);
            }
 
            if (!this.sftpClient.IsConnected)
            {
                this.sftpClient.Connect();
            }
 
            return this.sftpClient;
        }
 
        public List<string> GetDirectories(SftpClient _SftpClient, string path)
        {
            return _SftpClient.ListDirectory(path)/*.Where(n => n.IsDirectory)*/.Select(n => n.Name).ToList();
        }
 
        public void MoveFile(SftpClient _SftpClient, string sourcePath, string destinationPath, bool isPosix)
        {
            _SftpClient.RenameFile(sourcePath, destinationPath, isPosix);
        }
 
        public Stream DownloadFile(SftpClient _SftpClient, string sourcePath)
        {
            var memoryStream = new MemoryStream();
 
            _SftpClient.DownloadFile(sourcePath, memoryStream);
 
            memoryStream.Position = 0;
 
            return memoryStream;
        }
	public void upLoadFile(SftpClient _SftpClient, System.IO.Stream _sourceFile, string _fileName)
	{
	    _sourceFile.Position = 0;
	    _SftpClient.BufferSize = 8 * 1024;
	    _SftpClient.UploadFile(_sourceFile, _fileName);
	}
    }
}


X++ Code:

    public void sFTPConnection()
    {	
        str                       	sftpFile;
        ClrObject                 	list = new ClrObject("System.Collections.Generic.List`1[System.String]");
        SFTPConnect.sftpConnection	sftp = new SFTPConnect.sftpConnection();

        using (var sftpConnection = sftp.OpenSFTPConnection(host, port, username, password)) // Connect
        {
            try
            {
                int totalFiles = 0;
				
                sftpConnection.ChangeDirectory('/Upload');//Import Path

                list  = (sftp.GetDirectories(sftpConnection, '/Upload/'));// Files List
ClrObject enumerator = list.getEnumerator(); while (enumerator.movenext()) { totalFiles ++; sftpFile = enumerator.get_Current(); if(sftpFile != ".." && sftpFile !=null && sftpFile != ".") {         System.IO.Stream Stream = sftp.DownloadFile(sftpConnection, '/Upload' + '/'+ sftpFile);
this.ReadCSVFile(Stream,sftpFile); sftp.MoveFile(sftpConnection, 'Import Path'+ '/'+sftpFile, 'destination path'+ '/'+ sftpFile, false); } } }     catch     { throw error(infolog.text());     } finally { if(sftpConnection.IsConnected) sftpConnection.Disconnect(); } } }          public boolean ReadCSVFile(System.IO.Stream stream, str fileName)     { AsciiStreamIo file; container record; file = AsciiStreamIo::constructForRead(stream); if (file) { if (file.status()) {              throw error("@SYS52680"); } file.inFieldDelimiter(','); file.inRecordDelimiter('\r\n'); while (!file.status()) {         record = file.read(); recordCount++; if (conLen(record) && recordCount !=1) {     conPeek(record,2)); } } } return true;
}  


Tested in Console Application:

    To test in the console application we need to add the class library project as a reference.

    We can debug using a console application.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Renci.SshNet;

namespace TestSFTPConnection
{
    class Program
    {
        static void Main(string[] args)
        {
            SFTPTest.SFTPConnect sftp = new SFTPTest.SFTPConnect();

            using (var sftpConnection = sftp.OpenSFTPConnection("Host", 22, "userName", "UserPassword"))
            {
                //try
                {
                    sftpConnection.ChangeDirectory("/uploads");// folder name

                    List<string> list = sftp.GetDirectories(sftpConnection, "/uploads/");
                    List<string>.Enumerator enumerator = list.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        string sftpFile = enumerator.Current;

                        if (sftpFile != ".." && sftpFile != null && sftpFile != ".")
                        {
                            System.IO.Stream Stream = sftp.DownloadFile(sftpConnection, "/uploads" + '/' + sftpFile);
                        }
                    }
                }
            }
        }

    }
}


Reference Link:

https://dynamicsax4u.wordpress.com/2020/08/18/read-files-from-sftp-server-and-write-data-in-ax365-part-2/


Keep Daxing!!

No comments:

Post a Comment