質問

次のコードを機能させようとしています:

  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;

これは通常は機能しますが、特定のサーバーの場合、エラー500:構文が認識されません。問題のあるサーバーでは[ディレクトリの変更]コマンドが無効になっており、サイト管理者は、.NETがすべてのFTP接続でデフォルトで[ディレクトリの変更]コマンドを発行することを教えてくれました。本当?それを無効にする方法はありますか?
編集:コマンドラインからログインすると、正しいディレクトリに移動します:
ftp> pwd
257" /"現在のディレクトリです

役に立ちましたか?

解決

開発サーバーの1つでこれをテストしたところ、実際に.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()という名前の関数によって計算されます(このコードブロックの前に数行呼び出されます)。 GetPathAndFileName()は、newServerPathを" /"として計算しますパスが指定されていない場合、または" /" 「ftp:// ....」uriの末尾に明示的に追加されます。

したがって、当然、これは最終的にnull!=" /"であるため、コマンドパイプラインにCWDコマンドが追加されます。

一言で言えば、この動作はソースで焼き付けられているため、残念ながらオーバーライドできません。

他のヒント

この投稿は昔のようなものですが、気にしないで、ここで答えを提供します。

uriとして ftp:// server / path を使用する代わりに、 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

これがお役に立てば幸いです。

以前にも同様の問題があったと思いますが、正確な詳細は覚えていません。

.netがcdコマンドを発行しないようにするには、ログインするユーザーのデフォルトディレクトリが作業するディレクトリに設定されているかどうかを確認します。コマンドラインftpクライアントを使用して確認するだけです。これ。

解決策は次のとおりです。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(); 

このライブラリはそのまま使用できますが、簡単に拡張および変更できます。

上記の情報を使用して、これは私のために働いた。

CWDを送信- ftpState.ftpRequest = GetRequest(" ftp://192.168.0.2/tmp/file2download ")

CWDを送信しません- ftpState.ftpRequest = GetRequest(" ftp://192.168.0.2//tmp/file2download &quot ;)     //サーバー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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top