2008-10-14 15 views
6

Estoy intentando conseguir el siguiente código de trabajo:C# FTP con movilidad reducida CD

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; 

Esto normalmente funciona, pero para 1 servidor particular, esto da un error 500: Sintaxis no se reconoce. El comando Cambiar directorio está deshabilitado en el servidor problemático, y el administrador del sitio me dijo que .NET emite un comando Cambiar directorio de forma predeterminada con todas las conexiones FTP. ¿Es eso cierto? ¿Hay alguna forma de desactivar eso?
EDIT: Cuando me conecto desde una línea de comandos que estoy en el directorio correcto:
ftp> pwd
257 "/" es el directorio actual

Respuesta

11

Acabo de probar esto en uno de nuestros servidores dev y de hecho hay una caquexia crónica emitido por el .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) 

Este fue sin siquiera especificar '/' en el URI al crear el objeto FtpWebRequest .

Si depura o explora el código fuente, entra en juego una clase llamada 'FtpControlStream'. Ver la pila de llamadas:

 
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# 

Hay un método llamado BuildCommandsList() que se invoca. BuildCommandsList() crea una lista de comandos para enviar al servidor FTP. Este método tiene el siguiente fragmento de código:

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

Tras la primera conexión a la m_PreviousServerPath servidor siempre es nulo, el valor de newServerPath es "/" y se calcula mediante una función llamada GetPathAndFileName() (invocado unos pocos líneas antes de este bloque de código). GetPathAndFileName() calcula newServerPath como "/" si no se proporciona ninguna ruta o si "/" está explícitamente añadido al final de la URL 'ftp: // ....'.

Por lo tanto, esto hace que, por supuesto, el comando CWD se agregue a la canalización de comandos porque null! = "/".

En pocas palabras, desafortunadamente no puede anular este comportamiento porque está grabado en la fuente.

0

Creo que hemos tenido un problema similar hace un tiempo, yo no' Sin embargo, recuerdo los detalles exactos.

Para evitar que .net emita el comando cd, consulte si establece el directorio predeterminado para el usuario en el que inicia sesión, como se establece en el directorio en el que desea trabajar. Puede usar un cliente ftp de línea de comando para mira esto.

0

Aquí es una solución: utilizar esta fuente libre, abierto, FTP Client Library para C# realizado por Dan en C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

Aquí hay un código de ejemplo para cargar un archivo:

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

Esta biblioteca funciona perfectamente, pero también puede ampliarse y modificarse fácilmente.

1

Aunque la publicación es como hace mucho tiempo ... no importa, le daré la respuesta aquí.

En lugar de usar ftp://server/path como uri, intente ftp://server/%2fpath/.

El añadió %2f "es sólo una escaparon /, añadiendo que esto hará que C# tratan a toda la ruta absoluta. O bien C# será la cuenta para ftp://server/ con el nombre de usuario, vaya a la carpeta de inicio del usuario, a continuación, cd para su especificada camino, por lo que su trayectoria se convierten en user_home_path/path, que puede no ser deseable.

Más información se podría encontrar en MSDN http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

Espero que esto ayude.

0

Usando la información anterior, esto funcionó para mí.

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

No envía CWD - ftpState.ftpRequest = GetRequest (" ftp://192.168.0.2//tmp/file2download") aviso de la // después de la IP del servidor (o el nombre)

versión 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