While I was preparing another demo, I ran into an interesting problem that hadn’t occurred to me before. I was building a sample e-commerce site and thought it would be nice to always display the category list on the left hand side of every page.

The first way I could think of was always passing that data in every action method, but that seemed to be a brute force approach that lack any sort of elegance (not to mention poor application design).

So, since I’m using a master page (which most MVC projects are), the best way would be to place that data in there. However, I don’t want to hardcode it, so I would like to fetch the list of categories from the database.

Problem is…how do I pass data to the master page. The master page is not a common view and we have no specific controller action methods for it. In fact, the master page is rendered every time we return a view from an action method. Which brings us back to the original suggestion: should I pass the data in every action method?

Well, after playing around a bit, I found that the answer is “kinda”…

I absolutely refused to add a line of code to every action method passing that information in the ViewData dictionary. Not only it’s boring to keep repeating myself, it’s also against the DRY principle (Don’t Repeat Yourself).

So what to do? I’m sure there are other solutions but this one seems very elegant and in line with the best practices: we use inheritance.

Create a new class under your controllers folder and use the following code:

public class MySiteController : Controller

{

    public NorthwindEFEntities nw;

 

    public MySiteController()

    {

        nw = new NorthwindEFEntities();

        ViewData["categories"] = from c in nw.Categories

                                 select c;

    }

}

Notice that this new class inherits from the Controller class, just like any other controller you’d create. The trick now is to change your controllers to inherit from MySiteController instead, so that the category information is injected in every action method execution.

public class HomeController : MySiteController

{

    public ActionResult Index()

    {

        return View();

    }

}


So, we can implement our action methods as usual without worrying with the category information as that is being already passed on through the ViewData dictionary.

Of course, we need to change the master page so that it renders this information. Locate the ul element named “menu” and change it to this:

<ul id="menu">             

<% foreach (var c in (IEnumerable<MvcApplicationWithInheritance.Models.Category>) ViewData["categories"])

   {%>

    <li><%= Html.ActionLink(c.CategoryName, "Category", "Home", new { id = c.CategoryID },null) %></li>

<%} %>

</ul>


Now, if you browse your site, the menu will no longer display the links to Home and About as usual, but will instead appear as this:

 menu with category list

If you click on any of the buttons, you will be redirected (according to the parameters we placed on the action link) to http://<yoursite>/Home/Category/<categoryID>. That allows us to implement a simple action method to display the products in that category:

public ActionResult Category(int id)

{

    var productList = from p in nw.Products

                      select p;

 

    return View(productList);

}


Notice that instead of creating the NorthwindEFEntities object to make the query, I can reuse the one we created in the base class.

Until next time!