禁用CD的C#FTP

时间:2008-10-14 14:38:22

标签: c# ftp

我正在尝试使用以下代码:

  string url = String.Format(@"SOMEURL");
  string user = "SOMEUSER";
  string password = "SOMEPASSWORD";

  FtpWebRequest ftpclientRequest = (FtpWebRequest)WebRequest.Create(new Uri(url));
  ftpclientRequest.Method = WebRequestMethods.Ftp.ListDirectory;
  ftpclientRequest.UsePassive = true; 
  ftpclientRequest.Proxy = null;
  ftpclientRequest.Credentials = new NetworkCredential(user, password);
  FtpWebResponse response = ftpclientRequest.GetResponse() as FtpWebResponse;

这通常有效,但对于1个特定服务器,这会产生错误500:语法无法识别。在问题服务器上禁用了“更改目录”命令,并且站点管理员告诉我,.NET默认情况下会发出一个“更改目录”命令,其中包含所有FTP连接。真的吗?有没有办法禁用它?
编辑:当我从命令行登录时,我在正确的目录中:
FTP> PWD
257“/”是当前目录

5 个答案:

答案 0 :(得分:11)

我刚刚在我们的一个开发服务器上测试了这个,确实有一个由.NET FtpWebRequest发布的CWD:

new connection from 172.16.3.210 on 172.16.3.210:21 (Explicit SSL)
hostname resolved : devpc
sending welcome message.
220 Gene6 FTP Server v3.10.0 (Build 2) ready...
USER testuser
testuser, 331 Password required for testuser.
testuser, PASS ****
testuser, logged in as "testuser".
testuser, 230 User testuser logged in.
testuser, OPTS utf8 on
testuser, 501 Please CLNT first.
testuser, PWD
testuser, 257 "/" is current directory.
testuser, CWD /
testuser, change directory '/' -> 'D:\testfolder' --> Access allowed.
testuser, 250 CWD command successful. "/" is current directory.
testuser, TYPE I
testuser, 200 Type set to I.
testuser, PORT 172,16,3,210,4,127
testuser, 200 Port command successful.
testuser, NLST
testuser, 150 Opening data connection for directory list.
testuser, 226 Transfer ok.
testuser, 421 Connection closed, timed out.
testuser, disconnected. (00d00:05:01)

在创建FtpWebRequest对象时,甚至没有在uri中指定'/'。

如果您调试或浏览源代码,则会出现一个名为“FtpControlStream”的类。请参阅调用堆栈:

System.dll!System.Net.FtpControlStream.BuildCommandsList(System.Net.WebRequest req) Line 555    C#
System.dll!System.Net.CommandStream.SubmitRequest(System.Net.WebRequest request = 
    {System.Net.FtpWebRequest}, bool async = false, bool readInitalResponseOnConnect = true) Line 143   C#
System.dll!System.Net.FtpWebRequest.TimedSubmitRequestHelper(bool async) Line 1122 + 0x13 bytes C#
System.dll!System.Net.FtpWebRequest.SubmitRequest(bool async = false) Line 1042 + 0xc bytes C#
System.dll!System.Net.FtpWebRequest.GetResponse() Line 649  C#

有一个名为BuildCommandsList()的方法被调用。 BuildCommandsList()构建一个发送到FTP服务器的命令列表。此方法包含以下代码段:

if (m_PreviousServerPath != newServerPath) { 
    if (!m_IsRootPath
        && m_LoginState == FtpLoginState.LoggedIn
        && m_LoginDirectory != null)
    { 
        newServerPath = m_LoginDirectory+newServerPath;
    } 
    m_NewServerPath = newServerPath; 

    commandList.Add(new PipelineEntry(FormatFtpCommand("CWD", newServerPath), PipelineEntryFlags.UserCommand)); 
}

第一次连接到服务器时,m_PreviousServerPath始终为null,newServerPath的值为“/”,由名为GetPathAndFileName()的函数计算(在此代码块之前调用几行)。如果没有提供路径,或者在'ftp:// ....'uri的末尾显式添加了“/”,则GetPathAndFileName()将newServerPath计算为“/”。

所以这当然最终导致CWD命令被添加到命令管道,因为null!=“/”。

简而言之,遗憾的是,您无法覆盖此行为,因为它已在源代码中被烧毁。

答案 1 :(得分:1)

虽然帖子很久以前......没关系,我会在这里提供答案。

不要使用ftp://server/path作为uri,请尝试ftp://server/%2fpath/

添加的%2f“只是一个转义/,添加这将使C#将整个路径视为绝对路径。 或者C#将使用用户名登录ftp://server/,转到用户的主文件夹,然后按照指定的路径转到指定路径,这样您的路径就会变成user_home_path/path,这可能是不可取的。

更多信息可以在msdn找到 http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

希望这有帮助。

答案 2 :(得分:0)

我认为我们有一段时间有类似的问题,但我不记得确切的细节。

要阻止.net发出cd命令,请查看是否为您要登录的用户设置默认目录,因为设置为您要使用的目录。您可以使用命令行ftp client检查这个。

答案 3 :(得分:0)

这是一个解决方案:在C-SharpCorner.com上使用这个由Dan制作的C#免费开源FTP客户端库: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

以下是上传文件的示例代码:

FtpClient ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword);
ftp.Login();
ftp.Upload(@"C:\image.jpg");
ftp.Close(); 

这个库开箱即用,但也可以轻松扩展和修改。

答案 4 :(得分:0)

使用上面的信息,这对我有用。

发送CWD - ftpState.ftpRequest = GetRequest(“ftp://192.168.0.2/tmp/file2download”)

不发送CWD - ftpState.ftpRequest = GetRequest(“ftp://192.168.0.2//tmp/file2download”)     注意服务器IP(或名称)之后的//

DotNET版本2.0

Private Function GetRequest(ByVal URI As String) As FtpWebRequest
    'create request
    Dim result As FtpWebRequest = CType(FtpWebRequest.Create(URI), FtpWebRequest)
    Return result
End Function