我有一个控制器正在构建从
Linq到Sql的查询以传递到ViewBag.products对象.问题是,我不能像我预期的那样使用foreach循环.
这是构建查询的控制器中的代码,应用了.ToList()函数.
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();
由于我在Index.cshtml上使用了不同的模型来处理所需的其他项目,我认为可以使用简单的Html.Partial来包含viewbag循环.我已尝试使用和不使用partial的相同结果,只需使用index.cshtml中的foreach.包含部分的片段如下:
<div id="bundle_products">
<!--build out individual product icons/descriptions here--->
@Html.Partial("_homeBundle")
</div>
在我的_homeBundle.cshtml文件中,我有以下内容:
@foreach (var item in ViewBag.products)
{
@item
}
我正在获取ViewBag数据,但我将整个列表作为输出如下:
{ 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 }
我认为我能做的是:
@foreach(var item in ViewBag.Products)
{
@item.productName
}
如您所见,在输出中,productName = Awesomenes Game.但是,当我尝试这个时,我得到错误’object’不包含’productName’的定义.
如何输出每个“字段”以便在我的循环中单独说出,以便我可以为我的页面应用正确的HTML标记和样式?
我是否需要创建一个全新的ViewModel才能执行此操作,然后创建一个显示模板,如下所示:‘object’ does not contain a definition for ‘X’
或者我可以做我在这里尝试的事情吗?
***** UPDATE *****
在我的控制器中,我现在有以下内容:
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);
我有一个模型,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; }
}
}
我的视图现在有了
@model IEnumerable<JustBundleIt.Models.FullBundleModel>
@foreach (var item in Model)
{
<div class="hp_bundle">
<h3>@Html.Display(item.bundleName)</h3>
</div>
}
如果我从模型引用中删除IEnumerable,则foreach错误地指出枚举器没有公共定义.
在@Html.Display(item.bundleName)中,它错误地认为模型没有bundleName的定义.如果我尝试
@foreach(var item in Model.bundleItems)
我得到一个错误,没有在模型中定义bundleItems.
那么我没有正确连线使用组合模型呢?
最佳答案 为什么不创建包含所需数据的新模型?
示例一:
public class ContainerModel
{
public IQueryable<T> modelOne;
public IQueryable<T> modelTwo;
}
这将允许您访问Razor中的任一查询:
@model SomeNamespace.ContainerModel
@foreach (var item in Model.modelOne)
{
//Do stuff
}
我个人完全避免使用ViewBag,并将我需要的所有内容存储在这些模型中,因为它不是动态的,并强制所有内容都是强类型的.我也相信这会给你一个明确定义的结构/意图.
为了清楚起见:
public ViewResult Index()
{
var queryOne = from p in db.tableOne
select p;
var queryTwo = from p in db.tableTwo
select p;
var containerModel = new ContainerModel();
containerModel.modelOne = queryOne;
containerModel.modelTwo = queryTwo;
return View(containerModel);
}
示例二:
public class ContainerModel
{
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] //Format: MM/dd/yyyy (Date)
public Nullable<DateTime> startDate { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] //Format: MM/dd/yyyy (Date)
public Nullable<DateTime> endDate { get; set; }
public SelectList dropdown { get; set; }
public IQueryable<T> modelOne { get; set; }
public IQueryable<T> modelTwo { get; set; }
}
在这种情况下,您已使用2个查询在模型中存储了3个其他项目.您可以使用Html帮助程序在Razor中创建下拉列表:
@Html.DropDownList("dropdown", Model.dropdown)
您可以使用DisplayFor帮助程序使用数据注释显示模型中定义的日期:
@Html.DisplayFor(a => a.startDate)
这是有利的IMO,因为它允许您定义要在视图中使用的所有数据以及您计划如何在单个位置格式化该数据.您的Controller包含所有业务逻辑,您的模型包含所有数据/格式,而您的View仅关注页面内容.