【问题标题】:Display multiple models in a single view在单个视图中显示多个模型
【发布时间】:2026-01-23 19:05:01
【问题描述】:

我必须创建一个发票视图。我有很多模型(表格),我想在一个发票视图中显示来自多个模型的所有数据。我创建了一个空(无模型)视图并放入部分视图。部分视图之一返回一个具有一个模型的视图,但此解决方案返回异常...这是我的工作: 这是我在控制器中的操作:

public ActionResult Customer()
        {
            var data = db.Customer;

            return PartialView("Index", data);
        }

        public ActionResult Invoice()
        {
            var data = db.Invoice;

            return PartialView("Index", data);
        }

        public ActionResult Dealer()
        {
            var data = db.Dealer;

            return PartialView("Index", data);
        }

        public ActionResult Paid()
        {
            var data = dane.Paid;

            return PartialView("Index", data);
        }

        public ActionResult Products()
        {
            var data = dane.Products;

            return PartialView("Index", data);
        }

这是部分观点之一:

@model IEnumerable<Invoice_v1._0.Models.Products>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Amount)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Name)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Amount)
        </td>
    </tr>
}

</table>

这是我的部分视图的“索引”视图:

@Html.Partial("_Customer")
@Html.Partial("_Invoice")
@Html.Partial("_Dealer")
@Html.Partial("_Paid")
@Html.Partial("_Products")

我该如何解决?

【问题讨论】:

  • 什么/哪里有异常?
  • 使用@Html.Action() 是要调用一个控制器方法,该方法返回带有数据的部分视图。 (或使用包含所有填充数据的视图模型)
  • 我还注意到,没有必要仅仅因为视图中有不同的“表”就使用局部视图。这样做的惯用方法是创建一个 ViewModel,它包含视图所需的所有数据,并将其用作视图的“模型”。部分视图更适用于可以进入不同父视图的可重用视图。

标签: c# asp.net-mvc entity-framework


【解决方案1】:

如果你坚持只有一个视图,那么你可以有条件地渲染部分视图:

if (Model != null && Model is Customer)
    Html.Partial("_Customer", Model as Customer)

,以此类推。

在相关的说明中,由于所有模型都是独占的(您永远不会拥有一个以上的对象),我看不出拥有一个索引视图的意义。每个类已经有一个(部分)视图,那么为什么不将它们用作常规视图呢?

更新

如果您选择从每个操作方法返回单独的视图,那么您可以通过指定每个视图的名称来实现。详情参考这个问题:How to return ActionResult with specific View (not the controller name)

在您的特定情况下,这意味着:

public ActionResult Customer()
{
    return View("_Customer", db.Customer);
}

public ActionResult Invoice()
{
    return View("_Invoice", db.Invoice);
}

public ActionResult Dealer()
{
    return View("_Dealer", db.Dealer);
}

public ActionResult Paid()
{
    return View("_Paid", db.Paid);
}

public ActionResult Products()
{
    return View("_Products", db.Products);
}

确保每个视图都需要一个强类型模型。这将使视图的实现变得容易。

【讨论】:

  • 你的意思是我应该创建一个常规视图而不是部分视图?但是如何在一个视图(一页)上显示它?
  • 我正在使用您的解决方案,但它在 _Products 部分视图的 foreach 循环中的模型中返回“NullReferenceExcetion”。你知道为什么吗?
  • 你能找出模型中的哪个对象是空的吗?模型本身,还是集合中的项目,或者从集合中的项目返回的属性?那些似乎是候选人。
  • 模型本身返回 null
【解决方案2】:

虽然您的方法可能有效,但您对数据的控制权可能会减少或无法控制(如果您想让我们假设加入或使用任何父数据)。在这种情况下,我所做的是创建一个 ViewModel,其中包含多个对象。例如

public class InvoiceViewModel
{
    public InvoiceHead Header { get;set; }
    public IList<InvoiceDetail> Details { get; set; }
}

所以现在我可以在进入我的视图之前填充这个视图模型。

public ActionResult Invoice(int id)
{
     InvoiceViewModel viewModel = new InvoiceViewModel();
     viewModel.Header = db.InvoiceHead.SingleOrDefault(i => i.ID == id);
     if(viewModel.Header != null)
     {
         viewModel.Details = db.Details.Where(d => d.Inv_id == id).ToList();
     }
     return View(viewModel);
}

现在我可以使用部分视图或一个完整视图来设计我的发票数据视图。

我会将 IEnumerable 或 IList 作为模型

如果我对两者都使用部分,它将是 @model db.Objects.InvoiceHead // 用于标题

@model IEnumerable // 了解详情

【讨论】:

    【解决方案3】:

    在html代码中会是这样的

     @Html.Partial("~/Views/Customers/_AttachFileList.cshtml")
    

    使用您自己的文件夹路径。希望有效

    【讨论】:

      最近更新 更多