I have an MVC controller method defined like this:
public ActionResult GetPdf(string filename)
{
var pdfDownload = File("~/Content/GeneratedReports/report1.pdf", "application/pdf", Server.UrlEncode("report1.pdf"));
return pdfDownload;
}
If i change the first parameter to the url of a server hosted on a separate cloud server then I get the error :
‘MY FILE PATH’ is not a valid virtual path.
I just want my client to be able to download a file. This seems so much more complex than it need be.
I have a URL that points to a PDF. I want my client to download that pdf without clicking anything. (The download will initiate upon successful service response)
Why is this so hard and how do i solve it ?
I don’t care if the solution is in JS or MVC….
Actually, it’s not that hard:
Now obviously there’s a serious flaw with this method as it is buferring the file in memory. While this could work great for small reports, it could be problematic with large files and even more problematic if you have lots of users impatient to put their hands on this great report.
There’s also another serious flaw with the first controller action. It mixes responsibilities. It contains infrastructure code and I challenge you to unit test it in isolation.
So let’s solve those 2 serious problems by writing a custom action result:
that you will use like this:
and in your view:
Or you could totally question the usefulness of your controller action because in your view instead of:
you could have directly:
assuming the client has access to this server of course.
Remark: be very careful with the filenames you are sending in the
Content-Dispositionheader. I see in your question that you used something likeServer.UrlEncode("report1.pdf"). Checkout the following question for the nightmare that this could turn into.