Question

J'essaie de faire fonctionner le code suivant:

  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 reconnue. La commande Changer de répertoire est désactivée sur le serveur posant problème et l'administrateur du site m'a dit que .NET lance une commande Changer de répertoire par défaut avec toutes les connexions FTP. Est-ce vrai? Y at-il un moyen de désactiver cela?
EDIT: Lorsque je me connecte à partir d'une ligne de commande, je suis dans le bon répertoire:
ftp > pwd
257 " est le répertoire en cours

Était-ce utile?

La solution

Je viens de tester cela sur l'un de nos serveurs de développement et il existe effectivement un CWD émis par le .NET FtpWebRequest:

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)

C'était sans même spécifier '/' dans l'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 existe une méthode appelée BuildCommandsList () qui est appelée. BuildCommandsList () construit une liste de commandes à envoyer au serveur FTP. Cette méthode contient 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 serveur, m_PreviousServerPath est toujours nul, la valeur de newServerPath est " / " et est calculé par une fonction nommée GetPathAndFileName () (appelée quelques lignes avant ce bloc de code). GetPathAndFileName () calcule newServerPath en tant que " / " si aucun chemin n'est fourni ou si " / " est explicitement cloué à la fin du 'ftp: // ....' uri.

Cela a donc bien sûr pour conséquence d'ajouter la commande CWD au pipeline de commandes, car null! = "/".

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

Autres conseils

Bien que le message date il y a bien longtemps ... peu importe, je vais vous donner la réponse ici.

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

Le % 2f ajouté " est juste un / échappé, ajouter ceci fera que C # traitera le chemin entier comme absolu. Sinon, C # se connectera à ftp: // serveur / avec le nom d'utilisateur, accédera au dossier de base de l'utilisateur, puis cd vers le chemin spécifié, pour que votre chemin devienne chemin_home_utilisateur / chemin , ce qui peut ne pas être souhaitable.

Plus d’informations disponibles sur msdn http://msdn.microsoft.com/en-us/library /system.net.ftpwebrequest.aspx

J'espère que cela vous aidera.

Je pense que nous avons eu un problème similaire il y a quelque temps, je ne me souviens pas des détails exacts cependant.

Pour empêcher .net d’émettre la commande cd, vérifiez si le répertoire par défaut de l’utilisateur auquel vous vous connectez est défini sur le répertoire dans lequel vous souhaitez travailler. Vous pouvez simplement utiliser un client ftp en ligne de commande pour vérifier ceci dehors.

Voici une solution: utilisez gratuitement cette bibliothèque de clients FTP open source pour C # créée par Dan sur C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ ftpclient12062005053849am / ftpclient.aspx

Voici un exemple de code permettant de 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 parfaitement, mais peut également être facilement étendue et modifiée.

En utilisant les informations ci-dessus, cela a fonctionné pour moi.

Envoie CWD - ftpState.ftpRequest = GetRequest (&& ftp://192.168.0.2/tmp/file2download ")

N'envoie pas CWD - ftpState.ftpRequest = GetRequest (& ftp://192.168.0.2//tmp/file2download " ;)     remarquez le // après l'IP du serveur (ou le nom)

DotNET version 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top