'Trying to connect to wwwroot and get a image

I work in aspnet core mvc technology, I manage to add an image, it does go to wwwroot, but the image does not display well in the browser Example: enter image description here

enter image description here

My Controller:

 [HttpPost,ActionName("CreateAnimal")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> CreateAnimal([FromForm] CreateAnimalViewModel model)
    {
        string wwwPath = _Environment.WebRootPath;
        string contentPath = _Environment.ContentRootPath;
        ModelState.Clear();
        model.Animal!.Category = _context.Categories.Where(c => c.CategoryId == model.Animal.CategoryId).FirstOrDefault()!;
        var path = Path.Combine(wwwPath, "Images", model.Photo!.FileName);
        if (model.Photo.Length > 0)
        {
            using var stream = new FileStream(path, FileMode.Create);
            await model.Photo.CopyToAsync(stream);
        }

        model.Animal.PhotoUrl = path;
        _context.Add(model.Animal);
        
        if (TryValidateModel(model))
        {

            _context.Add(model.Animal!);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Manager));
        }

        ViewBag.CategoryId = new SelectList(_context.Categories, "CategoryId", "Name");
        return View();
    }

My View:

@model IEnumerable<PetShop.Data.Models.Animal>
<table id="Table">
<thead>
    <tr>
        <th>@Html.DisplayNameFor(model => model.PhotoUrl)</th>
        <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.Category.Name)</th>
        <th>@Html.DisplayNameFor(model => model.Category)</th>
        <th>Edit Animel</th>
        <th>Delete Animel</th>

@foreach (var item in Model!) {

           <img class="Images" src="~/Images/@Html.DisplayFor(modelItem => item.PhotoUrl)">
       </td>
       <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.Category.Name)</td>
       <td>@Html.DisplayFor(modelItem => item.CategoryId)</td>
     
           <a asp-action="EditAnimel" asp-route-id="@item.AnimalId">
           <input type="submit" value="Edit">
           </a>
   
           <a asp-action="DeleteAnimel" asp-route-id="@item.AnimalId">
           <input type="submit" value="Delete">
           </a>

}



Solution 1:[1]

Below is a work demo, you can refer to it.

ProductController.cs:

   [Route("product")]
    public class ProductController : Controller
    {
        private IWebHostEnvironment webHostEnvironment;

        public ProductController(IWebHostEnvironment _webHostEnvironment)
        {
            webHostEnvironment = _webHostEnvironment;
        }

        [Route("")]
        [Route("index")]
        [Route("~/")]
        public IActionResult Index()
        {
                return View("Index", new Product());
        }
        [Route("save")]
        [HttpPost]
        public IActionResult Save(Product product, IFormFile photo)
        {
            if (photo == null || photo.Length == 0)
            {
                return Content("File not selected");
            }
            else
            {
                var path = Path.Combine(this.webHostEnvironment.WebRootPath, "images", photo.FileName);
                var stream = new FileStream(path, FileMode.Create);
                photo.CopyToAsync(stream);
                product.Photo = photo.FileName;
            }
            ViewBag.product = product;

          

                return View("Success");
        }

    }

Index.cshtml:

@model SingleFile.Models.Product

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>

    <form asp-controller="product" asp-action="save" method="post" enctype="multipart/form-data">
        <table cellpadding="2" cellspacing="2">
            <tr>
                <td>Id</td>
                <td>
                    <input type="text" asp-for="Id" />
                </td>
            </tr>
            <tr>
                <td>Name</td>
                <td>
                    <input type="text" asp-for="Name" />
                </td>
            </tr>
            <tr>
                <td>Price</td>
                <td>
                    <input type="text" asp-for="Price" />
                </td>
            </tr>
            <tr>
                <td>Photo</td>
                <td>
                    <input type="file" name="photo" />
                </td>
            </tr>
            <tr>
                <td>&nbsp;</td>
                <td><input type="submit" value="Save" /></td>
            </tr>
        </table>
    </form>

</body>
</html>

Success.cshtml:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Success</title>
</head>
<body>

    <h3>Product Info</h3>
    <table cellpadding="2" cellspacing="2" border="1">
        <tr>
            <td>Id</td>
            <td>@ViewBag.product.Id</td>
        </tr>
        <tr>
            <td>Name</td>
            <td>@ViewBag.product.Name</td>
        </tr>
        <tr>
            <td>Price</td>
            <td>@ViewBag.product.Price</td>
        </tr>
        <tr>
            <td>Photo</td>
            <td><img src="~/images/@ViewBag.product.Photo" width="120" /></td>
        </tr>
    </table>

</body>
</html>

Product

 public class Product
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
        public string Photo { get; set; }

    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1