locked
Getting System.IO.FileNotFoundException error due to an image file. RRS feed

  • Question

  • User766850287 posted

    I recently bought the book "Learn ASP.NET MVC" by Amaud Weil. I don't know how familiar you guys are with this book, but one of the tasks in the book is to create a product page in Visual Studio that is connected with a database. I have already done that part, and now I have come to a part where I need to show an image for each product. Even when looking at the cheat sheet in the book, I cannot get this to work.

    Before going over the error, let me show you the whole project so that there is a better understanding of what I am doing.

    If we look at my models first, I have Product.cs

    @model Product.Models.Product

    @{
    ViewBag.Title = "Details";
    }

    <h2>Details</h2>

    <div>
    <h4>Product</h4>
    <hr />
    <dl class="dl-horizontal">
    <dt>
    @Html.DisplayNameFor(model => model.Name)
    </dt>

    <dd>
    @Html.DisplayFor(model => model.Name)
    </dd>

    <dt>
    @Html.DisplayNameFor(model => model.Description)
    </dt>

    <dd>
    @Html.DisplayFor(model => model.Description)
    </dd>

    <dt>
    @Html.DisplayNameFor(model => model.Price)
    </dt>

    <dd>
    @Html.DisplayFor(model => model.Price)
    </dd>

    </dl>
    </div>
    <p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
    @Html.ActionLink("Back to List", "Index")
    </p>

    And then I have a model called ShopFactory.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;

    namespace Product.Models
    {
    public class ShopFactory : DbContext
    {
    public ShopFactory()
    {
    Database.SetInitializer(new ShopInitializer());
    }
    public DbSet<Product> Products { get; set; }
    }
    public class ShopInitializer : DropCreateDatabaseIfModelChanges<ShopFactory>
    {
    protected override void Seed(ShopFactory context)
    {
    context.Products.Add(new Product() { Name = "Yoghurt", Description = "This creamy one will melt in your mouth", Price = 5.4M, ImageName="pc1.jpg" });
    context.Products.Add(new Product() { Name = "Banana", Description = "Hungry? That's going to get you satisfied", Price = 3M, ImageName="pc2.jpg" });
    context.Products.Add(new Product() { Name = "Cleaning logtion", Description = "Nothing gets in its way", Price = 64M, ImageName="pc3.jpg" });

    }
    }
    }

    Of course I have a HomeController

    using Product.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Mvc;

    namespace Products.Controllers
    {
    public class HomeController : Controller
    {
    public ActionResult Index()
    {
    var factory = new ShopFactory();
    var products = factory.Products.ToList();
    return View(products);
    }

    public ActionResult About()
    {
    ViewBag.Message = "Your application description page.";

    return View();
    }

    public ActionResult Contact()
    {
    ViewBag.Message = "Your contact page.";

    return View();
    }
    public ActionResult Details(int id)
    {
    var factory = new ShopFactory();
    var found = factory.Products.Where(p => p.ID == id).FirstOrDefault();
    return View(found);
    }
    public ActionResult Picture(int id)
    {
    var factory = new ShopFactory();
    var product = factory.Products.Where(p => p.ID == id).FirstOrDefault();
    if (product == null)
    {
    return HttpNotFound();
    }
    var img = new WebImage(string.Format("~/Content/Images/{0}.jpg", product.ImageName));
    img.Resize(50, 50);
    return File(img.GetBytes(), "image/jpeg");
    }
    }
    }

    And an Index page.

    @{
    ViewBag.Title = "Home Page";
    }

    <div class="row">
    <div class="col-md-8">
    <h2>Products</h2>
    <table class="table-striped table-bordered table-responsive">
    @foreach (var product in Model)
    {
    <tr>
    <td>
    @product.Name
    </td>
    <td>
    @product.Description
    </td>
    <td>
    @Html.ActionLink("Details", "Details", new { id = product.ID })
    </td>
    <td>
    <img src='@Url.Action("Picture", new { id = product.ID })'/>
    </td>
    </tr>
    }
    </table>
    </div>
    </div>

    Okay, so this is exactly how I was supposed to set it up according to the book. Now for the images, I was told to make a new folder in the "Contents" folder and name it "Images" where I would store all the images used for this project. I did so, and as you can see I already coded everything. 

    The problem is that during debugging I get the error in my HomeController file. System.IO.FileNotFoundException: 'The file 'L:\C#\Products\Products\Content\Images\pc1.jpg.jpg' was not found.'

    The error is located here: var img = new WebImage(string.Format("~/Content/Images/{0}.jpg", product.ImageName));

    I thought the "jpg.jpg" thing looked weird, so I tried to rename the ImageName value to ImageName="pc1" instead of ImageName="pc1.jpg", but it gave the same error.

    Here comes the weird part. I thought maybe the fault was with the image itself, so I deleted it and tried a completely different image that I gave the name "test". But even though I changed the ImageName value to "test.jpg" and deleted pc1.jpg, I am STILL getting the error that "pc1.jpg.jpg" was not found. I looked in Autos, and sure enough, ImageName STILL has the value "pc1". I can delete it and edit it all I want. I can close and open Visual Studio a hundred times, it STILL insists that pc1.jpg is a value... and that it cannot find it. The book is not giving me any answers, so I was hoping someone here could spot the problem. 

    Saturday, April 25, 2020 1:20 AM

All replies

  • User475983607 posted

    The error is very clear.  The file does not exist.  Take a couple of seconds to review the path and file name.  Notice the two jpg.jpg.  

    L:\C#\Products\Products\Content\Images\pc1.jpg.jpg

    If we assume the file name is incorrect and contains one .jpg not two then either product.ImageName should not have an extension or the string.Format is wrong.  A simple fix is updating the string.Format to remove the jpg. 

    var img = new WebImage(string.Format("~/Content/Images/{0}", product.ImageName));

    There could be other issues the code as it seems a bit odd to name a web application "Product".  If you find further issues with the code then I recommend contacting the author or finding another book.

    Saturday, April 25, 2020 11:10 AM
  • User550915133 posted

    You have your db initializer inherit from DropCreateDatabaseIfModelChanges<> so unless your model classes changes you are still using the old values.

    You could use DropCreateDatabaseAlways<> instead, but use that only during development.

    Saturday, April 25, 2020 1:34 PM
  • User1686398519 posted

    Hi,  McQvist

    Your image path is wrong, because your “product.ImageNamecarries the suffix name when it is stored, and the suffix name is added again when the path is generated, so “new WebImage” will report an error. There are two ways to modify your code.

    Or

    Here is the result.

    Best Regards,

    YihuiSun

    Wednesday, April 29, 2020 1:34 AM