我想在视图中列出单个产品详细信息。产品规格会动态变化,因为规格是在表格中逐行添加的,这意味着我们可以为每种产品添加大量规格(如电子商务网站中所做的那样)。现在我可以使用ViewBag
来满足要求,但我决定使用ViewModel
作为更好的做法。
模特课程:
// Product:
public partial class ProductTable
{
public ProductTable()
{
this.SpecificationsTable = new HashSet<SpecificationsTable>();
}
public int ProductID { get; set; }
public string Title { get; set; }
public string SmallDescription { get; set; }
public string FullDescription { get; set; }
public virtual ICollection<SpecificationsTable> SpecificationsTable { get; set; }
}
//Specifications:
public partial class SpecificationsTable
{
public int SpecificationsID { get; set; }
public string SpecificationName { get; set; }
public string SpecificationValue { get; set; }
public Nullable<int> ProductID { get; set; }
public virtual ProductTable ProductTable { get; set; }
}
视图模型:
public class DetailsViewModel
{
public int ProductID { get; set; }
public string Title { get; set; }
public string SmallDescription { get; set; }
public string FullDescription { get; set; }
public string SpecificationName { get; set; }
public string SpecificationValue { get; set; }
}
ActionMethod
public ActionResult ProductDetails(int id)
{
var details = (from c in dbo.ProductTable
join s in dbo.SpecificationsTable
on c.ProductID equals s.ProductID
where c.ProductID == id
select new DetailViewModel
{
Title = c.Title,
SmallDescription = c.SmallDescription,
FullDescription = c.FullDescription
}).ToList();
// To remove repeated product title , small and full description
var distinctItems = details.GroupBy(x => x.ProductID).Select(y => y.First());
// To show product title, small and full description for this product
ViewBag.ProductDetails = distinctItems;
var specifications = (from c in dbo.ProductTable
join s in dbo.SpecificationsTable
on c.ProductID equals s.ProductID
where c.ProductID == id
select new DetailViewModel
{
SpecificationName = s.SpecificationName,
SpecificationValue = s.SpecificationValue
}).ToList();
// To show list of specifications for this product
ViewBag.Specifcations = specifications;
return View();
}
视野中的预期输出:
详细信息:
Title: New Samsung offer
SmallDescription : Something small
FullDescription : Something full
Specifcations:
Mobile Name :Samsung
Model : 2015
Price : 70 $
Color: White
我正在使用数据库优先方法,我正在尝试学习如何在这里使用视图模型。
答案 0 :(得分:4)
Viewmodels确实是去这里的方式。我不会详细说明你已经在代码中声明了哪些视图模型,所以我假设你已经知道它们的用途和功能。但是,为了完整性,viewmodel仅表示要在视图中显示的数据;假设显示员工名字和姓氏的视图,当您只需要其中两个属性时,没有理由发回Employee
个对象。
根据上面提供的短视图模型定义,要返回视图模型而不是在ViewBag
上附加返回的对象,您只需创建一个类仅保存您想要在视图中显示的数据。因此,根据您在视图&#34;中的预期输出,您的viewmodel看起来与此类似:
public class YourViewModel
{
public string Title { get; set; }
public string SmallDescription { get; set; }
public string FullDescription { get; set; }
public string MobileName { get; set; }
public int ModelYear { get; set; }
public decimal Price { get; set; }
public string Color { get; set; }
}
将viewmodel实例化并填充后,将其传递给视图:
var yourViewModel = new YourViewModel();
//populate it and pass it to the view
return View(yourViewModel);
在视图的顶部,声明您的@model
变量属于YourViewModel
类型:
@model YourViewModel
..你很高兴。因此,如果您想在视图中打印出移动名称:
@Model.MobileName
请记住,虽然每个视图只能有一个 @model
,但您仍然可以拥有多个视图模型。这可以通过创建父视图模型来保存所有与视图相关的视图模型并将其设置为@model
来实现:
public class ParentViewModel
{
//all the viewmodels which are relevant to your view
public DetailsViewModel DetailsViewModel { get; set; }
public YourViewModel YourViewModel { get; set; }
//...etc
}
将viewmodel实例化并填充后,将其传递给视图:
var parentViewModel = new ParentViewModel();
var yourViewModel = new YourViewModel();
//populate it and attach it to the parent viewmodel
parentViewModel.YourViewModel = yourViewModel;
return View(parentViewModel);
这一次,在视图的顶部,将@model
变量声明为ParentViewModel
类型:
@model ParentViewModel
..你很高兴。使用相同的示例,如果您想在视图中打印出移动名称:
@Model.YourViewModel.MobileName
请记住,我并没有真正关注你如何构建视图模型,而是解释了如何将一个(或多个)视图模型传递回视图并使用它们而不是{{1} (根据你的问题)。对于你的视图模型应该如何填充和看起来像,Stephen Muecke's answer是要走的路。
答案 1 :(得分:4)
您当前的视图模型不反映您要在视图中显示的内容,这是每个产品的多个规范,因此您需要一个集合属性。将视图模型更改为
public class SpecificationVM
{
public string Name { get; set; }
public string Value { get; set; }
}
public class ProductVM
{
public string Title { get; set; }
public string SmallDescription { get; set; }
public string FullDescription { get; set; }
IEnumerable<SpecificationVM> Specifications { get; set; }
}
然后在控制器中,使用
填充查看模型public ActionResult ProductDetails(int id)
{
var product = db.ProductTable.Where(p => p.ProductID == id).FirstOrDefault();
// note you may need to add .Include("SpecificationsTable") in the above
if (product == null)
{
return new HttpNotFoundResult();
}
ProductVM model = new ProductVM()
{
Title = product.Title,
SmallDescription = product.SmallDescription,
FullDescription = product.FullDescription,
Specifications = product.SpecificationsTable.Select(s => new SpecificationVM()
{
Name = s.SpecificationName,
Value = s.SpecificationValue
})
};
return View(model);
}
然后在视图中
@model yourAssembly.ProductVM
<h2>Details</h2>
@Html.DisplayNameFor(m => m.Title)
@Html.DisplayFor(m => m.Title)
.... // ditto for SmallDescription and FullDescription
<h2>Specifications</h2>
@foreach(var item in Model.Specifications)
{
@Html.DisplayFor(m => item.Name)
@Html.DisplayFor(m => item.Value)
}