C# FTP с отключенным компакт-диском

Я пытаюсь заставить работать следующий код:

  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;

Обычно это работает, но для 1 конкретного сервера выдается ошибка 500: синтаксис не распознается. Команда «Изменить каталог» отключена на проблемном сервере, и администратор сайта сказал мне, что .NET выдает команду «Изменить каталог» по умолчанию для всех FTP-подключений. Это правда? Есть ли способ отключить это?
EDIT: когда я вхожу в систему из командной строки, я нахожусь в правильном каталоге:
ftp> pwd
257 "/" - текущий каталог

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
5 346
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я думаю, что у нас была похожая проблема некоторое время назад, хотя я не помню точных деталей.

Чтобы запретить .net запускать команду cd, проверьте, установлен ли каталог по умолчанию для пользователя, в который вы входите, как каталог, в котором вы хотите работать. Вы можете просто использовать ftp-клиент командной строки, чтобы проверить это.

Ответ принят как подходящий

Я только что протестировал это на одном из наших серверов разработки, и действительно, .NET FtpWebRequest выпускает CWD:

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)

Это было без указания символа «/» в uri при создании объекта FtpWebRequest.

Если вы отлаживаете или просматриваете исходный код, в игру вступает класс под названием «FtpControlStream». См. Стек вызовов:

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#

Вызывается метод BuildCommandsList (). BuildCommandsList () создает список команд для отправки на FTP-сервер. Этот метод имеет следующий фрагмент кода:

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

При первом подключении к серверу m_PreviousServerPath всегда имеет значение null, значение newServerPath равно «/» и вычисляется функцией с именем GetPathAndFileName () (вызывается за несколько строк до этого блока кода). GetPathAndFileName () вычисляет newServerPath как "/", если путь не указан или если "/" явно добавлен в конец uri 'ftp: // ....'.

Так что это, конечно, в конечном итоге приводит к добавлению команды CWD в командный конвейер, потому что null! = "/".

Вкратце, к сожалению, вы не можете изменить это поведение, потому что оно записано в исходном коде.

Вот решение: используйте эту бесплатную клиентскую библиотеку FTP с открытым исходным кодом для C#, созданную Дэном на C-SharpCorner.com: http://www.c-sharpcorner.com/uploadfile/danglass/ftpclient12062005053849am/ftpclient.aspx

Вот пример кода для загрузки файла:

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

Эта библиотека отлично работает "из коробки", но ее также можно легко расширить и изменить.

Хотя пост вроде как давным-давно ... неважно, я дам ответ здесь.

Вместо использования ftp://server/path в качестве URI попробуйте ftp://server/%2fpath/.

Добавленный %2f "- это просто экранированный /, добавление которого заставит C# рассматривать весь путь как абсолютный. В противном случае C# войдет в ftp://server/ с именем пользователя, перейдет в домашнюю папку пользователя, затем cd по указанному пути, так что ваш путь станет user_home_path/path, что может быть нежелательно.

Более подробную информацию можно найти на msdn http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx

Надеюсь это поможет.

Используя информацию выше, у меня это сработало.

Отправляет CWD - ftpState.ftpRequest = GetRequest ("ftp://192.168.0.2/tmp/file2download")

Не отправляет CWD - ftpState.ftpRequest = GetRequest ("ftp://192.168.0.2//tmp/file2download") обратите внимание на // после IP-адреса сервера (или имени)

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

Другие вопросы по теме