2008-10-14 7 views
6

Je suis en train de faire fonctionner le code suivant:C# FTP avec CD désactivé

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; 

Cela fonctionne normalement, mais pour 1 serveur particulier cela donne une erreur 500: Syntaxe non reconnu. La commande Change Directory est désactivée sur le serveur à problèmes et l'administrateur du site m'a indiqué que .NET émet une commande Change Directory par défaut avec toutes les connexions FTP. Est-ce vrai? Y a-t-il un moyen de désactiver cela?
EDIT: Lorsque je me connecte à partir d'une ligne de commande que je suis dans le bon répertoire:
ftp> pwd
257 «/» est le répertoire courant

Répondre

11

Je viens de tester cela sur un de nos serveurs dev et même il y a une encéphalopathie des cervidés émis par le FtpWebRequest .NET:

 
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) 

Ce fut sans même préciser «/» dans le uri lors de la création de l'objet FtpWebRequest .

Si vous déboguez ou parcourez le code source, une classe appelée 'FtpControlStream' entre en jeu. Voir la pile d'appels:

 
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# 

Il y a une méthode nommée BuildCommandsList() qui est invoquée. BuildCommandsList() construit une liste de commandes à envoyer au serveur FTP. Cette méthode a l'extrait de code suivant:

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)); 
} 

Lors de la première connexion au m_PreviousServerPath du serveur est toujours nulle, la valeur de newServerPath est «/» et est calculée par une fonction nommée GetPathAndFileName() (invoqué quelques lignes antérieures à ce bloc de code). GetPathAndFileName() calcule newServerPath en tant que "/" si aucun chemin n'est fourni ou si "/" est explicitement ajouté à la fin de l'uri 'ftp: // ....'. Par conséquent, cela finit par entraîner l'ajout de la commande CWD au pipeline de commandes, car null! = "/".

En résumé, vous ne pouvez pas remplacer ce comportement car il est gravé dans la source.

0

Je pense que nous avons eu un problème similaire un certain temps, je ne » Je me souviens des détails exacts. Pour empêcher l'exécution de la commande cd par .net, voir si vous définissez le répertoire par défaut de l'utilisateur auquel vous vous connectez comme défini dans le répertoire dans lequel vous voulez travailler. Vous pouvez simplement utiliser un client ftp en ligne de commande pour regarde ça.

0

Voici une solution: utiliser cette libre, open source, FTP Client Library pour C# faite par Dan à C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

Voici quelques exemples de code pour télécharger un fichier:

FtpClient ftp = new FtpClient(FtpServer,FtpUserName,FtpPassword); 
ftp.Login(); 
ftp.Upload(@"C:\image.jpg"); 
ftp.Close(); 

Cette bibliothèque fonctionne correctement, mais elle peut également être facilement étendue et modifiée.

1

Bien que le poste est comme il ya longtemps ... peu importe, je vais fournir la réponse ici.

Au lieu d'utiliser ftp://server/path comme uri, essayez ftp://server/%2fpath/.

Le ajouté %2f "est juste un échappèrent /, ajoutant cela fera # C traiter tout le chemin absolu. Ou bien C# se connecter à ftp://server/ avec le nom d'utilisateur, allez dans le dossier de l'utilisateur, puis cd à votre spécifiée chemin, de sorte que votre chemin devienne user_home_path/path, ce qui peut ne pas être souhaitable.

Plus d'informations n'a pu être trouvée à msdn http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

Hope this helps.

0

En utilisant l'info ci-dessus, cela a fonctionné pour moi.

Transmet l'encéphalopathie des cervidés - ftpState.ftpRequest = GetRequest ("ftp://192.168.0.2/tmp/file2download ")

Ne pas envoyer l'encéphalopathie des cervidés - ftpState.ftpRequest = GetRequest (" ftp://192.168.0.2//tmp/file2download") avis // l'après l'adresse IP du serveur (ou nom)

version 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