0

I am following the tutorial for the MVC music store and trying to build upon it. I want to be able to show an image for each item in a category. So far I can return a list of items for a category but am unable to get a URL from the database to populate the image source in my view.

The way I have set my models up is below. I have an item table which contains a foreign key to the Category table. I then have an Image table which has a foreign key to the item table. I have been trying to get a url from the url table for each item returned from the controller.

Category Model: Just a list of Categories

public class Category
{
   public int CategoryId { get; set; }
   public string CategoryName { get; set; }
   public ICollection<Item> Items { get; set; }
 }

Item Model : Contains foreign key to the categories

public class Item
{
    public int ItemId { get; set; }
    public int CategoryId { get; set; }
    public string ItemName { get; set; }

    public virtual Category Category { get; set; }
    public ICollection<Image> Images { get; set; }
}

Image Model : Contains a foreign key to the item table.

public class Image
{
    public int ImageId { get; set; }
    public string ImageURL { get; set; }
    public int ItemId { get; set; }
    public virtual Item Item { get; set; }
}

Browse Controller

public ActionResult Browse(string category)
{
 var categoryModel = storeDB.Categorys.Include("Items")
                     .SingleOrDefault(c => c.CategoryName == category);

 return View(categoryModel);
}

View:

@model Project.Models.Category

<div class="items">
    <h3><em> @Model.CategoryName </em></h3>

        @foreach (var item in Model.Items)
        {
            <a href="@Url.Action("Details",new {id = item.ItemId})"/> @item.ItemName
            <a href="@Url.Action("Details",new {id = item.ItemId})"/> <img alt="@item.ItemName" src= "@item.Image.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault()" />
        }

When I step through the code above, I can see that the Image URL is null, but have been failing to figure out the correct way to set this up. As with any beginner question I imagine Im doing something wrong or missing the obvious. Any help would be welcome.

Thanks

2
  • The title of the question is misleading... Commented Sep 22, 2014 at 23:50
  • bare in mind I wasn't sure what my issue was. What would you suggest? Commented Sep 23, 2014 at 11:11

1 Answer 1

3

First of all there is a typo in view @item.Image.Wher... in model is Images (plural). Second, you are trying to display:

<img alt="@item.ItemName" src= "@item.Images.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault()" />

FirstOrDefault() reteruns null or instance of Image neither of them is path to image.

You should check first if object isn't null and url isn't empty and after display Image.ImageURL:

@{var image = item.Images.Where(i => i.ImageURL.Contains("thumb")).FirstOrDefault();}
if (image != null && !String.IsNullOrEmpty(image.ImageURL))
{
    <img alt="@item.ItemName" src="@image.ImageURL" />
}   
else
{
    <img alt="@item.ItemName" src="~/default/image/path" />
}

To enable lazy loading, you can use virtual keyword befor ICollection in model:

...
public virtual ICollection<Image> Images { get; set; }
...
public virtual ICollection<Item> Items { get; set; }
...

Does it help?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.