MVC ComponentController vs. ViewUserControl

UPDATE: The component controller was removed from the MVC framework before the RTM release. For an updated version of this post, click **here.**

At some point when creating a web app, you're going to want some reusable UI components.  This might be because you want the same visual UI snippet repeated more than once on a single page or it might be because you want to use the same component on multiple pages.  In a traditional ASP.NET web app, typically you would use a User Control for this type of thing.  In MVC you still have the option of using a User Control but you also have the option of rendering your UI snippet with a ComponentController.  So the question is, when do you use which?  There are pros and cons to each.

The most common scenario for a user control is that you pass in the Model from the containing view page.  For example, consider a AddressEditor user control that you use multiple times on a page to edit Contacts - once for Home address and once for Work address.  It might look like this:

 <%=Html.RenderUserControl("~/Views/Home/AddressEditor.ascx", new AddressViewData(ViewData.Model.Contact.HomeAddress))%>

This is fine for those simple cases but what happens when you want your user control to have its own self contained logic?  For example, what if you're buildng a portal or a portal-like website where you want to have several self-contained "widgets" in your page.  You don't want the parent controller having to keep track of the models for 10 different widgets and then have to pass them in to each one.  A good answer to this is to use a ComponentController rather than a View user control.  A ComponentController can render its own views and the containing page can just look like this:

<div id="firstWidget" class="widget">
    <%=Html.RenderComponent<MvcWidget.Controllers.WidgetCompController>(c => c.Widget1()) %>
</div>

In this case, the controller class basically looks like most any other controller class with the exception that it inherits from ComponentController:

public class WidgetCompController : ComponentController
{
    public void Widget1()
    {
        IWidgetManager widgetManager = new Widget1Manager();
        List<Foo> list = widgetManager.GetFooData();
        RenderView("Widget1", list);
    }
}

However, there still are some uses for view user controls here.  Let's say you want to render your widgets via an AJAX call.  One feature of the "normal" MVC controllers is that the views rendered can be either aspx or ascx.  Rendering an ascx user control from an MVC Controller would be a good choice when you want to implement the AJAX HTML Message Design Pattern where you're returning only an HTML snippet from the server rather than an entire page.  In this case, we can render our user controls with an AJAX jQuery call.  So if we had a couple of HTML divs (called "secondWidget" and "thirdWidget") and a WidgetController class with actions methods Widget2() and Widget3(), we could simply implement this simple jQuery function:

<script type="text/javascript">
    $(function() {
        $('#secondWidget').load('/Widget/Widget2');
        $('#thirdWidget').load('/Widget/Widget3');
    });
</script>

These are some rough ideas to get you started.  The complete code sample can be downloaded here.

Tweet Post Share Update Email RSS