2008-10-14 60 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