Displaying [foo] on every page of an ASP.NET MVC application
Frequently in web applications there’s a requirement like this: “Every page should display [foo].” Where “foo” can be literally anything: a list of favorites, sponsors, news, or whatever – it’s data. In what I’ll call “normal, by a long shot” ASP.NET cases, universally displayed data will probably be encapsulated in a user control and put on a master page. The master page includes the user control on all pages, and the user control loads the data and renders it, and it was all declared Good.
The MVC world (ASP.NET “unplugged”) turns everything on it’s head. Maintaining a clean separation of concerns means the controller is responsible for ensuring the appropriate data is made available to the appropriate view. The view does not load data on it’s own, nor does it know or care where the data came from. And the view was declared Dumb.
Views aren’t really dumb, of course, they have to render data, and the MVC framework does give them some tools to help. For example, the ViewMasterPage base class exposes helpers for constructing links, accessing the view data, etc.

So what do you do in the ASP.NET MVC world when you’ve got a “user control” embedded in your master page that needs specific data? Let’s say that hypothetically speaking you’re working on a CodeCampServer project, and you need to, oh I don’t know, display a list of code camp Sponsors (ahem, “Contributors”) on every single page?
The way I see it, you’ve got three options:
1. “Global” data for global display
Data can be loaded at a low level for each and every request. Something like:
protected void Application_BeginRequest(object sender, EventArgs e) { this.Context.Items["FooData"] = new FooData(); }
The pro is that FooData will be available to every view (though not through the standard ViewData). Unfortunately if this data is expensive to compute (or even if it isn’t) it’ll be loaded for every request, no matter what. Oh, and no one in their right mind would actually do it this way.
There’s that, too.
2. Controller.OnPreAction
The main Controller class exposes a virtual OnPreAction method which offers a hook just before an action is invoked. For global data, all controllers in your application could derive from a common base controller class which loads the necessary data.
protected override bool OnPreAction(string actionName, System.Reflection.MethodInfo methodInfo) { ViewData["FooData"] = new FooData(); return base.OnPreAction(actionName, methodInfo); }
Views will be able to access the data via the ViewData property, as normal. With single inheritance in C#, a required base class just for common data can potentially cause problems.
3. Call “RenderAction” from the view
RenderAction is an extension method that allows a view to reference a Controller and Action and have the results be rendered in-place within the view.

The “Tags” controller and “Cloud” action would render a view that generated an HTML fragment that would fit within the current view. This approach has advantages of only loading data when absolutely necessary and changing your view doesn’t necessarily require changing the application code to match.
There could be questions about separation of concerns: a view is determining what data to include regardless of what it’s controller gave it. But the same is true for the other solutions as well – this is just more dynamic.
Another advantage to this approach is that if you set it up right, with no extra work your “viewlets” (the views that render fragments) can return JSON serialized data for an AJAX call, for example.
I’m pro-RenderAction, but in discussions I’ve had with people it hasn’t been as big a hit with them. What are your thoughts? Am I missing some pros or cons? Are there more options that I didn’t include? Is it really just an app-by-app decision, or is there an emerging convention that should be followed?
January 26th, 2008 at 5:11 pm
While it may be overly optimistic to hope for a technical solution, I think it’s likely there will be at least an established convention before RTM.
January 27th, 2008 at 5:08 am
A fourth option could be to use strongly named view data, and then have a base view data class which held the common data.
For expensive data, lazy loading could be implemented to ensure that only views that used the data had to pay the overhead of loading it.
January 27th, 2008 at 5:10 am
My comment above should read strongly *typed* view data, not strongly named, of course :p
January 27th, 2008 at 10:48 am
[...] Displaying [foo] on Every Page of an ASP.NET MVC Application (Aaron Lerch) [...]
February 4th, 2008 at 3:11 pm
[...] Displaying [foo] on every page of an ASP.NET MVC application [...]
February 5th, 2008 at 1:26 pm
Your RenderAction extension method has some of the same concerns as the rails folks did with components. They aren’t recommended now due to perf reasons and separation of concerns, and the rails team now favors the use of :before_filter’s (OnPreAction).
Your last example could use a UserControl instead of the RenderAction, provided the required data already existed in ViewData.
March 12th, 2008 at 12:26 pm
I was glad you took the time to blog about this. The decision here is not an easy one. I am not a unit testing expert yet so I will ask the question. What of the possible solutions above is easiest to test?
March 12th, 2008 at 12:31 pm
Some of this is a little moot with the newest MVC Preview 2 release, but given what I wrote in the post, the easiest to test would be choices 2 and 3.
Choice 2 is easy to test because you can write tests for the OnPreAction for each controller (or a base controller).
Choice 3 is easy to test because you’ve effectively “siloed” the functionality into a specific controller/action/view, which you’re already testing just like the rest.
I’m also not a unit test expert (not by a long shot) so take this with a grain of salt.
April 9th, 2008 at 11:40 am
If you need to aggregate all the data request calls, as in the case of multitier application, choice 3 is not really suitable – it could end up in a number of small calls to business logic layer. I would prefer all the data-gathering logic to happen before any view is rendered.
In classic ASP.NET, this is enabled by the DataSourceControls and the hidden asynchronous nature of DataSourceView’s Select method. One of the arguments of this method is callback delegate, that the DataSourceView calls when the data are available. You can write your own DataSourceView that defers actual executing of the data retrieval code to the point that all the DataSourceControls in page (including those in master pages and user controls) have de facto registered their data requests by calling the Select method, and you can aggregate all these requests to a single call over remote boundary. This is enabled by multiphase lifecycle of the Page class and it’s controls.
Because MVC has no tricky lifecycle (which is cool), it seems like the master page is not the right place to make any additional data requests. In my opinion, that only violates the principle of separation of concerns. So the right approach would be to find some way how to compose the controllers before the view is rendered. Creating a base controller class (“master page controller”) could be a solution, but it smells to me a bit as it limits composition.
August 13th, 2008 at 8:22 am
At 3. solution
- what do I have to refer to (set reference to, Import, etc)
to use “RenderAction” method?
I have RenderControl, RenderChildren, but there is no RenderAction…
… or i just have to upgrade?
August 13th, 2008 at 8:25 am
@estevez The RenderAction I spoke of here was custom code available from the link I gave. But it’s since been included in the MVC framework (new in Preview 4 I think). You’ll have to download and build the source from codeplex (www.codeplex.com/aspnet) to get it, but if you’re going to use that functionality I’d recommend using the baked in version.
August 14th, 2008 at 3:26 am
Thanx!
October 31st, 2008 at 8:28 am
Graet post mate. Kepp them coming….
February 24th, 2009 at 6:10 am
[...] For additional reading check out this, this and this [...]