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?