Reputation: 315
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
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