In this recipe, we are going to take a look at how to render views directly within a master page. Really, this technique can be used in any view. The nice bit about this is that we don't have to concern ourselves with what data and other dependencies the other view requires to be rendered, such as rendering partial views. This allows us to easily call this view from anywhere without having to concern ourselves with the guts of the view.
ActionResult
and view in our HomeController
. We will call this new method _Categories
. (I usually use the underscore prefix for partial views and views that can only be rendered as a child using [ChildActionOnly]
.) _Categories
action, we will create a quick list of common e-commerce categories. This list will then be returned to the view by way of the ViewData
dictionary. We will also mark the action with the [ChildActionOnly]
attribute to ensure that this view can't be rendered by just anyone.Controllers/HomeController.cs:
[ChildActionOnly] public ActionResult _Categories() { List<string> navigation = new List<string>(); navigation.Add("Books"); navigation.Add("Cars"); navigation.Add("Clothes"); navigation.Add("Computers"); ViewData["navigation"] = navigation; return View(); }
_Categories
action.Views/Home/_Categories.ascx:
<% List<string> navigation = ViewData["navigation"] as List<string>; StringBuilder output = new StringBuilder(); foreach (string s in navigation) { output.Append(s + " - "); } string nav = output.ToString().Substring(0, output.ToString().Length - 3); %> <%: nav %>
Html.Action
method, which requires the view and controller to be passed in. The rest of what is needed to render the view is hidden away from us!Views/Shared/Site.Master:
...
<div id="main">
<%= Html.Action("_Categories", "Home") %>
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
...
/Home/_Categories
to see that the view can't be viewed directly.This method of rendering a partial view in line with another view is part of the MVC framework. Some people like this method of rendering data view within a view, others do not. By using this method you are allowing a view to be in charge of what it renders rather than only rendering what the controller says it can.
This method of rendering data has its upside though. As you are rendering the two views—the calling view and the partial view—separately, you can control the caching, security, and so on, separately too.