Reputation: 101
I have images in wwwroot/photos dir and I want to display the images in a table after adding a new item (animal), along other details from my database.
Here is the Index page, showing my data without images displaying-
All my images are in wwwroot/photos dir.
I've tried to print the value of PhotoUrl on Index View and saw that it get this path - wwwroot\Photos\Cats\Leon.jpeg
So what is the right way show my images ?
here are the relevent parts of my code: Storage Service-
public class StorageService : IStorageService
{
readonly IHostingEnvironment _hostingEnvironment;
public StorageService(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
public string AbsolutePath => _hostingEnvironment.WebRootPath;
}
Image Service-
public class ImageService : IImageService
{
readonly IStorageService _storageService;
public ImageService(IStorageService storageService)
{
_storageService = storageService;
}
//puts Image folder on wwwroot
public string ImageDir => Path.Combine(_storageService.AbsolutePath, "Photos");
//puts the category name under Image folder
public string CategoryDir(string name) => Path.Combine(ImageDir, name);
public string GetFullImageUrl(Animal animal, IFormFile imageFile)
{
var fileName = $"{imageFile.FileName}";
return Path.Combine(CategoryDir(animal.Category.Name), fileName ?? "");
}
public Task EnsureDirCreated(Category category)
{
Directory.CreateDirectory(CategoryDir(category.Name));
return Task.CompletedTask;
}
public async Task<(bool,string)> UploadImage(IFormFile imageFile, Animal animal)
{
if (imageFile != null && imageFile.Length > 0)
{
var fileName = $"{imageFile.FileName}";
//create file path
var categoryPath = CategoryDir(animal.Category.Name);
await EnsureDirCreated(animal.Category);
string fullPath = Path.Combine(categoryPath, fileName);
using (var fileStream = new FileStream(fullPath, FileMode.Create))
{
await imageFile.CopyToAsync(fileStream);
}
return (true,fullPath);
}
return (false,String.Empty);
}
}
Animal Service-
public async Task<Animal> AddAnimalAsync(Animal animal, IFormFile image)
{
animal.Category = await _categoryService.GetAsync(animal.CategoryId);
var (isSuccess, imageName) = await _imageService.UploadImage(image, animal);
if (isSuccess)
{
animal.PhotoUrl= imageName;
_animalRepository.Add(animal);
return animal;
}
return null;
}
CreaeAnimal ViewModel-
public class CreateAnimalViewModel
{
public Animal Animal { get; set; }
public IFormFile Photo { get; set; }
}
Controllers-
public async Task<IActionResult> Index()
{
var petShopData = _animalService.GetAnimalWithCategoryAsync();
return View(await petShopData);
}
public async Task<IActionResult> CreateAnimal()
{
var categories = await _categoryService.GetAnimalCategory();
ViewBag.Categories = categories.Select(c => new SelectListItem(c.Name, c.CategoryId.ToString())).ToList();
return View();
}
[HttpPost]
public async Task<IActionResult> CreateAnimal([FromForm] CreateAnimalViewModel vm)
{
await _animalService.AddAnimalAsync(vm.Animal, vm.Photo);
return RedirectToAction("Index");
}
Index View-
@model IEnumerable<PetShop.Data.Models.Animal>
@{
ViewBag.Title = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="CreateAnimal">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.BirthDate)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.PhotoUrl)
</th>
<th>
@Html.DisplayNameFor(model => model.Category)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.BirthDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@*@Html.DisplayFor(modelItem => item.PhotoUrl)*@
<img src="@item.PhotoUrl" alt="..." style="width:18rem"/>
</td>
<td>
@Html.DisplayFor(modelItem => item.Category.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.AnimalId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.AnimalId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.AnimalId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Upvotes: 2
Views: 3638
Reputation: 11826
add the codes in your startup class:
app.UseStaticFiles();
if you added the codes,you could try to view your pic and check if it exist as below:
Upvotes: 2