Как загрузить файл .xlsx с помощью FTPWebRequest через C # ASP.NET

Я перепробовал все, чтобы получить файл xlsx для загрузки через FTPWebRequest — безрезультатно. Я пробовал преобразовать тип файла из xlsx в xls и даже в csv, но он просто дает мне файл, полный неразборчивых символов. Все типы файлов загружаются через Chrome, как и ожидалось, без исключений с предоставленным кодом, за исключением файлов xlsx.

Когда я пытаюсь загрузить файл xlsx с помощью этого кода, я получаю следующую ошибку от excel: «Мы обнаружили проблему с некоторым содержимым в ‘filename.xlsx’. Вы хотите, чтобы мы восстановили столько, сколько мы можем? Если вы доверяете источник этой книги, нажмите «Да» ». После нажатия «Да» появилось сообщение «Microsoft Excel пытается открыть и восстановить файл. Чтобы снова запустить этот процесс, выберите« Открыть и восстановить »в диалоговом окне« Открыть файл ». Выполнение этих инструкций создает бесконечный цикл одних и тех же сообщений.

Любая помощь по этому поводу была бы замечательной! Кроме того, я попытался изменить тип содержимого на «application / vnd.openxmlformats-officedocument.spreadsheetml.sheet» и «application / vnd.ms-excel», и ни один из них не работает.

string ftpfilename = "ftp://ftpserverinfo/randomfilename.xlsx";                                
string filename = "randomfilename.xlsx";

FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpfilename));
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = new NetworkCredential(username, password);
request.UseBinary = true;
request.KeepAlive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
byte[] bytes = new byte[2048];
int i = 0;
MemoryStream mStream = new MemoryStream();
do { i = stream.Read(bytes, 0, bytes.Length); mStream.Write(bytes, 0, i); } while (i != 0);
context.Response.Clear();
context.Response.ClearHeaders();
context.Response.ClearContent();
context.Response.ContentType = MimeMapping.GetMimeMapping(filename);
context.Response.AddHeader("content-disposition", @"attachment;filename=" + filename);
context.Response.BinaryWrite(mStream.GetBuffer());

См. также:  Snakemake - правило загрузки данных
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. aspnet123

    Фактически вы не говорите FtpWebRequest, какой файл загружать, ftpfilename содержит только URL-адрес FTP-сервера. Попробуйте изменить эту строку:

    FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpfilename));
    

    To:

    var requestUri = new Uri(ftpfilename + filename);
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(requestUri);
    

    Я бы предложил выделить ваш код FtpWebRequest в отдельный метод с подписью типа public byte[] FtpDownloadBinary(Uri fromUri), который вы можете реализовать и протестировать отдельно, затем вы можете передать результат этого метода в context.Response.BinaryWrite(fileBytes);

    == редактировать ==

    Вот пример метода, с помощью которого FTP загружает заданный двоичный URL:

    string username = "anonymous";
    string password = "[email protected]";
    
    public byte[] FtpDownloadBinary(Uri fromUri)
    {
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create(fromUri);
        request.Method = WebRequestMethods.Ftp.DownloadFile;
        request.Credentials = new NetworkCredential(username, password);
        request.UseBinary = true;
        request.KeepAlive = true;
    
        FtpWebResponse response = (FtpWebResponse)request.GetResponse();
        using (var responseStream = response.GetResponseStream())
        using (var memoryStream = new MemoryStream())
        {
            responseStream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }
    }
    

    Вы можете проверить, что это работает, сохранив результат в локальном файле в вашей системе с помощью чего-то вроде кода ниже, получившийся файл можно открыть с помощью 7-Zip, WinRAR, WinZip и т. Д .:

    string ftpfilename = "ftp://ftp.ubuntu.com/ubuntu/ls-lR.gz"; //1.7MB example
    var requestUri = new Uri(ftpfilename);
    var fileBytes = FtpDownloadBinary(requestUri);
    
    using (var fileStream = new FileStream("ls-lR.gz", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
    {
        fileStream.Write(fileBytes, 0, fileBytes.Length);
    }
    

    Извините, я не включил фактическое имя файла в строку ftpfilename … Однако оно присутствует в моем фактическом коде. И спасибо за ваше предложение, я попробую это, но указанный мной код корректно работает для меня со всеми другими типами файлов, кроме xlsx. person aspnet123; 28.07.2019

    По-прежнему не работает с файлами excel xlsx. Я могу без проблем загружать эти файлы прямо с ftp-сервера, что говорит мне о том, что сами файлы не повреждены. Это просто фактическая загрузка с использованием этого метода по какой-то причине повреждает файл. person aspnet123; 28.07.2019

    Файлы XLSX не являются чем-то особенным, по сути, это серия файлов XML, упакованных в архив .zip. Вы можете убедиться в этом сами, переименовав один из Foo.xlsx в Foo.zip и открыв его в 7-Zip, WinRAR или WinZip, или даже просто просмотрев его содержимое с помощью современного проводника Windows. Боюсь, у меня нет никаких дополнительных предложений для вас, кроме вероятности того, что FTP-клиент Microsoft .NET может быть несовместим с вашим FTP-сервером. Возможно, вам придется попробовать альтернативную библиотеку FTP, например библиотеку автоматизации WinSCP .NET. person aspnet123; 28.07.2019

    @ aspnet123 На самом деле, у меня возникла еще одна мысль … До того, как request.GetResponse() вы могли добавить request.UsePassive = true; Это побудит FTP-клиент использовать режим PASV для передачи, который может быть необходим для вашего конкретного FTP-сервера. person aspnet123; 28.07.2019

    Спасибо за вашу помощь, но все равно не повезло. Однако я смотрю на размер загруженного файла по сравнению с фактическим размером файла, а размер загруженного файла почти вдвое больше. Может ли это быть проблемой? И если да, есть ли у вас идеи, как это исправить? person aspnet123; 28.07.2019

    Определенно проблема, хотя я не знаю, что может быть причиной этого. Если бы он был на 33% больше, чем должен был бы, я бы заподозрил, что применена кодировка base64 — она ​​берет каждые 3 двоичных байта и преобразует их в 4 символа из словаря base64, тем самым расширяя поток на 33%. Но я не знаю, что могло бы увеличить его размер вдвое. person aspnet123; 29.07.2019

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: