Why is it so complicated and how do I solve it?
Actually, this is not so difficult:
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"); } }
Now, obviously, there is a serious flaw in this method, since it loads the file into memory. Although this may work fine for small reports, it can be problematic with large files and even more problematic if you have many users eager to put their hand in this excellent report.
There is also another serious flaw with the first controller action. He mixes duties. It contains infrastructure code, and I suggest you unit test isolate it.
So, let me solve these two serious problems by writing the result of a custom action:
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)) {
what you will use like this:
public ActionResult GetPdf(string filename) { return new ReportResult(filename); }
and in your opinion:
@Html.ActionLink("Download report", "GetPdf", new { filename = "report.pdf" })
Or you can completely ask about the usefulness of the actions of your controller, because in your view, instead of:
@Html.ActionLink("Download report", "GetPdf")
you could directly:
<a href="http://foo.com/bar.pdf">Download report</a>
assuming the client has access to this server, of course.
Note: be very careful with the file names that you send in the Content-Disposition header. I see in your question that you used something like Server.UrlEncode("report1.pdf") . Draw up the following question for a nightmare that might turn into.