askm
askm

Reputation: 315

Get files from folder based on conditions mvc asp

I have two tables, Note and file(one to many). I saved all files in "Files" folder,then i saved name,path,extension in File tables in addition to NoteID(FK).

I uploaded them successfully. But when i want to download files based on NoteID condtions, i can't. i can get all files in that folder.

My question is How i can get some files from specific folder based on condition? i have tried several solutions, but they don't work.

Any help?

Action:

public ActionResult Download(int NoteID)
{

    var fs = db.Files.Where(f => f.NoteID == NoteID);

    string[] files = Directory.GetFiles(Server.MapPath("/Files"));


    for (int i = 0; i < files.Length; i++)
    {
        files[i] = Path.GetFileName(files[i]);
    }
    ViewBag.Files = files;
    return View();
}

public FileResult DownloadFile(string fileName)
{
    var filepath = System.IO.Path.Combine(Server.MapPath("/Files/"), fileName);
    return File(filepath, MimeMapping.GetMimeMapping(filepath), fileName);
}

Download View:

@{
    ViewBag.Title = "Download Files";
    var Files = (ViewBag.Files as string[]);

    if (Files != null && Files.Any())
    {
        foreach (var file in Files)
        {
            <br />
            @Html.ActionLink(file, "DownloadFile", new { fileName = file })
            <br />

        }
    }
    else
    {
        <label>No File(s) to Download</label>
    }
}

Edit:

the code above is working and get and display all files in 'Files' folder

when i'm trying run code below i get IOEception

actions:

  public ActionResult Download(int? NoteID)
    {


        var fs = db.Files.Where(f => f.NoteID == NoteID);


        string[] files = new string[(fs.Count()) - 1];



        int counter = 0;

        foreach (var item in fs)
        {
            files[counter] = Directory.GetFiles(Server.MapPath("/Files/"+item.FileName)).Single();
            /*here is the Exception
             * 
            System.IO.IOException:
            { "The directory name is invalid.\r\n"}

            InnerException message:
            The directory name is invalid.    
            */

        }



        for (int i = 0; i < files.Length; i++)
        {
            files[i] = Path.GetFileName(files[i]);
        }
        ViewBag.Files = files;
        return View();
    }

    public FileResult DownloadFile(string fileName)
    {
        var filepath = System.IO.Path.Combine(Server.MapPath("/Files/"), fileName);
        return File(filepath, MimeMapping.GetMimeMapping(filepath), fileName);
    }

View:

@{
    ViewBag.Title = "Download Files";
    var Files = (ViewBag.Files as string[]);

    if (Files != null && Files.Any())
    {
        foreach (var file in Files)
        {
            <br />
            @Html.ActionLink(file, "DownloadFile", new { fileName = file })
            <br />

        }
    }
    else
    {
        <label>No File(s) to Download</label>
    }
}

Upvotes: 1

Views: 8370

Answers (1)

Pedro Perez
Pedro Perez

Reputation: 932

In your new code:

files[counter] = Directory.GetFiles(Server.MapPath("/Files/"+item.FileName))

You are using an incorrect parameter. You are passing a file path, but this method needs a directory path.

You can use this:

var filteredByFilename = Directory
                        .GetFiles(Server.MapPath("/Files"))
                        .Select(f => Path.GetFileName(f))
                        .Where(f => f.StartsWith("yourFilename"));

ViewBag.Files = filteredByFilename.ToArray();

But in your case I think is better to use Directory.EnumerateFiles method. Please read here.

So the new code would be:

var filteredByFilename = Directory
                        .EnumerateFiles(Server.MapPath("/Files"))
                        .Select(f => Path.GetFileName(f))
                        .Where(f => f.StartsWith("yourFilename"));

ViewBag.Files = filteredByFilename.ToArray();

The whole Download method could be:

public ActionResult Download(int NoteID)
{
    var fs = db.Files.Where(f => f.NoteID == NoteID);

    var fileNames = Directory
        .EnumerateFiles(Server.MapPath("/Files"))
        .Select(f => Path.GetFileName(f));

    var result = new List<string>();

    foreach (var fileName in fs)
    {
        var filteredByName = fileNames.Where(f => f.StartsWith(fileName));
        result.AddRange(filteredByName);
    }

    ViewBag.Files = result.ToArray();
    return View(); 
}

Upvotes: 3

Related Questions