如何通过 C# 使用 FTPWebRequest 下载“.xlsx”文件 ASP.NET

How to download ".xlsx" file using FTPWebRequest through C# ASP.NET

我已经尝试了所有方法来通过 FTPWebRequest 下载 xlsx 文件——但无济于事。我试过将文件类型从 xlsx 转换为 xls,甚至转换为 csv,但它只是给我一个充满无法辨认符号的文件。所有文件类型都按预期通过 Chrome 下载,提供的代码没有例外,xlsx 文件除外。

当我尝试使用此代码下载 xlsx 文件时,excel 出现以下错误:"We found a problem with some content in 'filename.xlsx'. Do you want us to recover as much as we can? If you trust the source of this workbook, click 'Yes'." 单击 'Yes' 后,消息 "Microsoft Excel was attempting to open and repair the file. To start this process again, choose Open and Repair from the Open file dialog."继续执行这些指令只会造成相同消息的无限循环。

如果对此有任何帮助,那就太好了!另外,我尝试将内容类型更改为 "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());

您实际上并没有告诉 FtpWebRequest 要下载哪个文件,ftpfilename 只包含 FTP 服务器 URL。尝试修改此行:

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

收件人:

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 = "anonymous@example.org";

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