关于.net:如果可能,在C#中使用FtpWebRequest实现不带第三方dll的FTP / SFTP

Achieving FTP/SFTP without 3rd party dll with FtpWebRequest if possible in C#

我正在尝试通过C#中的FtpWebRequest类实现ftp / sftp,但到目前为止没有成功。

我不想使用任何第三方免费或付费dll。

凭证就像

  • 主机名= sftp.xyz.com
  • 用户ID = abc
  • 密码= 123
  • 我能够使用ip地址来实现ftp,但无法通过凭据获得上述主机名的sftp。

    对于sftp,我已将FtpWebRequest类的EnableSsl属性启用为true,但出现错误,无法连接到远程服务器。

    我可以使用相同的凭据和主机名连接Filezilla,但不能通过代码连接。

    我观察到filezilla,它将主机名从sftp.xyz.com更改为sftp://sftp.xyz.com
    在文本框和命令行中,它将用户标识更改为[email protected]

    我已经在代码中做了同样的事情,但没有成功完成sftp。

    请对此进行紧急帮助。提前致谢。

    下面是到目前为止的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    private static void ProcessSFTPFile()
    {
        try
        {
            string[] fileList = null;
            StringBuilder result = new StringBuilder();

            string uri ="ftp://sftp.xyz.com";

            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(uri));
            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
            ftpRequest.EnableSsl = true;
            ftpRequest.Credentials = new NetworkCredential("[email protected]","123");
            ftpRequest.UsePassive = true;
            ftpRequest.Timeout = System.Threading.Timeout.Infinite;

            //ftpRequest.AuthenticationLevel = Security.AuthenticationLevel.MutualAuthRequested;
            //ftpRequest.Proxy = null;
            ftpRequest.KeepAlive = true;
            ftpRequest.UseBinary = true;

            //Hook a callback to verify the remote certificate
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            //ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

            FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
            StreamReader reader = new StreamReader(response.GetResponseStream());
            string line = reader.ReadLine();
            while (line != null)
            {
                result.Append("ftp://sftp.xyz.com" + line);
                result.Append("
    "
    );
                line = reader.ReadLine();
            }

            if (result.Length != 0)
            {
                // to remove the trailing '
    '
                result.Remove(result.ToString().LastIndexOf('

    '), 1);

                // extracting the array of all ftp file paths
                fileList = result.ToString().Split('

    ');
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message.ToString());
            Console.ReadLine();
        }
    }

    public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        if (certificate.Subject.Contains("CN=sftp.xyz.com"))
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    更新:

    如果使用BizTalk,则可以使用ESB工具包使用SFTP适配器。自2010年以来一直受到支持。有人想知道为什么它没有出现在.Net Framework

  • BizTalk Server 2013:以ESB工具包SFTP创建自定义适配器提供程序为例
  • BizTalk Server 2013:如何使用SFTP适配器
  • MSDN文件
  • -

    不幸的是,目前仅与框架有关仍需要大量工作。放置sftp协议前缀不足以构成make-it-work,现在或将来可能仍然没有内置的.Net Framework支持。

    -------------------------------------------------- -------

    1)一个不错的库可以尝试使用SSHNet。

    -------------------------------------------------- -------

    它具有:

  • 还有更多功能,包括内置的流支持。
  • API文档
  • 较简单的API进行编码
  • 文档中的示例代码:

    清单目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /// <summary>
    /// This sample will list the contents of the current directory.
    /// </summary>
    public void ListDirectory()
    {
        string host            ="";
        string username        ="";
        string password        ="";
        string remoteDirectory ="."; // . always refers to the current directory.

        using (var sftp = new SftpClient(host, username, password))
        {
            sftp.Connect();

            var files = sftp.ListDirectory(remoteDirectory);
            foreach (var file in files)
            {
                Console.WriteLine(file.FullName);
            }
        }
    }

    上传文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /// <summary>
    /// This sample will upload a file on your local machine to the remote system.
    /// </summary>
    public void UploadFile()
    {
        string host           ="";
        string username       ="";
        string password       ="";
        string localFileName  ="";
        string remoteFileName = System.IO.Path.GetFileName(localFile);

        using (var sftp = new SftpClient(host, username, password))
        {
            sftp.Connect();

            using (var file = File.OpenRead(localFileName))
            {
                sftp.UploadFile(remoteFileName, file);
            }

            sftp.Disconnect();
        }
    }

    下载文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /// <summary>
    /// This sample will download a file on the remote system to your local machine.
    /// </summary>
    public void DownloadFile()
    {
        string host           ="";
        string username       ="";
        string password       ="";
        string localFileName  = System.IO.Path.GetFileName(localFile);
        string remoteFileName ="";

        using (var sftp = new SftpClient(host, username, password))
        {
            sftp.Connect();

            using (var file = File.OpenWrite(localFileName))
            {
                sftp.DownloadFile(remoteFileName, file);
            }

            sftp.Disconnect();
        }
    }

    -------------------------------------------------- -------

    2)另一个替代库是WinSCP

    -------------------------------------------------- -------

    下面的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    using System;
    using WinSCP;

    class Example
    {
        public static int Main()
        {
            try
            {
                // Setup session options
                SessionOptions sessionOptions = new SessionOptions
                {
                    Protocol = Protocol.Sftp,
                    HostName ="example.com",
                    UserName ="user",
                    Password ="mypassword",
                    SshHostKeyFingerprint ="ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
                };

                using (Session session = new Session())
                {
                    // Connect
                    session.Open(sessionOptions);

                    // Upload files
                    TransferOptions transferOptions = new TransferOptions();
                    transferOptions.TransferMode = TransferMode.Binary;

                    TransferOperationResult transferResult;
                    transferResult = session.PutFiles(@"d:\toupload\*","/home/user/", false, transferOptions);

                    // Throw on any error
                    transferResult.Check();

                    // Print results
                    foreach (TransferEventArgs transfer in transferResult.Transfers)
                    {
                        Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
                    }
                }

                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e);
                return 1;
            }
        }
    }

    在这里找到更多。


    FTP可以仅使用.NET来完成。但是,没有用于SFTP的内置类。我建议您看一下WinSCP。


    同意Tejs。只是澄清一下:

    具有EnableSsl = true的FtpWebRequest表示它是ftps,显式模式,或使用Filezilla措辞:" FTPES-FTP over Explicit TLS / SSL,默认端口21"。您可以使用内置的.net东西进行此操作。

    对于隐式ftp(在Filezilla中用" FTPS-隐式TLS / SSL上的FTP,默认端口990"),您必须使用第3方(例如ftps.codeplex.com)。

    对于sftp(在Filezilla中用" SSH文件传输协议,默认端口22"表示),您还必须使用第三方(例如sshnet.codeplex.com)。

    正如Joachim Isaksson所说,如果您不能使用第三方,则必须自己实施。