In this recipe, we are going to take a look at how to pass data down to the master page. While we could pass data from a normal ActionResult
to the view via the ViewData
dictionary and then have the MasterPage
use that data, we won't as that creates a lot of redundant code spread out over multiple actions in the controller. We could alleviate some of this action code and move it up to the OnActionExecuted
method in our controller. However, if our master page is shared across multiple controllers, then this too wouldn't be a good solution. For that reason, we will instead create a controller base class and use that for creating the data for our master page.
BaseController
. In this base controller, we will initiate a list of data for navigational purposes.Models/BaseController.cs:
public class BaseController : Controller { public BaseController() { List<string> manufacturers = new List<string>(); manufacturers.Add("Ford"); manufacturers.Add("Toyota"); manufacturers.Add("Chevy"); manufacturers.Add("Dodge"); manufacturers.Add("Nissan"); manufacturers.Add("Mazda"); manufacturers.Add("Audi"); ViewData["manufacturers"] = manufacturers; } }
HomeController
to inherit from our new BaseController
.Controllers/HomeController.cs:
public class HomeController : BaseController
Views/Shared/Site.Master:
... <div id="main"> <%string menu = ""; if (ViewData["manufacturers"] != null) { StringBuilder sbMenu = new StringBuilder(); List<string> manufacturers = ViewData["manufacturers"] as List<string>; foreach (string item in manufacturers) { sbMenu.Append(item + " - "); } menu = sbMenu.ToString().Substring(0, sbMenu.ToString().Length - 3); } %> <%: menu %> ... </div> ...
To achieve this, we have essentially injected data that is required by our master page into the controller pipeline by inserting a controller base class. As long as our controller inherits from the base class, the ViewData
will contain the navigation data. This helps us to centralize such logic and can obviously be taken in many different directions.