同一视图中的普通模型和IEnumerable模型

时间:2015-12-10 18:44:53

标签: c# asp.net-mvc model

有一点问题,我自己无法解决。我想在一个视图中使用相同的模型,但是一次使用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&lt;&gt;并且应该是简单的模型(AMBIT_CMS_MVC.Areas.Admin.Models.Product)。这就像我想要将索引和详细信息视图合二为一。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

使用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>

答案 1 :(得分:0)

有几种方法可以实现这一目标。

  1. 使用视图模型。通过使用视图模型,您可以将每个视图作为单独的属性:

    public class ProductViewModel
    {
        public IEnumerable<Product> AllProducts { get; set; }
        public Product ActiveProduct { get; set; }
    }
    

    然后,您可以使用Model.AllProducts进行迭代,并显示用户通过Model.ActiveProduct点击的单个产品。

  2. 使用部分内容并从列表中选择产品以传递给它。首先,这将要求您的模型为List<Product>而不是IEnumerable<Product>。您不能同时迭代并查询可枚举。但是,通过这种更改,您可以按照当前的情况迭代所有产品,然后通过以下方式呈现所单击的产品:

    @Html.Partial("_Product", Model.SingleOrDefault(m => m.ProductID == Request["ProductID"]))
    

    从技术上讲,你甚至不需要在这里使用部分。您可以将该查询的结果设置为Razor中的变量,然后利用它在同一视图中直接呈现HTML。

  3. 使用子操作。通过子操作,您可以获得完全独立的上下文,这意味着您也可以为视图使用不同的模型。只需在控制器中添加以下内容:

    [ChildActionOnly]
    public ActionResult DisplayProduct(int productID)
    {
        var product = // retrieve product by id;
        return PartialView("_Product", product);
    }
    

    然后,在您看来:

    @Html.Action("DisplayProduct", new { productID = Request["productID"] })
    

答案 2 :(得分:0)

好的,所以我想出了答案:

将我的观点更改为:

@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 partial:

@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 partial:

@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);

所以这就是我的成就。希望它能帮助下一代开发人员出现同样的错误并面临同样的问题。