如果可能,在 C# 中使用 FtpWebRequest 在没有 3rd 方 dll 的情况下实现 FTP/SFTP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10657377/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:41:55  来源:igfitidea点击:

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

c#.netwinforms

提问by pan4321

I am trying to achieve the ftp/sftp through FtpWebRequest class in C# but not succeeded till now.

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

I dont want to use any 3rd party free or paid dll.

我不想使用任何 3rd 方免费或付费的 dll。

credentials are like

凭据就像

  1. hostname = sftp.xyz.com
  2. userid = abc
  3. password = 123
  1. 主机名 = sftp.xyz.com
  2. 用户 ID = abc
  3. 密码 = 123

I am able to achieve the ftp with Ip address but unable to acheive sftp for above hostname with credentials.

我能够使用 Ip 地址实现 ftp,但无法使用凭据实现上述主机名的 sftp。

For sftp I have enabled the EnableSsl property of FtpWebRequest class to true but getting error unable to connect to remote server.

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

I am able to connect with Filezilla with the same credentials and hostname but not through code.

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

I observed filezilla, it changes the host name from sftp.xyz.com to sftp://sftp.xyz.com in textbox and in command line it changes the userid to [email protected]

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

I have done the same in code but not succeeded for sftp.

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

Please need urgent help on this. Thanks in advance.

请在这方面需要紧急帮助。提前致谢。

Below is my code so far:

以下是我到目前为止的代码:

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("\n");
            line = reader.ReadLine();
        }

        if (result.Length != 0)
        {
            // to remove the trailing '\n'
            result.Remove(result.ToString().LastIndexOf('\n'), 1);

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

    }
    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;
    }
}

回答by Tejs

FTP can be accomplished with .NET alone. There is no built in class for SFTP though. I would recommend taking a look at WinSCP.

FTP 可以单独使用 .NET 来完成。不过,SFTP 没有内置类。我建议看看WinSCP

回答by Thierry_S

Agreed with Tejs. Just to clarify:

同意 Tejs。只是为了澄清:

FtpWebRequest with EnableSsl = true means it's ftps, Explicit mode, or in Filezilla wording: "FTPES - FTP over Explicit TLS/SSL, default port 21". You can do this with the built-in .net stuff.

带有 EnableSsl = true 的 FtpWebRequest 表示它是 ftps,显式模式,或在 Filezilla 中的措辞:“FTPES - FTP over Explicit TLS/SSL,默认端口 21”。你可以用内置的 .net 东西来做到这一点。

For Implicit ftps (in Filezilla wording "FTPS - FTP over Implicit TLS/SSL, default port 990") you have to use a 3rd party (example ftps.codeplex.com).

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

For sftp (in Filezilla wording "SSH File Transfer Protocol, default port 22") you also have to use 3rd party (example sshnet.codeplex.com).

对于 sftp(在 Filezilla 中,“SSH 文件传输协议,默认端口 22”)您还必须使用 3rd 方(例如 sshnet.codeplex.com)。

As Joachim Isaksson says, if you can't use 3rd parties, you have to implement it yourself.

正如 Joachim Isaksson 所说,如果你不能使用 3rd 方,你必须自己实现它。

回答by user919426

UPDATE:

更新:

If using BizTalk, you can work with the SFTP Adapter, using the ESB Toolkit. It has been supported since 2010. One wonders why it didn't make it to the .Net Framework

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

  1. BizTalk Server 2013: Creating Custom Adapter Provider in ESB Toolkit SFTP As an Example
  2. BizTalk Server 2013: How to use SFTP Adapter
  3. MSDN Docs
  1. BizTalk Server 2013:在 ESB Toolkit SFTP 中创建自定义适配器提供程序作为示例
  2. BizTalk Server 2013:如何使用 SFTP 适配器
  3. MSDN 文档

--

——

Unfortunately, it still requires alot of work to do with just the Framework currently. Placing the sftpprotocol prefix isnt enough to make-it-workStill no built-in, .Net Framework support today, maybe in the future.

不幸的是,目前它仍然需要大量的工作来处理框架。放置sftp协议前缀是不够的make-it-work今天仍然没有内置的 .Net Framework 支持,也许在未来。

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

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

1) A good library to try out is SSHNet.

1) 一个值得尝试的好库是SSHNet

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

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

It has:

它有:

  1. a lot more features, including built-in streaming support.
  2. an API document
  3. a simpler API to code against
  1. 更多功能,包括内置流媒体支持。
  2. API 文档
  3. 一个更简单的 API 来编码

Example code from documentation:

文档中的示例代码:

List directory

列出目录

/// <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);
        }
    }
}

Upload File

上传文件

/// <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();
    }
}

Download File

下载文件

/// <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) Another alternative library is WinSCP

2) 另一个替代库是WinSCP

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

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

With the follwing example:

使用以下示例:

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;
        }
    }
}

Found hereand with more here.

在这里找到更多在这里找到