Die System.Net.FtpWebRequest-Klasse verhält sich in .NET Framework 4 und .NET Framework 3.5 unterschiedlich.
Dieser Artikel hilft Ihnen bei der Behebung des FTP-Fehlers 5xx, der auftritt, wenn Sie die System.Net.FtpWebRequest Klasse auf Microsoft .NET Framework 4 zum Ausführen des FTP oder STOR RETR Befehls verwenden.
Ursprüngliche Produktversion: .NET Framework
Ursprüngliche KB-Nummer: 2134299
Problembeschreibung
Wenn Sie die System.Net.FtpWebRequest Klasse auf .NET Framework 4 zum Ausführen des STOR FTP- oder RETR Befehls verwenden, löst die Klasse einen FTP-Fehler 5xx aus, z. B.:
501 Syntaxfehler : Absender/Empfänger fehlt.
Diese Klasse funktioniert jedoch gut mit .NET Framework 3.5 und löst nicht denselben Fehler aus.
Ursache
Die Ursache dieses Problems liegt in einer Verhaltensänderung in der System.Net.FtpWebRequest Klasse in .NET Framework 4. Die Klasse wurde von System.Net.FtpWebRequest .NET Framework 3.5 auf .NET Framework 4 geändert, um die Verwendung der CWD Protokollbefehle zu optimieren. Die neue Implementierung der System.Net.FtpWebRequest Klasse verhindert das Senden CWD zusätzlicher Befehle, bevor der tatsächliche Befehl ausgegeben wird, den der Benutzer angefordert hat, und sendet stattdessen den angeforderten Befehl direkt. Bei vollständig RFC-kompatiblen FTP-Servern sollte dies kein Problem sein. Bei nicht vollständig RFC-kompatiblen Servern werden jedoch diese Fehlertypen angezeigt.
Lösung
Um dieses Problem zu beheben, muss erzwungen werden, dass der System.Net.FtpWebRequest Befehl wieder auf das alte Verhalten zurückgesetzt wird, wie er in .NET Framework 2.0 oder 3.5 verwendet wurde, und den zusätzlichen Befehl auszugeben, bevor der eigentliche Befehl ausgegeben CWD wird.
Der folgende Code sollte platziert werden, bevor eine Instanz der System.Net.FtpWebRequest Klasse aufgerufen wird.
Der folgende Code muss nur einmal aufgerufen werden, da er die Einstellungen der gesamten Anwendungsdomäne ändert.
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);
}
}
Änderungen des FtpWebRequest-Verhaltens
Das Verhalten der System.Net.FtpWebRequest Klasse hat sich in .NET Framework 4 im Vergleich zu .NET Framework 3.5 geändert.
In .NET Framework 3.5 folgt ein Dateiupload auf einen Server mithilfe der System.Net.FtpWebRequest Klasse einem typischen Austausch der folgenden FTP-Befehle:
USEPASSOPTSPWDCWDSTOR
In .NET Framework 4 durchläuft ein typischer Dateiupload jedoch die folgende Befehlssequenz:
USERPASSOPTSPWDSTOR
Der Unterschied zwischen den beiden Verhaltensweisen besteht darin, dass in der Version 3.5 der Upload erfolgt, indem ein Befehl ausgeführt wird, um das aktuelle Verzeichnis in CWD das beabsichtigte Verzeichnis zu ändern, gefolgt vom STOR Befehl mit nur dem Dateinamen.
.NET Framework 4-Implementierung verhindert jedoch das Senden des zusätzlichen CWD-Befehls und sendet den STOR Befehl direkt an das Zielverzeichnis mit der vollqualifizierten Verzeichnisstruktur.
Bei vollständig RFC-kompatiblen FTP-Servern wäre dies kein Problem, aber bei anderen wäre dieses Verhalten möglicherweise ein Fehler bei vorhandenen Anwendungen, die mit .NET Framework 4 arbeiten.
Für eine solche Serverkommunikation wird der Server mit einem FTP-Fehlercode antworten: 5xx, z. B. 501 Syntaxfehler - Absender/Empfänger fehlt, während derselbe Code für die Klasse funktioniert, wenn er System.Net.FtpWebRequest mit dem .NET Framework 3.5 verwendet wird.