Search code examples
asp.net-mvcmodel-view-controlleruser-controlscontrollerseparation-of-concerns

Where to apply logic for a sidebar control in ASP.NET MVC


Take the example of wanting to have a "Latest news items" sidebar on every page of your ASP.NET MVC web site. I have a NewsItemController which is fine for pages dedicating their attention to NewsItems. What about having a news sidebar appear on the HomeController for the home page though? Or any other controller for that matter?

My first instinct is to put the logic for selecting top 5 NewsItems in a user control which is then called in the Master Page. That way every page gets a news sidebar without having to contaminate any of the other controllers with NewsItem logic. This then means putting logic in what I understood to be the presentation layer which would normally go in a Controller.

I can think of about half a dozen different ways to approach it but none of them seem 'right' in terms of separation of concerns and other related buzz-words.


Solution

  • http://eduncan911.com/blog/html-renderaction-for-asp-net-mvc-1-0.aspx

    This seems to address the question - even using the instance of a sidebar - but using a feature not included with MVC 1 by default.

    http://blogs.intesoft.net/post/2009/02/renderaction-versus-renderpartial-aspnet-mvc.aspx

    This also indicates the answer lies in RenderAction.

    For anyone else interested, here's how I ended up doing it. Note you'll need to the MVC Futures assembly for RenderAction.

    Basically you'd have something like this in your controller:

    public class PostController
    {
    
    //...
    
       public ActionResult SidebarBox()
       {
          // I use a repository pattern to get records
          // Just replace it with whatever you use
          return View(repoArticles.GetAllArticles().Take(5).ToList());
       }
    
    //...
    
    }
    

    Then create a partial view for SidebarBox with the content you want displayed, and in your Master Page (or wherever you want to display it) you'd use:

    <% Html.RenderAction<PostController>(c => c.SidebarBox()); %> 
    

    Not so hard after all.