如何从外部服务器初始化文件下载?

我有一个MVC控制器方法定义如下:

public ActionResult GetPdf(string filename) { var pdfDownload = File("~/Content/GeneratedReports/report1.pdf", "application/pdf", Server.UrlEncode("report1.pdf")); return pdfDownload; } 

如果我将第一个参数更改为托管在单独的云服务器上的服务器的URL,那么我得到错误:

‘MY FILE PATH’不是有效的虚拟路径。

我只是希望我的客户能够下载文件。 这似乎比它需要的复杂得多。

我有一个指向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") 

你可以直接: