Rendering A Single View Using Multiple ViewEngines

One of the relatively obscure features of ASP.NET view rendering is that you can render a single view using multiple view engines.

Brad Wilson actually mentioned this in his monster blog post about Partial Rendering and View Engines in ASP.NET MVC, but the implications may have been lost amongst all that information provided.

One of the best features of this new system is that your partial views can use a different view engine than your views, and it doesn’t require any coding gymnastics to make it happen. It all comes down to how the new view system resolves which view engine renders which views.

Let’s dig into a brief example of this in action to understand the full story. Lately, I’ve been playing around with the Spark view engine lately and really like what I see there. Unlike NHaml which pretty gets rid of all angle brackets via a terse DSL for generating HTML, Spark takes the approach that HTML itself should be the “language” for defining the view.

This is not to say that one is specifically better than the other, I’m just highlighting the difference between the two.

Let’s take a look at a small snippet of Spark markup:

<ul>
  <li each='var p in ViewData.Model.Products'>
    ${p.Name} ${Html.ActionLink("Edit Product", "Edit")}
  </li>  
</ul>

Notice that rather than embedding a for loop in the code, you apply the each attribute to a piece of markup to denote that it should be repeated. This is much more declarative than using code nuggets to define a for loop.

As a demonstration, I thought I would take the default ASP.NET MVC project template and within the Index.aspx view, I would render a partial using the Spark view engine.

After referencing the appropriate assemblies from the Spark project, Spark.dll and Spark.Mvc.dll, I registered the spark view engine in Global.asax.cs like so:

protected void Application_Start() {
    ViewEngines.Engines.Add(new SparkViewFactory());
    RegisterRoutes(RouteTable.Routes);
}

I then created a small spark partial view…

<div class="spark-partial">
    <if condition='ViewData.ContainsKey("Title")'>
        <h1>${ViewData["Title"]}</h1>    
    </if>
    
    <p>${ViewData["Message"]}</p>
    <p>${Html.ActionLink("About Page", "About")}</p>
</div>

… and added it to the appropriate directory. I also added a bit of CSS to my default stylesheet in order to highlight the partial.

views-spark-partial

In my Index.aspx view, I added a call to the Html.RenderPartial helper method.

<p>This is a WebForm View.</p>
<p>But the bordered box below, is a partial rendered using Spark.</p>
<% Html.RenderPartial("SparkPartial"); %>

And the result...

spark partial view result

When we tell the view to render the partial view named “SparkPartial”, ASP.NET MVC will ask each registered view engine, “Hey, yous happens to knows a partial who goes by the name of SparkPartial? I have some unfinished bidness wid this guy.”

Yes, our view infrastructure speaks like a low level mobster thug.

The first view engine that answers yes, gets to render that particular view or partial view. The benefit of this is that if you create a partial view using one view engine, you can reuse that partial on another site that might use a different view engine as its default.

If you want to try out the demo I created, download it and give it a twirl. It is built against ASP.NET MVC Beta.

What others have said

Requesting Gravatar... Mike Brown Nov 16, 2008 2:22 PM
# re: Rendering A Single View Using Multiple ViewEngines
I was wondering if this was possible. That's amazing. So does that mean I can leverage this to slowly migrate from webforms to MVC? Also, which do you recommend keep Webforms and host MVC inside or move to MVC and host Webforms inside?
Requesting Gravatar... haacked Nov 16, 2008 2:39 PM
# re: Rendering A Single View Using Multiple ViewEngines
@Mike Not sure how this helps in migrating from WebForms to MVC. The view engine I referred to is the WebFormViewEngine which is part of ASP.NET MVC.

This view engine makes use of WebForms only to render views. You still don't get PostBack or ViewState etc... with this view engine. At least not in any supported fashion. :)
Requesting Gravatar... Ayende Rahien Nov 16, 2008 2:55 PM
# re: Rendering A Single View Using Multiple ViewEngines
Haack,
The problem is that while this is techincally interesting, in practice this isn't something that is used very often. Trying to introduce several view engines in a project is a rare edge case, because of the mental complexity involved.
Requesting Gravatar... Jonathan Carter Nov 16, 2008 7:06 PM
# re: Rendering A Single View Using Multiple ViewEngines
Spark brings back bad memories of writing ColdFusion for a living.
Requesting Gravatar... ANaimi Nov 16, 2008 8:27 PM
# re: Rendering A Single View Using Multiple ViewEngines
Spark looks like the solution to all my spaghetti looking views.
I did see and try Spark before, but I refused to use it for a real project because having a ".spark" iconless extension is just too strange. Is there a way to make VS2008 support .spark just as good as it supports .aspx? (with all the intellisense and everything).
Requesting Gravatar... huey Nov 16, 2008 8:44 PM
# re: Rendering A Single View Using Multiple ViewEngines
@Ayende

Not sure what you mean by problem. The first line of the post is:

"One of the relatively obscure features of ASP.NET view rendering is that you can render a single view using multiple view engines."

That seems to go hand in hand with what you said about not being used often in practice.
Requesting Gravatar... Josh Nov 16, 2008 9:52 PM
# re: Rendering A Single View Using Multiple ViewEngines
Interesting, but I don't really see where this would ever be used. I would think a development team would stick to one view engine. Unless there was some technical advantage in specific cases that would either require or make using a different view engine a valid.
Requesting Gravatar... Dan F Nov 17, 2008 12:28 AM
# re: Rendering A Single View Using Multiple ViewEngines
This is mad cool Phil!

Sure, many people might not use it, and you could potentially bend your brain using different view engines, but the fact that you *can* do it is hella cool. I'd like to think that the 4 people out there smart enough to work in more than one language at once are giving you high fives and toasting in your honour.
Requesting Gravatar... Sergio Pereira Nov 17, 2008 5:28 AM
# re: Rendering A Single View Using Multiple ViewEngines
From what I've seen, another problem is the different ways the view passes data to the partials or how/if the partials have visibility to the view's local variables.
I mean, it's very possible that you cannot just change the engine of the partial and leave the RenderPartial("partialname") untouched.
Sidenote: Spark is interesting but, as @Jonathan said, above brings some cold-confusion with it. It's not spaghetti code, probably ravioli or tortelini code.
Requesting Gravatar... Mike Brown Nov 17, 2008 6:43 AM
# re: Rendering A Single View Using Multiple ViewEngines
So this would be more useful in like a composite app scenario where one is using components made by different teams or vendors in their view engine of choice. So for example if someone had a nice forum application written with Spark, I would be able to combine it with a blog engine written with MVC to make a unified website.
Requesting Gravatar... haacked Nov 17, 2008 8:55 AM
# re: Rendering A Single View Using Multiple ViewEngines
@Mike exactly.
Requesting Gravatar... Eric Nov 17, 2008 9:37 AM
# re: Rendering A Single View Using Multiple ViewEngines
How specifically does it resolve the correct View Engine? Is it based on the physical file extension? Sounds like a bit of overhead to query the registered views for each Render() or RenderPartial() call. This almost feels like it should be something registered in a web.config file of a subdirectory if you're truly trying to accommodate the ability of "dropping" in application components (like a forums or blog module). That way your original web application which only uses ViewEngine XXX doesn't have to incur a penalty of resolving View Engines that it doesn't use. Maybe I have everything backwards?!
Requesting Gravatar... Louis DeJardin Nov 17, 2008 10:01 AM
# re: Rendering A Single View Using Multiple ViewEngines
Haack, very cool. Maybe some simple standards will emerge for modular MVC site architecture. Use case for MEF?

@ANaimi I looked into what it would take to provide a language extension for VS at one point. It's possible of course, but in the end will probably take more effort than writing a custom engine in the first place. Personally, I use the built-in xml editor.

@Jonathan, @Sergio I've never seen cold fusion, but I've heard that reaction before. It's been compared to other template engines too, like Genshi (genshi.edgewall.org/.../xml-templates.html) and Kid (http://kid-templating.org/language.html)... Is that a bad thing? Most html template engines end up solving the same problems, so similarities are kind of unavoidable.

Requesting Gravatar... haacked Nov 17, 2008 12:02 PM
# re: Rendering A Single View Using Multiple ViewEngines
We give the view engines a view name, such as "Foo". The view engines are each responsible for figuring out whether or not they can render that view.

In our case, we will implement caching to try and ensure high performance.
Requesting Gravatar... Steve Nov 17, 2008 12:13 PM
# re: Rendering A Single View Using Multiple ViewEngines
Very cool stuff - I do see where it could also be useful if a team decides to move to a new view engine, the changes could be incremental without a complete rewrite
Requesting Gravatar... Gauthier Segay Nov 17, 2008 4:24 PM
# ViewEngine interop
Brillant, that's the CLR of view rendering pipeline :)

@Ayende & all: I agree that in most cases it will not be used, but I can see a common usage for this: when you would share some views/parts between projects that don't necessarily use the same view engine, then you can mixin all theses stuff without rewrite
Requesting Gravatar... mikenz Nov 19, 2008 11:11 PM
# re: Rendering A Single View Using Multiple ViewEngines
That is cool. It makes the decision to adopt a particular view engine not such a huge deal. For example you might write some pieces in nhaml and then discover down the track that it would be easier/more flexible/better to write other pieces in webformsview. I've not used nhaml but it would be interesting to try it, i like the concept.
Requesting Gravatar... Anoop Jun 11, 2010 6:00 AM
# re: Rendering A Single View Using Multiple ViewEngines
Following the thought process, I just created a CompositeViewEngine that can render both aspx/ascx (by using the WebFormViewEngine) and *.view.tt files (using a custom T4View I wrote).

Details: Creating a custom View Engine for ASP.NET MVC leveraging Text Template (T4) engine for rendering the view

amazedsaint.blogspot.com/...

What do you have to say?

(will show your gravatar)
Please add 2 and 6 and type the answer here: