Domanda

Sto cercando di far funzionare il seguente codice:

  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;

Funziona normalmente, ma per 1 server particolare questo dà un errore 500: sintassi non riconosciuta. Il comando Cambia directory è disabilitato sul server problematico e l'amministratore del sito mi ha detto che .NET emette un comando Cambia directory per impostazione predefinita con tutte le connessioni FTP. È vero? C'è un modo per disabilitarlo?
EDIT: quando accedo da una riga di comando mi trovo nella directory corretta:
ftp >
pwd 257 "/"; è la directory corrente

È stato utile?

Soluzione

L'ho appena provato su uno dei nostri server di sviluppo e in effetti esiste un CWD rilasciato da .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)

Questo è stato senza nemmeno specificare '/' in uri durante la creazione dell'oggetto FtpWebRequest.

Se esegui il debug o sfogli il codice sorgente, entra in gioco una classe chiamata 'FtpControlStream'. Vedi stack di chiamate:

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#

Esiste un metodo chiamato BuildCommandsList () che viene invocato. BuildCommandsList () crea un elenco di comandi da inviare al server FTP. Questo metodo ha il seguente frammento di codice:

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

Alla prima connessione al server m_PreviousServerPath è sempre null, il valore di newServerPath è " / " ed è calcolato da una funzione chiamata GetPathAndFileName () (invocato alcune righe prima di questo blocco di codice). GetPathAndFileName () calcola newServerPath come " / " se non viene fornito alcun percorso o se " / " è esplicitamente appiccicato alla fine dell'uri "ftp: // ...."

Quindi, ovviamente, ciò alla fine fa sì che il comando CWD venga aggiunto alla pipeline dei comandi perché null! = " / " ;.

Purtroppo, in poche parole, non è possibile ignorare questo comportamento perché è stato masterizzato nel sorgente.

Altri suggerimenti

Anche se il post è come molto tempo fa ... non importa, fornirò la risposta qui.

Invece di usare ftp: // server / percorso come uri, prova ftp: // server /% 2fpath / .

Il % 2f aggiunto " è solo un / con escape, l'aggiunta di questo renderà C # l'intero percorso come assoluto. Altrimenti C # accederà a ftp: // server / con il nome utente, andrà nella cartella home dell'utente, quindi cd nel percorso specificato, in modo che il percorso diventi percorso_utente_utente / percorso , che potrebbe non essere desiderabile.

Ulteriori informazioni sono disponibili su msdn http://msdn.microsoft.com/en-us/library /system.net.ftpwebrequest.aspx

Spero che questo aiuti.

Penso che abbiamo avuto un problema simile qualche tempo fa, ma non ricordo i dettagli esatti.

Per evitare che .net emetta il comando cd, controlla se l'impostazione della directory predefinita per l'utente a cui accedi è impostata sulla directory in cui vuoi lavorare. Puoi semplicemente usare un client ftp a riga di comando per controllare questo fuori.

Ecco una soluzione: usa questa libreria client FTP gratuita e open source per C # creata da Dan su C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ ftpclient12062005053849am / ftpclient.aspx

Ecco un esempio di codice per caricare un file:

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

Questa libreria funziona perfettamente, ma può anche essere facilmente estesa e modificata.

Usando le informazioni sopra, ha funzionato per me.

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

Non invia CWD - ftpState.ftpRequest = GetRequest (" ftp://192.168.0.2//tmp/file2download " ;)     notare // dopo l'IP (o il nome) del server

DotNET versione 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top