如何初始化从外部服务器下载的文件
How to initialize file download from an external server?
我有一个MVC控制器方法定义如下:
public ActionResult GetPdf(string filename)
{
var pdfDownload = File("~/Content/GeneratedReports/report1.pdf", "application/pdf", Server.UrlEncode("report1.pdf"));
return pdfDownload;
}
如果我将第一个参数更改为托管在单独云服务器上的服务器的url,那么我会得到错误:
"我的文件路径"不是有效的虚拟路径。
我只是希望我的客户能够下载一个文件。这似乎比它需要的要复杂得多
我有一个指向PDF的URL。我想让我的客户在不点击任何东西的情况下下载pdf。(下载将在服务响应成功后启动)
为什么这么难,我该如何解决?
我不在乎解决方案是JS还是MVC。。。。
为什么这么难,我该如何解决?
事实上,这并不难:
public ActionResult GetPdf(string filename)
{
using (var client = new WebClient())
{
var buffer = client.DownloadData("http://foo.com/bar.pdf");
return File(buffer, "application/pdf", "report1.pdf");
}
}
现在很明显,这个方法有一个严重的缺陷,因为它正在内存中缓冲文件。虽然这对小报告很有效,但对大文件可能会有问题,如果有很多用户迫不及待地想要使用这个好报告,问题会更大。
第一个控制器操作还有另一个严重缺陷。它混合了责任。它包含基础结构代码,我要求您单独对其进行单元测试。
因此,让我们通过编写自定义操作结果来解决这两个严重问题:
public class ReportResult : ActionResult
{
private readonly string _filename;
public ReportResult(string filename)
{
_filename = filename;
}
public override void ExecuteResult(ControllerContext context)
{
var cd = new ContentDisposition
{
FileName = _filename,
Inline = false
};
var response = context.HttpContext.Response;
response.ContentType = "application/pdf";
response.Headers["Content-Disposition"] = cd.ToString();
using (var client = new WebClient())
using (var stream = client.OpenRead("http://foo.com/" + _filename))
{
// in .NET 4.0 implementation this will process in chunks
// of 4KB
stream.CopyTo(response.OutputStream);
}
}
}
你会这样使用:
public ActionResult GetPdf(string filename)
{
return new ReportResult(filename);
}
在您看来:
@Html.ActionLink("Download report", "GetPdf", new { filename = "report.pdf" })
或者你可以完全质疑你的控制器动作的有用性,因为在你看来,而不是:
@Html.ActionLink("Download report", "GetPdf")
你可以直接:
<a href="http://foo.com/bar.pdf">Download report</a>
当然,假设客户端可以访问该服务器。
备注:要非常小心您在Content-Disposition
标头中发送的文件名。我在你的问题中看到你使用了类似Server.UrlEncode("report1.pdf")
的东西。看看下面的问题,看看这可能会变成什么样的噩梦。
您只需重定向远程报告中的用户;如果这不是一个选项,你将需要代理它:
byte[] blob;
using(var client = new WebClient()) {
blob = client.DownloadData(remoteUrl);
}
return File(blob, "application/pdf", "report1.pdf");
上述假设文件不是很大;一个更健壮的实现将获取和发送块。
我正在执行类似的例程。现在我有它从本地驱动器访问图像
byte[]cimage=new WebClient().DownLoadData(System.Web.HttpContent.Server.MapPath("~/Content/koala.jpg"));
如何访问SQL Server上的共享。我在SQL Server上的文件夹中有要检索的图像。
byte[]cimage=new WebClient().DownLoadData("服务器共享"+/Files/koala.jpg");
- 如何在生成下载文件时显示加载动画
- 直接下载文件,而不是从window.open(url)
- Javascript运行php文件,然后下载文件
- 在单击href链接的同时下载文件
- 通过javascript下载文件时设置文件名
- HTML锚标记无法在android平台中下载文件
- 链接/按钮从子文件夹下载文件--浏览器只是浏览
- iPhone强制下载文件
- 正在下载文件,同时加载另一个页面
- 如何在node.js中只下载文件的前10 KB
- 如何使用XMLHttpRequest下载文件
- 使用angular js在前端下载文件
- 使用blob从ajax结果下载文件
- 通过Android Chrome浏览器下载文件
- 使用AJAX下载文件.来自SD卡
- 如何使用phonegap从android中的URL下载文件
- 使用ajax下载文件
- 无法使用Angular JS和spring MVC打开下载文件
- 无法使用API-node.js从Google Drive下载文件
- 点击jQuery按钮下载文件