Provide static file download at server in web appl

2020-05-06 11:43发布

问题:

I am working on an MVC 4 web application. On one page I am providing an anchor link which refers to a file on application's directory. The code of the same is -

@Html.Action("Download_Static_File", "Charge_Entry", new { File_Path = "../../Content/Templates/Pt_Data/Pt_Data.xls", File_Name = "Pt_Data_Template", value = "Download template" });

My motive is that the file should be downloaded on click.

However when I click the link, I get an error like

Could not find a part of the path 'C:\Program Files\Common Files\Microsoft Shared\Content\Templates\Pt_Data\Pt_Data.xls'.'

I also tried

System.Web.HttpContext.Current.Server.MapPath

which is giving this error:

OutputStream is not available when a custom TextWriter is used.

The action method being called is:

    public FileResult Download_Static_File(string File_Path,string File_Name)
    {
        byte[] fileBytes = System.IO.File.ReadAllBytes(File_Path);
        return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, File_Name);
    }

Is it the correct approach? Any help will be appreciated.

I also referred this link

回答1:

Your anchor seem to be pointing to a controller action named Download_Static_File (which unfortunately you haven't shown) and passing a parameter called File_Path.

The @Html.Action helper that you are using in your view is attempting to execute the specified action as a child action. You may find the following blog post useful which describes child actions: http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx/

I guess that what you are trying to achieve is to generate an anchor in your view pointing to the static file which can be downloaded by the user. In this case you'd rather use an anchor tag in conjunction with the Url.Action helper:

<a href="@Url.Content("~/Content/Templates/Pt_Data/Pt_Data.xls")">
    Download_Static_File
</a>

This assumes that your web application has a folder called Content/Templates/Pt_Data under the root containing a file named Pt_Data.xls which will be downloaded by the user when he clicks upon this anchor tag.

If on the other hand the file that you want to be downloaded by the user is situated in a folder which is not publicly accessible from the client (for example the ~/App_Data folder) you might in this case have a controller action on your server that will stream the file:

public ActionResult DownloadStaticFile(string filename)
{

    string path = Server.MapPath("~/App_Data");
    string file = Path.Combine(path, filename);
    file = Path.GetFullPath(file);
    if (!file.StartsWith(path))
    {
        throw new HttpException(403, "Forbidden");
    }
    return File(file, "application/pdf");
}

and then in your view you would have an anchor to this controller action:

@Html.ActionLink(
    linkText: "Download template", 
    actionName: "DownloadStaticFile", 
    controllerName: "Charge_Entry", 
    routeValues: new { filename = "Pt_Data.xls" },
    htmlAttributes: null
)