普通模型和IEnumerable模型在同一视图中
本文关键字:模型 视图 IEnumerable | 更新日期: 2023-09-27 18:26:29
有一个小问题,我自己无法解决。我想在一个视图中使用相同的模型,但有一次使用IEnumerable<>第二次没有它。
我的观点:
@model IEnumerable<AMBIT_CMS_MVC.Areas.Admin.Models.Product>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>DYSKRET - FOLIE OKIENNE</title>
@Styles.Render("~/Content/Site.css")
@Styles.Render("~/Content/bootstrap.css")
@Scripts.Render("~/Scripts/jquery-1.10.2.min.js")
@Scripts.Render("~/Scripts/bootstrap.js")
@Scripts.Render("~/Scripts/buttons.js")
</head>
<body>
<div class="container-fluid okienne">
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-8 menu">
<a href="http://dyskret.pl/" target="_blank">
<img src="~/Images/logo.png" class="img-responsive fimg" />
</a>
</div>
<div class="col-sm-2"></div>
</div>
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-2 lista">
<ul>
@foreach (var item in Model)
{
<li>@Html.ActionLink(item.Name, "Produkt", new { ProductID = item.ProductID })</li>
}
</ul>
</div>
<div class="col-sm-6 details">
@Html.DisplayFor(m => m.Name)
</div>
<div class="col-sm-2"></div>
</div>
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-8 footerProducts">
Text...
</div>
<div class="col-sm-2"></div>
</div>
</div>
</body>
</html>
问题是foreach循环将完美工作(我想列出该类别中的所有产品),但当单击时,我想在右侧显示它的详细信息,但我不能,因为模型是IEnumerable<>并且应该是简单的模型(AMBIT_CMS_MVC.Areas.Admin.Models.Product)。这就像我想把"索引"answers"详细信息"视图放在一起一样。我怎样才能做到这一点?
使用Tuple
方法正常模型和IEnumerble
模型
控制器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ProjectX.Models;
namespace ProjectX.Controllers
{
public class StudentController : Controller
{
// GET: Student
public ActionResult Index()
{
ProjectX.DAL.ProjectContext db = new ProjectX.DAL.ProjectContext();
// DAL is Data Access Layer Folder's name
return View(Tuple.Create<Student, IEnumerable<Student>>(new Student(), db.Student.ToList()));
}
}
}
视图:
@model Tuple<ProjectX.Models.Student,IEnumerable<ProjectX.Models.Student>>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_StudentLayout.cshtml";
}
<table>
<thead>
<th>
@Html.DisplayNameFor(model => model.Item1.student_name)
<th />
<th>
@Html.DisplayNameFor(model => model.Item1.student_surname)
<th />
<thead />
<tbody>
@foreach (var item in Model.Item2)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.student_name)
</td>
<td>
@Html.DisplayFor(modelItem => item.student_surname)
</td>
</tr>
}
<tbody />
</table>
好的,所以我找到了答案:
将我的视图更改为:
@model AMBIT_CMS_MVC.Models.ProductViewModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>DYSKRET - FOLIE OKIENNE</title>
@Styles.Render("~/Content/Site.css")
@Styles.Render("~/Content/bootstrap.css")
@Scripts.Render("~/Scripts/jquery-1.10.2.min.js")
@Scripts.Render("~/Scripts/bootstrap.js")
@Scripts.Render("~/Scripts/buttons.js")
</head>
<body>
<div class="container-fluid okienne">
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-8 menu">
<a href="http://dyskret.pl/" target="_blank">
<img src="~/Images/logo.png" class="img-responsive fimg" />
</a>
</div>
<div class="col-sm-2"></div>
</div>
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-2 lista">
@Html.Partial("_Lista", Model.Products)
</div>
<div class="col-sm-6 details">
@Html.Partial("_Produkt", Model.ProductDetails)
</div>
<div class="col-sm-2"></div>
</div>
<div class="row">
<div class="col-sm-2"></div>
<div class="col-sm-8 footerProducts">
Text...
</div>
<div class="col-sm-2"></div>
</div>
</div>
</body>
</html>
_Lista分部:
@model IEnumerable<AMBIT_CMS_MVC.Areas.Admin.Models.Product>
<ul>
@foreach (var item in Model)
{
<li>@Html.ActionLink(item.Name, "Produkt", new { ProductID = item.ProductID })</li>
}
</ul>
_Produkt部分:
@model AMBIT_CMS_MVC.Areas.Admin.Models.Product
@Html.DisplayFor(m => m.Name)
@Html.DisplayFor(m => m.Description)
然后在我的模型中添加了一个类-ProductViewModel(添加到使用我的区域模型来处理它们,因为这个模型在区域之外):
using AMBIT_CMS_MVC.Areas.Admin.Models;
namespace AMBIT_CMS_MVC.Models
{
public class ProductViewModel
{
public IEnumerable<Product> Products { get; set; }
public Product ProductDetails { get; set; }
}
}
最后把我的控制器改成:
public ActionResult Produkt(int? ProductID)
{
string domain = Request.Url.Host;
int clientid = (from a in db.Client where a.Domain == domain select a.ID).First();
int categoryID = db.Category.Where(b => b.ClientID == clientid && b.Name == "Okienne").Select(b => b.ID).First();
var ProductViewModel = new ProductViewModel();
ProductViewModel.Products = db.Product.Where(c => c.ClientID == clientid && c.CategoryID == categoryID).ToList();
ProductViewModel.ProductDetails = db.Product.SingleOrDefault(c => c.ClientID == clientid && c.CategoryID == categoryID && c.ProductID == ProductID);
return View(ProductViewModel);
我就是这么做的。希望它能帮助下一代开发人员出现同样的错误,面临同样的问题。
有几种方法可以实现这一点。
-
使用视图模型。通过使用视图模型,您可以将每个视图模型作为一个单独的属性:
public class ProductViewModel { public IEnumerable<Product> AllProducts { get; set; } public Product ActiveProduct { get; set; } }
然后,您可以使用
Model.AllProducts
进行迭代,并显示用户通过Model.ActiveProduct
单击的单个产品。 -
使用分部并从列表中选择一个产品传递给它。首先,这将要求您的型号为
List<Product>
而不是IEnumerable<Product>
。不能同时迭代和查询枚举对象。不过,有了这个更改,您可以迭代当前的所有产品,然后通过呈现单击的产品@Html.Partial("_Product", Model.SingleOrDefault(m => m.ProductID == Request["ProductID"]))
从技术上讲,你甚至不必在这里使用分部。您可以将该查询的结果设置为Razor中的一个变量,然后利用该变量直接在同一视图中呈现HTML。
-
使用子动作。使用子操作,您可以获得一个完全独立的上下文,这意味着您也可以为视图使用不同的模型。只需在控制器中添加以下内容:
[ChildActionOnly] public ActionResult DisplayProduct(int productID) { var product = // retrieve product by id; return PartialView("_Product", product); }
然后,在你看来:
@Html.Action("DisplayProduct", new { productID = Request["productID"] })