I have a controller that is building a query from Linq to Sql to pass into the ViewBag.products object. The problem is, I cannot loop using a foreach on it as I expected I could.
Here's the code in the controller building the query, with the .ToList() function applied.
var products = from bundles in db.Bundle
join bProducts in db.BundleProducts on bundles.bundleId equals bProducts.bundleID
join product in db.Products on bProducts.productID equals product.productID
join images in db.Images on product.productID equals images.productID
where bundles.bundleInactiveDate > DateTime.Now
select new {
product.productName,
product.productExcerpt,
images.imageID,
images.imageURL
};
ViewBag.products = products.ToList();
Since I am using a different model on the Index.cshtml for other items needed, I thought a simple Html.Partial could be used to include the viewbag loop. I have tried it with the same result with and without using the partial and simply by using the foreach in the index.cshtml. A snippet that includes the partial is below:
<div id="bundle_products">
<!--build out individual product icons/descriptions here--->
@Html.Partial("_homeBundle")
</div>
In my _homeBundle.cshtml file I have the following:
@foreach (var item in ViewBag.products)
{
@item
}
I am getting the ViewBag data, but I am getting the entire list as output as such:
{ productName = Awesomenes Game, productExcerpt = <b>Awesome game dude!</b>, imageID = 13, imageURL = HotWallpapers.me - 008.jpg }{ productName = RPG Strategy Game, productExcerpt = <i>Test product excerpt</i>, imageID = 14, imageURL = HotWallpapers.me - 014.jpg }
What I thought I could do was:
@foreach(var item in ViewBag.Products)
{
@item.productName
}
As you can see, in the output, productName = Awesomenes Game. However, I get the error 'object' does not contain a definition for 'productName' when I attempt this.
How can I output each "field" so to say individually in my loop so I can apply the proper HTML tags and styling necessary for my page?
Do I need to make a whole new ViewModel to do this, and then create a display template as referenced here: 'object' does not contain a definition for 'X'
Or can I do what I am attempting here?
*****UPDATE*****
In my Controller I now have the following:
var bundle = db.Bundle.Where(a => a.bundleInactiveDate > DateTime.Now);
var products = from bundles in db.Bundle
join bProducts in db.BundleProducts on bundles.bundleId equals bProducts.bundleID
join product in db.Products on bProducts.productID equals product.productID
join images in db.Images on product.productID equals images.productID
where bundles.bundleInactiveDate > DateTime.Now
select new {
product.productName,
product.productExcerpt,
images.imageID,
images.imageURL
};
var bundleContainer = new FullBundleModel();
bundleContainer.bundleItems = bundle;
return View(bundleContainer);
I have a model, FullBundleModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace JustBundleIt.Models
{
public class FullBundleModel
{
public IQueryable<Bundles> bundleItems { get; set; }
public IQueryable<Images> imageItems { get; set; }
}
}
and my View now has
@model IEnumerable<JustBundleIt.Models.FullBundleModel>
@foreach (var item in Model)
{
<div class="hp_bundle">
<h3>@Html.Display(item.bundleName)</h3>
</div>
}
If I remove IEnumerable from the model reference, the foreach errors out that there is no public definition for an enumerator.
In the @Html.Display(item.bundleName) it errors out that the model has no definition for bundleName. If I attempt
@foreach(var item in Model.bundleItems)
I get an error that bundleItems is not defined in the model.
So what don't I have wired up correctly to use the combined model?