How do I pass multiple models to partial views in ASP.NET MVC
Asked Answered
N

1

10

I've been reading Scott Guthrie's post on Passing ViewData from Controllers to Views, but I don't think the lesson is clicking for my specific situation.

(Note: Due to client proprietary restrictions, I can't talk paste the actual code, so I apologize if my made up case is a bit stupid/confusing.)

I have a Controller called ScenarioController which handles the various actions revolving around the creation of a Scenario model. Various actions a user will complete are the general CRUD of Scenarios. I can create a website that does this for the Scenario model. However, I recently updated the Scenario model so that it is now made up of various sub-components (lists of other objects). The corresponding view utilizes jQuery Tabs which load partial views to, ultimately, load the forms to the various sub-component data. Unfortunately, this is where I am having trouble.

My Index page currently looks something like this:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">

<% using (Html.BeginForm()) {%>
    <div id="scenario">
        <div id="tabs">
            <ul>
                <li><a href="#tab1">Tab 1</a></li>
                <li><a href="#tab2">Tab 2</a></li>
                <li><a href="#tab3">Tab 3</a></li>
            </ul>

            <div id="tab1"><% Html.RenderPartial("Tab1"); %></div>
            <div id="tab2"><% Html.RenderPartial("Tab2"); %></div>
            <div id="tab3"><% Html.RenderPartial("Tab3"); %></div>
        </div>

        <div class="submitButtons">
            <input type="button" value="Save Scenario" id="SaveScenario" />
            <input type="button" value="Submit Scenario" id="SubmitScenario" />
        </div>
    </div>
<% } %>
</asp:Content>

And the partial pages are strongly-typed to whatever they represent (primarily List<SomeObject>).

How should the data be stored within the Scenario model? I am using a SQL database and interfacing with Entity Framework. Do I still need Properties representing the various lists of items (so I can pass ViewData using strongly typed classes), or is this something I can pass in the ViewData directly from the entity calls (and cast as needed)?

Nevins answered 22/9, 2010 at 14:41 Comment(0)
G
4

You can pass as many models as you want in your view. you just have to make an encapsulating model which can contain all your 'to send' models.

you can also make use of ViewData but using a model is recommended.

Do your 3 tabs need the whole model or just a part of it?

let's say you have 3 models in your encapsulating model. named tab1 tab2 tab3.

so then you could send each Renderpartial it's appropriate model as so:

        <div id="tab1"><% Html.RenderPartial("Tab1", Model.tab1); %></div>
        <div id="tab2"><% Html.RenderPartial("Tab2", Model.tab2); %></div>
        <div id="tab3"><% Html.RenderPartial("Tab3", Model.tab3); %></div>

your encapsulating model could then look like

namespace MVCNAMESPACE.Models {
    public partial class EnCapModel {
        public List<SomeObject> tab1 { get; set; }
        public List<SomeObject> tab2 { get; set; }
        public List<SomeObject> tab3 { get; set; }
    }
}

hope this helps

Geffner answered 22/9, 2010 at 14:46 Comment(8)
This is the path I first took. In the case of Model.tab1, tab1 is actually an EntityCollection, so I'm trying to do: Model.tab1.FirstOrDefault() (I don't need the collection right now). I get an error message which says: "The model item passed into the dictionary is of type 'Scenario', but this dictionary requires a model item of type 'Tab1'." - Maybe I am just making a dumb error? Thanks, @Stefanvds!Nevins
when you take 1 (firstordefault) you dont have a list but just 1 item of the type Scenario. so you need to change your RenderPartial to take 1 Scenario, or you just do the FirstOrDefault inside the RenderPartialGeffner
Yeah...I am doing that. Here's my partial view: <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Tab1>" %> - I appreciate your help...this is a very weird (and frustrating) problem.Nevins
Weird. I had to do something like this, but only for Tab1. Tab2 and Tab3 didn't need it. - <% Html.RenderPartial("Tab1", Model.Scenario.FirstOrDefault<Tab1>()); %>Nevins
probably your tab2 and 3 were dynamic?Geffner
No, they're strongly typed too. That's what's really confusing. There's no apparent difference.Nevins
@Geffner - Something I didn't understand from your post - where do I actually use EnCapModel? Should the encapsulating ASPX page be strongly-typed to that? Your answer isn't clear on that.Nevins
this EncapModel would be sent to your 'main page' where you have placed the code of in your question. so yes, strongly typed. the EnCapModel.cs file would you put in the ViewModel folder.Geffner

© 2022 - 2024 — McMap. All rights reserved.