Think about the following two (common) scenarios within an ASP.NET MVC application:
- You have an user control which displays - for example - an ad. To define which ad will be displayed some logic is necessary. You want to use this control on different places within your site, one time placed in your MasterPage, one time in a View.
- You have a portal page where each of your users can select some "portal objects" (calendar, news or whatever else). These "portal objects" will only be rendered when selected by the user. Each of this object has its only logic.
Both scenarios vary from the common way how ASP.NET MVC works. Because each of this controls will need its own model and own logic behind, you can't filfill that with handling it in the current action method of your actual controller. Each of this controls needs its own "place for business logic".
With ASP.NET WebForms the solution would propably be to put that logic in the code behind. This is also possible with ASP.NET MVC (remember, the ASP.NET life cycle is still valid), but it would break the rules.
So what should we do?
The solution is very simple but not delivered by Microsoft within the official bits. There exists a project called "ASP.NET MVC Futures" which offers a HTML helper called Html.RenderAction(). This extension offers you the complete flexibility and plays the MVC game at the same time.
How does it work?
As well as your "normal" controllers and views! Just create a method in a controller of type ActionResult and call it via Html.RenderAction(). That's it.
Sample
Controller:
1: [Authorize]
2: public class PortalController : Controller
3: {
4: public ActionResult Portlet_3_ProfileVisitors()
5: {
6: return View("~/Views/Portal/Portlets/3_ProfileVisitors.ascx",
7: UserService.GetLatestProfileVisitors(CurrentUser.ID, 4));
8: }
9: }
Control:
1: <%@ Control Language="C#" AutoEventWireup="true"
2: Inherits="System.Web.Mvc.ViewUserControl<List<Guid>>" %>
3: <% if (Model != null && Model.Count > 0) { %>
4: <table border="0" cellpadding="0" cellspacing="0">
5: <% Html.Repeater(Model, "", "", (visitorID, item) => { %>
6: <tr>
7: <td>Besucher-ID: <%= visitorID%></td>
8: </tr>
9: <% }); %>
10: </table>
11: <% } else { %>
12: Dein Profil wurde noch nicht aufgerufen
13: <% } %>
Call:
1: <% Html.RenderAction("Portlet_3_ProfileVisitors", "Portal"); %>
Summary
This feature is so useful - I don't know why it hasn't made its way into the System.Web.Mvc assembly. But I'm sure, it will. So, go and use it :-).