Reputation: 151
I have a project that requires the multiple images to be stored in the wwwroot folder. The image references are saved in the database. So I've written a function that retrieves the image references, and loops through the images that are saved in the wwwroot folder.
So far, I am only able to retrieve the very first image in the folder. Unfortunately the other images are not being returned.
Below is the code:
[HttpGet("images")]
public IActionResult GetImages()
{
var results = _context.ImageTable.Select(i => i.ImageNames).ToList();
foreach (var result in results)
{
var folderPath = Path.Combine(_hostingEnvironment.WebRootPath, "imagesFolder", $"{result}.png");
var file= System.IO.File.ReadAllBytes(folderPath);
return File(file, "image/jpg");
}
return NotFound("No Images");
}
So what I'm expecting are all the images saved in the wwwroot folder to be displayed.
Upvotes: 1
Views: 6991
Reputation: 25360
Apprach 1 : Return an array of urls
and use javascript to create a serial of img
within browser:
public class HomeController : Controller
{
private IHostingEnvironment _env;
// inject a hosting env so that we can get the wwwroot path
public HomeController(IHostingEnvironment env){
this._env = env;
}
public IActionResult GetImages()
{
// get the real path of wwwroot/imagesFolder
var rootDir = this._env.WebRootPath;
// the extensions allowed to show
var filters = new String[] { ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".bmp", ".svg" };
// set the base url = "/"
var baseUrl = "/";
var imgUrls = Directory.EnumerateFiles(rootDir,"*.*",SearchOption.AllDirectories)
.Where( fileName => filters.Any(filter => fileName.EndsWith(filter)))
.Select( fileName => Path.GetRelativePath( rootDir, fileName) ) // get relative path
.Select ( fileName => Path.Combine(baseUrl, fileName)) // prepend the baseUrl
.Select( fileName => fileName.Replace("\\","/")) // replace "\" with "/"
;
return new JsonResult(imgUrls);
}
}
This will return something as below:
[
"/imagesFolder/avatar.jpg",
"/imagesFolder/avatar.png",
"/imagesFolder/subFolder/suit-portrait-preparation-wedding-copy.jpg",
"/imagesFolder/subFolder/woman-street-walking-girl.jpg",
"/imagesFolder/subFolder/subFoler2/pexels-photo-copy1.jpg",
"/imagesFolder/subFolder/subFoler2/road-fashion-vintage-bag-copy.jpg"
]
What you need is to send an ajax request to this action method and then create related <img src={url}>
with these urls. Here's a working sample that uses plain javascript:
<script>
var xhr = new XMLHttpRequest();
xhr.onload=function(e){
var urls=JSON.parse(e.target.responseText);
for(var i = 0 ;i<urls.length;i++){
var img = document.createElement("img");
img.src = urls[i];
document.body.appendChild(img);
}
};
xhr.open("get","/home/getimages");
xhr.send();
</script>
Approach 2 : Use Razor to render the view on server side:
Change the action method to return a View Result:
public IActionResult GetImages() { // ...return new JsonResult(imgUrls);return View(imgUrls); }
Here' the GetImages.cshtml
:
@model IEnumerable<string>
<ul>
@foreach (var url in Model)
{
<li><img src="@url" alt="@System.IO.Path.GetFileName(url)"/></li>
}
</ul>
Both should work.
Upvotes: 1