简体   繁体   中英

Display multiple models in a single view

I have to create one view of invoice. I have many models (tables) and I want to display all data from multiple models in one view of invoice. I created one empty (without model) view and put into a partial views. One of Partial View return one view with one model but this solution return me exception... This is my work: This is my action in controller:

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

This is one of partial view:

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

This is my "Index" view with Partial Views:

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

How can I fix them?

If you insist on having a single view, then you can make rendering of partial views conditional:

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

, and so on.

On a related note, since all the models are exclusive (you never have more than one object), I don't see the point of having one Index view. You already have one (partial) view per class, so why not just use them as regular views?

Update

If you choose to return separate view from each of the action methods, then you can do that by specifying the name of each view. Refer to this question for details: How to return ActionResult with specific View (not the controller name)

In your particular case, that would mean:

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

Make sure that each of the views expects a strongly typed model. That will make it easy to implement the views.

While your approach may work, you will have less or no control over the data (if you want to let's assume join or use any of the parent data). In such situations what I do is create a ViewModel with more than one objects as part of it. For example

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

So now I can populate this View Model before going into my view.

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

Now I can design my view with either Partial views or one whole view for my invoice data.

I will put as model the IEnumerable or IList

if I use partial for both it will be @model db.Objects.InvoiceHead // for the header

@model IEnumerable // for the details

in html code will be like that

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

use your own folder path. hope works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM