Although design patterns are known for reducing an entire algorithm to a single word or sentence, that doesn't always happen around the
Model-View-Controller (MVC) pattern. In general, the core idea of design patterns is that when someone says, "I use the Singleton pattern," everybody
gets the point and understands the solution adopted without further explanation. ASP.NET MVC, instead, has quite a blurred definition for being a
design pattern. Like it or not, you can find multiple definitions of MVC that share the same basic idea with some significant variations. To make an
otherwise long story short, in the original formulation of the MVC pattern (from the 1980s), the view and the model were in touch through an
event-based mechanism. In the modern definition of MVC (the definition we find implemented in the ASP.NET MVC framework), model and view are neatly
separated, and the view receives the data to work on (i.e., the view model) directly from its caller-the controller.
Design patterns are just high-level tools; when it comes to concrete implementation, you may be facing other issues mostly related to technicalities of
the underlying framework. So in ASP.NET (and web in general), two successive requests are completely independent from one another, and their output
must be regenerated from scratch. In ASP.NET Web Forms, the viewstate and the overall page lifecycle simplified much of this work, allowing developers
to focus essentially on the section of the page that has to be updated in the request. As you saw in my article last month, "Filling the View Model," in ASP.NET MVC the intentional lack of viewstate and the different page architecture force developers
to re-create the view entirely per each request.
Last month I presented a special action filter attribute that helps in splitting the core code of a request from the repetitive code required to fill a
view model. This column is dedicated to exploring an alternative approach to solve the same problem: render actions.
Controller/View Mechanics
In ASP.NET MVC, the controller is the component that deals with the request details. The controller reads the information from the request and decides
the action to take. The action produces data for the view. Next, the controller selects the next view to render and passes data to incorporate. The
basic mechanics work very well as long as the view is a thin and humble object-no processing logic, just plain rendering and binding logic.
But what if adjusting the data for the view requires some work? What kind of work? Things like retrieving data from the cache or some database,
filtering view data such as images or links per user or scenario, and loading preferences from cookies or persistent storage. What does this code
belong to?
One option is to move this code in the controller layer so that the view always receives ready-to-display data. You can use action filters (as
discussed in last month's installment of this column) to take any required code out of controller classes. Another option is adding ad hoc methods to
existing controllers or, better yet, ad hoc controllers whose only purpose in life is serving data to the views. These controllers (or methods) are
never exposed as public URLs but are exclusively invoked by the view in an internal child procedure.
What Are Render Actions, Anyway?
As mentioned, render actions are special controller methods defined only to be called back from the view. Typically, the view calls render actions to
incorporate external markup. This is markup that results from the application of processing logic-logic that you don't want to stay in the view. The
syntax of a render method is nearly the same as the syntax of a regular controller method.
A render action is a public method on the controller class. You can define a render action method to return any data, but you can only safely use it if
it returns an HTML markup string. In addition, a render action can be decorated with the ChildActionOnly attribute, which has the effect of hiding the
method to public callers.