System.Net.FtpWebRequest クラスは、.NET Framework 4 と .NET Framework 3.5 では動作が異なります
この記事は、Microsoft .NET Framework 4 のクラスを使用して FTP またはRETR
コマンドをSystem.Net.FtpWebRequest
実行するときに発生する FTP STOR
エラー 5xx を修正するのに役立ちます。
元の製品バージョン: .NET Framework
元の KB 番号: 2134299
現象
.NET Framework 4 の クラスをSystem.Net.FtpWebRequest
使用して FTP STOR
またはRETR
コマンドを実行すると、次のように FTP エラー 5xx がスローされます。
501 構文エラー - 送信者/受信者が見つかりません。
ただし、このクラスは.NET Framework 3.5 では正常に動作し、同じエラーはスローされません。
原因
この問題の原因は、.NET Framework 4 のクラスのSystem.Net.FtpWebRequest
動作の変更によるものです。 プロトコル コマンドの使用をSystem.Net.FtpWebRequest
効率化するために、.NET Framework 3.5 から .NET Framework 4 にクラスがCWD
変更されました。 クラスの System.Net.FtpWebRequest
新しい実装では、ユーザーが要求した実際のコマンドを発行する前に追加 CWD
のコマンドが送信されるのを防ぎ、代わりに要求されたコマンドを直接送信します。 完全に RFC 準拠の FTP サーバーの場合、これは問題になりませんが、完全に RFC に準拠していないサーバーの場合は、これらの種類のエラーが表示されます。
解決方法
この問題を解決するには、コマンドを強制的System.Net.FtpWebRequest
に 2.0 または 3.5 で動作する以前の動作に戻し、実際のコマンドを発行する前に余分なCWD
コマンドを発行.NET Framework必要があります。
クラスのインスタンスが呼び出される前に、次のコードを配置する System.Net.FtpWebRequest
必要があります。
次のコードは、アプリケーション ドメイン全体の設定を変更するため、1 回だけ呼び出す必要があります。
private static void SetMethodRequiresCWD ()
{
Type requestType = typeof (FtpWebRequest);
FieldInfo methodInfoField = requestType.GetField ("m_MethodInfo", BindingFlags.NonPublic | BindingFlags.Instance);
Type methodInfoType = methodInfoField.FieldType;
FieldInfo knownMethodsField = methodInfoType.GetField ("KnownMethodInfo", BindingFlags.Static | BindingFlags.NonPublic);
Array knownMethodsArray = (Array) knownMethodsField.GetValue (null);
FieldInfo flagsField = methodInfoType.GetField ("Flags", BindingFlags.NonPublic | BindingFlags.Instance);
int MustChangeWorkingDirectoryToPath = 0x100;
foreach (object knownMethod in knownMethodsArray)
{
int flags = (int) flagsField.GetValue (knownMethod);
flags |= MustChangeWorkingDirectoryToPath;
flagsField.SetValue (knownMethod, flags);
}
}
FtpWebRequest の動作の変更
クラスの動作は、System.Net.FtpWebRequest
.NET Framework 4 と .NET Framework 3.5 で変更されました。
.NET Framework 3.5 では、 クラスを使用してSystem.Net.FtpWebRequest
サーバーにファイルをアップロードし、次の FTP コマンドの一般的な交換に従いました。
USE
PASS
OPTS
PWD
CWD
STOR
ただし、.NET Framework 4 では、一般的なファイルアップロードでは次のコマンド シーケンスが実行されます。
USER
PASS
OPTS
PWD
STOR
2 つの動作の違いは、3.5 バージョンでは、現在のディレクトリを目的のディレクトリに変更するコマンドを CWD
実行し、ファイル名だけを指定したコマンドを STOR
実行することでアップロードが行われる点です。
ただし、.NET Framework 4 実装では、追加の CWD コマンドの送信を禁止し、完全修飾ディレクトリ構造を使用してコマンドを宛先ディレクトリに直接送信STOR
します。
完全に RFC 準拠の FTP サーバーの場合は問題になりませんが、他の場合、この動作により、既存のアプリケーションが .NET Framework 4 で動作しなくなる可能性があります。
このようなサーバー通信の場合、サーバーは FTP エラー コード 5xx (501 構文エラーなど) で応答します。送信者/受信側が見つからないのに対し、.NET Framework 3.5 で使用すると、同じコードがクラスに対System.Net.FtpWebRequest
して機能します。