0

I have a directory C:\Source\SomeDirectory\ that has any number of .pdf and .txt files. I need to display these files on my ASP.NET web page and have each one of them be downloadable links e.g.:

downloadable links

Where each one of these is either a .pdf or .txt.

How can I create links for every single one of these files? I know they will all be in the same directory. I have tried things like Returning a file to View/Download in ASP.NET MVC but this only returns one file?

Instead, I need to return a bunch of downloadable files and have links for them on my page among other normal HTML elements. How can I achieve this?

Edit: I have already written code that utilizes DirectoryInfo(path).GetFiles() to get a list of those files. I store the each fileName and its filePath into a list of objects in my viewmodel and pass that into my view. Can I use these attributes as parameters to make the download happen?

It is displayed like:

<ul>
    <li><a href="@FileList[0].Path"><@FileList[0].FileName</a></li>
    <li><a href="@FileList[1].Path"><@FileList[1].FileName</a></li>
    <li><a href="@FileList[2].Path"><@FileList[2].FileName</a></li>
</ul>
Community
  • 1
  • 1
AlbatrossCafe
  • 1,710
  • 6
  • 26
  • 49
  • 1
    You need two separate action results. You need a view that lists all the files, and you need a action result that returns a specific file based on some URL parameter. – mason Aug 18 '15 at 18:40
  • So would each "link" actually be some `ActionResult()` call that returns the one file that was clicked? – AlbatrossCafe Aug 18 '15 at 18:42
  • Correct, based on some parameter you pass in the URL such as ID number or file name. – mason Aug 18 '15 at 18:43
  • Ok. I have already written code that successfully writes out file names/paths. Can you help give syntax as to what that might look like in the view (like how to actually pass in that parameter or which function to use) ? – AlbatrossCafe Aug 18 '15 at 18:45
  • Well, a big question here: is the directory these files reside in served by IIS or at least possible to be served by IIS by adding a virtual directory? – Chris Pratt Aug 18 '15 at 18:52
  • @Chris yes, they are in a virtual directory and are served by IIS! – AlbatrossCafe Aug 18 '15 at 18:53
  • 2
    Then all you really need to do is just transform the physical path into a virtual path. This question might help: http://stackoverflow.com/questions/6081433/getting-relative-virtual-path-from-physical-path – Chris Pratt Aug 18 '15 at 18:57
  • @ChrisPratt I think the real question is "if I don't specify file name in HREF (only path) how I get user intention to download particular file"... – Alexei Levenkov Aug 18 '15 at 19:07
  • @Alexei I don't care what is in the HREF or how it is accomplished, I just want the file to be downloaded when the user clicks on its associated link – AlbatrossCafe Aug 18 '15 at 19:16
  • 2
    Why wouldn't you specify the filename in the link? Just get the virtual path to the file and then set that as the href for your links. Done. You're making this far harder than it needs to be. – Chris Pratt Aug 18 '15 at 19:32

2 Answers2

3

What I ended up doing was adding a Virtual Directory to the root of my web application in IIS. I called it TestClassicWeb and set the path of it to the local directory that had the files.

For help getting the files from the the page, refer the following:

Models:

public class DisplayViewModel
{
    public List<DownloadableFile> FileList{ get; set; }
}

public class DownloadableFile
{
    public string FileName { get; set; }
    public string Path { get; set;}
}

Controller:

using System.Collections.Generic;   //for "List" type
using System.IO;    //GetFiles()

/* ... */

//identify the virtual path
string filePath = "/TestClassicWeb/Reports/SethRollins";

//map the virtual path to a "local" path since GetFiles() can't use URI paths
DirectoryInfo dir = new DirectoryInfo(Server.MapPath(quicklinksPath));

//Get all files (but not any subdirectories) in the folder specified above
FileInfo[] files = dir.GetFiles()

//iterate through each file, get its name and set its path, and add to my VM
foreach (FileInfo file in files )
{
    DownloadableFile newFile = new DownloadableFile();
    newFile.FileName = Path.GetFileNameWithoutExtension(file.FullName);     //remove the file extension for the name
    newFile.Path = filePath + file.Name;                        //set path to virtual directory + file name
    vm.FileList.Add(newFile);                                       //add each file to the right list in the Viewmodel
}

return (vm);

View:

<ul>
    @foreach (DownloadableFile file in Model.FileList)
    {
        <li><a target="_blank" href="@file.Path">@file.FileName</a></li>
    }
</ul>

Thanks for the help in the comments!

AlbatrossCafe
  • 1,710
  • 6
  • 26
  • 49
  • 1
    to remove the extension you should really use: `Path.GetFileNameWithoutExtension(file.Name)`. It declares intent as well as scales with extensions of lengths other than 4 (dot + 3). – Sam Axe Aug 19 '15 at 02:51
0

As stated in the comments, you can transform the absolute paths to virtual paths, also you can set the download attribute for them to be downloadable

<a href="/images/myw3schoolsimage.jpg" download>

According to W3School

The download attribute specifies that the target will be downloaded when a user clicks on the hyperlink.

This attribute is only used if the href attribute is set.

The value of the attribute will be the name of the downloaded file. There are no restrictions on allowed values, and the browser will automatically detect the correct file extension and add it to the file (.img, .pdf, .txt, .html, etc.).

If the value is omitted, the original filename is used.

Though this is limited as some browsers do not fully support it.

Community
  • 1
  • 1
mahlatse
  • 1,322
  • 12
  • 24