I have an MVC 4 application with several views. I.e. Products, Recipes, Distrubutors & Stores.
Each view is based around a model.
Let\'s keep it simple
public class MenuContents
{
public IEnumerable<Products> AllProducts { get; set; }
public IEnumerable<Recepies> AllRecepies { get; set; }
public IEnumerable<Distributors> AllDistributors { get; set; }
public IEnumerable<Stores> AllStores { get; set; }
private XXXDb db = new XXXUSDb();
public void PopulateModel()
{
AllProducts = db.Products.ToList();
AllRecepies = db.Recepies.ToList();
AllDistributors = db.Distributors.ToList();
AllStores = db.Stores.ToList();
}
}
Then in your controller
public ActionResult PartialWhatever()
{
MenuContents model = new MenuContents();
model.PopulateModel();
return PartialView("PartialViewName", model);
}
Then in your partial view
@Model MenuContents
... do whatever here
I'm going to be making a few assumptions because I don't have all the information.
I suspect you want to create something like this:
When you run into the issue of "How do I put everything into a single controller/viewmodel" it's possible that it's doing too much and needs to be divided up.
Don't treat your a final page as one big view - divide the views up into smaller views so they are doing 'one thing'.
For example, the navigation is just one part of your layout. You could go even further to say that each dropdown menu is a single view that are part of the navigation, and so on.
Suppose you have a _Layout.cshtml
that looks like this:
<body>
<div class="navbar">
<ul class="nav">
<li><a href="#">Products</a></li>
<li><a href="#">Recipes</a></li>
</ul>
</div>
@RenderBody()
</body>
As you can see we have a simple navigation system and then the main body is rendered. The problem that we face is: How do we extract this navigation out and give it the models it needs to render everything?
Let's extract the navigation into it's own view. Grab the navigation HTML and paste it into a new view called __Navigation.cshtml_ and put it under ~/Views/Partials
.
_Navigation.cshtml
<div class="navbar">
<ul class="nav">
<li><a href="#">Products</a></li>
<li><a href="#">Recipes</a></li>
</ul>
</div>
Create a new controller called PartialsController. Create a new action to call our navigation.
PartialsController.cs
[ChildActionOnly]
public class PartialsController : Controller
{
public ActionResult Navigation()
{
return PartialView("_Navigation");
}
}
Update our Layout to call the navigation.
_Layout.cshtml
<body>
@Html.Action("Navigation", "Partials")
@RenderBody()
</body>
Now our navigation is separated out into its own partial view. It's more independent and modular and now it's much easier to give it model data to work with.
Suppose we have a few models such as the ones you mentioned.
public class Product { //... }
public class Recipe { //... }
Let's create a view-model:
NavigationViewModel.cs
public class NavigationViewModel
{
public IEnumerable<Product> Products { get; set; }
public IEnumerable<Recipe> Recipes { get; set; }
}
Let's fix up our action:
PartialsController.cs
public ActionResult Navigation()
{
NavigationViewModel viewModel;
viewModel = new NavigationViewModel();
viewModel.Products = db.Products;
viewModel.Recipes = db.Recipes;
return PartialView("_Navigation", viewModel);
}
Finally, update our view:
_Navigation.cshtml
@model NavigationViewModel
<div class="navbar">
<ul class="nav">
@foreach (Product product in Model.Products)
{
@<li>product.Name</li>
}
@foreach (Recipe recipe in Model.Recipes)
{
@<li>recipe.Name</li>
}
</ul>
</div>