views:

982

answers:

2

There has been a lot of discussions on View-engines for ASP.NET MVC and some criticisms against the inline "tag-soup" with for-loops and thing like it.

The alternative or complement has been to use HTML-helpers, which are just inline method-calls.

When I look inside ASP.NET MVC's HTML-helpers today they are using a class called TagBuilder.

My proposal is to use LINQ to XML to get strongly typed and correctly formatted (X)HTML:

XDocument output = new XDocument();
XElement root = new XElement("div",
    new XAttribute("class", "root_item"));

XElement iconImage = new XElement("img",
    new XAttribute("src", ResolveUrl("~/image.gif")),
    new XAttribute("alt", "This is an image"));

XElement link = new XElement("a",
    new XAttribute("class", "link"),
    new XAttribute("href", "http://google.com"),
    new XText("Link to Google"));


root.Add(link);
root.Add(iconImage);
output.Add(root);

I like it because it's like the strongly typed controls in WebForms, where you can new-up a Button and add it to another control's Control-collection.

Are there any apparent problems or limitations in this?

A: 

I can think of two problems to the above mentioned method. First,

XElement iconImage = new XElement("img",
new XAttribute("src", ResolveUrl("~/image.gif")),
new XAttribute("alt", "This is an image"));

Referring to what you write above, we can have something like:

<img src=<%=whatever%> alt=<%=whatever%> />

This might be personal judgement or what, but I certainly vote the later one more "human" readable. Right, using LINQ 2 XML might get rid of the weird <% } %> that wandering around in my aspx pages, but at the same time, you make those "good boys" looks clumsy.

Second might come with performance issue. I think parsing and executing LINQ 2 XML could be quite slow, although I don't have any data regarding this.

Personally I am still experimenting the MVC framework, it feels like getting back to old days like ASP or PHP 3.X, since almost all the interactive parts are explicitly handled, instead of the window/GUI-OOP oriented ASP Dot Net Framework. I think the main reason I will use MVC is that it can guarantee the best quality client-side HTML codes..

xandy
In my experience, Linq to XML construction is blindingly fast - it'll never be your bottleneck. Were performance relevant (hypothetically), in general, string manipulation is quite expensive - it'll often be cheaper to construct an xml tree using objects directly than to perform string manipulations on a serialized tree (note that elements with the same name can for instance share the same string reference to that name). 'course, ASP.NET compiles the views, so it's avoiding run-time parsing +string formatting too...
Eamon Nerbonne
+3  A: 

This is a great idea! The only problem I see with it is the use of C#. ;) VB.NET has much better support for producing XML via it's XML literals feature.

The code you list in your question could be written like this in VB.NET. (With the addition of the text "This is a link" as your example didn't contain any text within the a element.)

Dim root = <div class="root_item">
               <img src=<%= ResolveUrl("~/image.gif") %> alt="This is an image"/>
               <a class="link" href="http://google.com"&gt;This is a link</a>
           </div>

There are still <%= ... %> tags, but they are checked for validity at compile time. If this code was made the return value of a function that returned type XElement, then that Xhtml snippet could be reused elsewhere in the site.

I have a project on CodePlex that uses VB.NET XML Literals as a custom ASP.NET MVC View Engine at http://vbmvc.codeplex.com. It is based on code by Dmitry Robsman, who is Product Unit Manager for ASP.NET at Microsoft. Views are VB.NET classes and Master Pages are base classes. You new-up Partial view classes instead of referencing them by a name string, so that is also an additional compile time check. Instead of the HtmlHelper class, which returns strings, there is an XhtmlHelper class which returns XElement and works similarly to what you have proposed.

Dennis Palmer
Added text-node to code example. Thanks for the reminder.
Seb Nilsson