首页 > 解决方案 > 如何通过 C# ASP.NET 使用 FTPWebRequest 下载“.xlsx”文件

问题描述

我已经尝试了一切以通过 FTPWebRequest 下载 xlsx 文件——但无济于事。我尝试将文件类型从 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());

标签: c#asp.netdownloadxlsxftpwebrequest

解决方案


您实际上并没有告诉 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);
}

推荐阅读