Pergunta

Eu estou tentando obter o seguinte trabalho código:

  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;

Isto normalmente funciona, mas para um servidor em particular o que dá um erro 500: Sintaxe não reconhecido. O comando Change Directory está desabilitada no servidor problema, e o administrador do site me disse que as questões .NET um comando Change Directory por padrão com todas as conexões FTP. Isso é verdade? Existe uma maneira de desativar isso?
EDIT: Quando eu iniciar sessão a partir de uma linha de comando Eu estou no diretório correto:
ftp> pwd
257 "/" é o diretório atual

Foi útil?

Solução

Eu só testei isso em um dos nossos servidores dev e de fato há um CWD emitida pela 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 foi, mesmo sem especificar '/' na URI ao criar o objeto FtpWebRequest.

Se você depurar ou procure o código-fonte, uma classe chamada 'FtpControlStream' entra em jogo. Veja pilha de chamadas:

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#

Há um método chamado BuildCommandsList () que é invocado. BuildCommandsList () cria uma lista de comandos para enviar para o servidor FTP. Este método tem o seguinte trecho 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)); 
}

Após a primeira conexão com o servidor m_PreviousServerPath é sempre nulo, o valor de newServerPath é "/" e é calculado por uma função chamada GetPathAndFileName () (chamado algumas linhas anteriores a este bloco de código). GetPathAndFileName () calcula newServerPath como "/" se nenhum caminho for informado ou se "/" é explicitamente anexados ao final da. 'Ftp: // ....' uri

Então, isso, claro, em última análise, faz com que o comando CWD a ser adicionado ao pipeline de comando porque nula! = "/".

Em poucas palavras, infelizmente, você não pode substituir esse comportamento porque ele é queimado na fonte.

Outras dicas

Embora o post é como há muito tempo ... não importa, eu vou dar a resposta aqui.

Em vez de usar ftp://server/path como o uri, ftp://server/%2fpath/ tentativa.

O %2f acrescentado" é apenas um / escapou, adicionando isso vai fazer C # tratar o caminho inteiro como absoluto. Ou então C # irá login para ftp://server/ com o nome de usuário, vá para a pasta pessoal do usuário, depois mude para o caminho especificado, para que o seu caminho se tornar user_home_path/path, que pode não ser desejável.

Mais informações podem ser encontradas no MSDN http://msdn.microsoft.com/en-us/library /system.net.ftpwebrequest.aspx

Espero que isso ajude.

Eu acho que nós tivemos um problema de um semelhantes tempo atrás, eu não me lembro os detalhes exatos embora.

Para evitar .net de emitir o comando cd, ver se definir o diretório padrão para o usuário que você está de login em como está definido para o diretório que você deseja trabalhar. Você pode apenas usar um cliente de linha de comando ftp para verificação isto.

Aqui está uma solução: usar este, livre de código aberto, FTP Client Library para C # feito por Dan em C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ ftpclient12062005053849am / ftpclient.aspx

Aqui está um exemplo de código para fazer upload de um arquivo:

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

Esta biblioteca funciona bem fora da caixa, mas também pode ser facilmente estendido e modificado.

Usando a informação acima, isso funcionou para mim.

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

Não envia CWD - ftpState.ftpRequest = GetRequest ( " ftp://192.168.0.2//tmp/file2download ") notar a // após o IP do servidor (ou nome)

DotNET versão 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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top