Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to download file with MVC4/Razor

I have a MVC-application. And I want to download a pdf.

This is a part of my view:

<p>
    <span class="label">Information:</span>
    @using (Html.BeginForm("DownloadFile")) { <input type="submit" value="Download"/> }
</p>

And this is a part of my controller:

private string FDir_AppData = "~/App_Data/";

public ActionResult DownloadFile()
{
    var sDocument = Server.MapPath(FDir_AppData + "MyFile.pdf");

    if (!sDocument.StartsWith(FDir_AppData))
    {
        // Ensure that we are serving file only inside the App_Data folder
        // and block requests outside like "../web.config"
        throw new HttpException(403, "Forbidden");
    }

    if (!System.IO.File.Exists(sDocument))
    {
        return HttpNotFound();
    }

    return File(sDocument, "application/pdf", Server.UrlEncode(sDocument));
}

How can I download the specific file?

like image 742
user1531040 Avatar asked Sep 01 '14 22:09

user1531040


People also ask

How to download a file in MVC?

Go to File->New->Project. Give FileUploadDownload as project name or give a suitable name to the application. Click OK. Now, select MVC as a template and then click OK.

What is Razor syntax in MVC?

Razor is a markup syntax that lets you embed server-based code into web pages using C# and VB.Net. It is not a programming language. It is a server side markup language. Razor has no ties to ASP.NET MVC because Razor is a general-purpose templating engine. You can use it anywhere to generate output like HTML.


2 Answers

Possible solution - provide form method and controller name:

@using (Html.BeginForm("DownloadFile", "Controller", FormMethod.Get))
        { <input type="submit" value="Download" /> }

or try to use action link instead of form:

@Html.ActionLink("Download", "DownloadFile", "Controller")

or try to provide direct url to the file:

<a href="~/App_Data/MyFile.pdf">Download</>

This isn't the best practice because of security reasons, but still you can try... Also, You can wrap file location to some @Html helper method:

public static class HtmlExtensions {
    private const string FDir_AppData = "~/App_Data/";

    public static MvcHtmlString File(this HtmlHelper helper, string name){
        return MvcHtmlString.Create(Path.Combine(FDir_AppData, name));
    }
}

And in the view:

<a href="@Html.File("MyFile.pdf")">Download</>
like image 184
Dmytro Avatar answered Sep 30 '22 10:09

Dmytro


Change the DownloadFile Action signature from:

 public ActionResult DownloadFile()

To:

 public FileResult DownloadFile()

In addition, I think that the UrlEncode of the file path is redundant, change it to:

return File(sDocument, "application/pdf", sDocument);

And make sure that this path does physically exist.

like image 20
Yair Nevet Avatar answered Sep 30 '22 11:09

Yair Nevet