Inbar Manor
Inbar Manor

Reputation: 101

ASP.NET Core how to display images from wwwroot/Photos

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- enter image description here

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

Answers (1)

Ruikai Feng
Ruikai Feng

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: enter image description here

Upvotes: 2

Related Questions