2008-10-14 62 views
6

我试图让下面的代码工作:C#FTP与CD残疾人

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“/”是当前目录

回答

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第一连接总是空,newServerPath的值是“/”和由名为GetPathAndFileName函数来计算()(调用几此代码块之前的行)。如果未提供路径,或者在“ftp:// ....'uri”末尾明确指定了“/”,则GetPathAndFileName()会将newServerPath计算为“/”。

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

简而言之,不幸的是,您不能重写此行为,因为它在源代码中被烧毁。

0

我认为我们也有类似的问题了一段时间回来,我不但请记住确切的细节。

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

1

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

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

增加的%2f“只是一个转义/,加入这将使C#处理整个路径作为绝对的。 否则C#将登录到ftp://server/的用户名,进入用户的主文件夹,然后cd到您指定路径,所以你的路径变得user_home_path/path,这可能不是理想的。

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

希望这有助于。

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