I’ve been running silent for a little while because of some project work at the office which has kicked up. There are a lot of things going on and I’ve been recharging on the nights and weekends. But it’s been a few weeks since I posted anything so I thought I would throw out something that was kinda interesting last week.

One of the areas of the project involves transforming a document for display that’s stored in a non-html xml dialect. It’s something which has been implemented in xsl since the last millenium but the current requirements stretch the use of that technology past it’s breaking point. You’re not able to produce links with mvc’s helpers, you can’t yield control to render media or widgets, etc.

You can overcome those types of challenges of course, but it’s a good place to take a moment and explore the alternatives. This blog post is about one of those alternatives we decided against. It’s really cool but seemed far too tricky remain practical over a long period of time.

The idea in general goes like this. The entire Spark template becomes nothing more than a simple csharp function. If you wrap chunk of the template with some code to start and end an anonymous function then you can call that action at any time. That has the effect of calling into that closure to render whatever it contained.

Like this:


#Action<XmlNode> doRoot = node => {

<p>This is showing the node ${node.Name}</p>

#};

<p>Now I'm going to call that action.</p>

#doRoot(doc.DocumentElement);

Add to this the idea of a rule as a delegate pair of a boolean predicate and a rendering action. Then have a rule table to hold them and you can throw some nodes at the table to run the appropriate lambda action. Which could at that point call macros, use helpers, recurse deeper into the document against the action table, and you’ll work your way through the entire document this way.

At the bottom of the view you would kick off the root element:

<viewdata model="XNode"/>
#rules.Dispatch(Model);

And the action would simply provide the document.

public ActionResult Invoice(string id)
{
    var doc = XDocument.Load(Server.MapPath("~/App_Data/" + id + ".xml"));
    return View(doc.Root);
}

A working copy of this ActionSample (zip) is available for download if you would like to see it work. But I wouldn’t recommend you go down this road.

You leave yourself wondering too many things. For example, if xslt was a problem how is re-implementing a lightweight version of it the solution? This gives way too much responsibility to the view in a way that’s virtually untestable. In the end this sample would be much better if there were structured classes to model the invoice. That way you could unit test the class which parsed the document into the model, and the view becomes a much simpler case of turning a model into html.

But that’s why you explore alternatives. The first thing you try won’t always be the best idea.