The New Web App Architecture: ASP.NET MVC 3, jQuery Templating with PURE and the Json Value Provider

Over the past couple of years there has been a slow progression in the .NET web app world to fully separate out client/server interaction.  Long gone are the horrible days of ViewState and Events; MVC provided a nice step to better structure web applications for powerful Web 2.0 experiences.  But the barrier between client and server interaction has never really been clean-  MVC markup has always been littered with C# code and there hasn’t always been widespread tools available to easily build desktop class applications in the browser.  Sure, spark and haml provide alternatives, but these are essentially make a core problem easier to bear.

With the new preview of MVC 3, we can eliminate that core problem of server based html rendering: the built in Json Support via the JsonValueProviderFactory along with some jQuery goodies presents us with the new web app architecture: service- orientated web apps built with a rich, js based client driven by Json based services.  Using core tools of html, css, and js and not requiring the overhead of Silverlight, Flash, or JS based web frameworks.  This JSON functionality, combined with javascript templating using PURE gives us the ability to break free from the static html navigation and build dynamic apps in much more efficient ways.

ASP.NET MVC 3 and the JsonValueProviderFactory

Scott Guthrie writes about the new ASP.NET MVC 3 preview features, and among the hype is the default Json support for action methods.  In his blog post he forgets one crucial step to actually make this work, which is adding the new JsonValueProviderFactory to the global value provider factories class in the Application start method of the global.asax, like so:

protected void Application_Start()
{
	AreaRegistration.RegisterAllAreas();

	//Must add this factory explicitly (for now, at least):
	ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

	RegisterGlobalFilters(GlobalFilters.Filters);
	RegisterRoutes(RouteTable.Routes);
}

Once this is in place we can treat our controller actions as usual, even when using Json.  The serialization mechanism is agnostic (this is pretty much exactly the same as Scott’s code):

[HttpPost]
public ActionResult Search(ImageSearchInput input)
{
	//AssetSearchInput can be posted via Json
	return new JsonResult() { Data = new { ImageInfo = new Repository.ImageRepository().Search(input).Images } };
}

ImageSearchInput, with a string property of “Caption”, will be built from the Json data posted to the server by the following Ajax call:

$('#search').submit(function () {
  var input = { Caption: $('#caption').val() };

  $.ajax({url: '/Home/Search',
    type: 'POST',
    data: JSON.stringify(input),
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
        $('.imgContainer').autoRender(data);
    }
  });

  return false;
});

The server will route the request to the Home/Search method, and will serialize the posted data in the ImageSearchInput class.  As long the properties match up and are of the correct type, the deserialization will be fluid.  Notice how we don’t actually need to specify the ImageSearchInput class name when building the Json object.

Those with keen eyes may have noticed the success: callback containing the autoRender() function.  This is the PURE javascript templating engine at work.  I came across PURE when reading about the jQuery templating proposal on GitHub and was immediately drawn to its simplistic syntax.

The philosophy behind PURE is simple: instead of interleaving markup and template directives (which, to be honest, is just as bad as mixing code with markup), PURE can make assumptions about what to repeat and what to bind based on css class names and Json property names.

Let’s say I had the following json markup:

var data = {
	Image:
		{ Filename: 'mypic1.jpg', ImageUrl: '/images/mypic1.jpg'},
		{ Filename: 'agoodphoto.jpg', ImageUrl: '/images/agoodphoto.jpg'}
}

This is simply an Array with two objects in it.  Using PURE’s autoRender function, we can specify binding directives using CSS classes, building li elements and populating content as appropriate:

<ul class="imgContainer">
	<li class="Image">
		<p><img class="ImageUrl@src" /></p>
		<p class="info"><span class="Filename"></span></p>
	</li>
</ul>

Because the li has the Image css class, and we have an array of Image objects, PURE will duplicate the li contents for each element in the array.  The span tag will show the filename property because it has the Filename css class.  The src attribute of the img tag will get the ImageUrl property because it is using the @ directive, which simply says “put the ImageUrl property in the src attribute”.  PURE can easily get it’s own post, but the point is simple:  we no longer need to generate server side html for displaying complex content.  Even though this has always been possible before, it hasn’t been as fluid as PURE.  Another primary benefit is that we can send incredibly complex Json data back to the client which can update numerous page snippets.  Orchestrating multi-updates, like a detail page, shopping cart, or other areas simultaneously has not been trivial, but because we have json data and templating these complex scenarios are easily achievable.

Gotchas

Client side templating is dangerous- you don’t really know how well the client’s computer it is.  Be mindful of performance and memory requirements, and ensure you’re targeting the right browsers.  Chrome’s V8 javascript engine has evolved remarkably well in handling javascript intensive applications.

As for the MVC 3 preview, I wish we saw dynamic results from controllers: specifically, one action to return either  Json, Xml, or Html output based on some request directive.  This is possible with various ActionResults or ActionFilters, and there’s some functionality already out there to do it, but it isn’t as nice as Ruby on Rail’s respond_to functionality.  A single action supporting multiple outputs will allow developers to easily target various platforms and scenarios in the web world.

Final Thoughts

Despite techniques of Json serialization and jQuery templating already existing in the ecosystem, it has never been as robust and integrated as with the new MVC 3 support (sure, Rails has had this for a while).  Combining this functionality with templating tools like PURE will open up new development paths for rich web applications based entirely on standard tools like javascript, html, and css without relying on chunky js frameworks.  Keeping core tools simple means having the ability to build out specific functionality as needed, rather than getting boxed into more complete frameworks.  From the managing side, it also keeps the available pool of developers large so you’re not requiring knowledge on a specific tool.  Play around with these tools and see what you can do!


Shout it

  • Pingback: Tweets that mention The New Web App Architecture: ASP.NET MVC 3, jQuery Templating with PURE and the Json Value Provider | Adventures in HttpContext -- Topsy.com

  • http://beebole.com Mic

    Hi Michael,

    This is a very nice usage of PURE.
    When I see your post, I think I could have tried harder to use the autoRender in our web app.
    I switched rather quickly to the declarative mode of PURE (directives).

    One thing that you may know already; You can use the methods: compile + render, instead of autoRender.
    This allows to render the same template again and again, even if the original HTML is destroyed.

    Thanks for promoting our lib.

  • http://www.michaelhamrah.com Michael

    Hey Mic, I’m happy to give exposure to PURE. As you know, I’ve been on the PURE boards to learn more, and am looking to put together some PURE specific posts. I’m torn on the ease-of-use of autoRender with the power of compile vs. render. In growing out some apps using PURE, I think the directives are the smarter way to go.

  • James Hughes

    Wait what?

    “ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());”

    For my first MVC3 sample app I didn’t have to do this and it currently works fine.

  • Pingback: ASP.NET MVC Archived Buzz, Page 1

  • Jay

    Yeah, you could do this with the MVC 2 futures, which is now part of MVC 3.

    http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx

    Also, regarding the second gotcha, with the MVC 2 futures you can simply decorate your ActionResults with [WebApiEnabled] (in Microsoft.Web.Mvc.Resources) and you will get JSON (or XML, depending on what you pass in) in return as well. Not sure if this made/makes it into MVC 3 though.

  • http://beebole.com Mic

    @Michael If you check the directives but still want some automation, you can think a directive as a JSON that can be dynamically generated instead of a static one. And as they are live (not stringyfied), you can use closures and pass functions as parameters.
    By using some conventions, this could be a good compromise between the simplistic autoRender and the static directives.

  • http://blog.runxc.com Bret Ferrier @runxc1

    I wonder if one of the Issues that you are going to run into with the PURE js templating is the fact that it uses the same kind of syntax as the new default view engine in MVC namely the Razor engine. It looks like the two might be stepping on each others toes though if you pull it off right perhaps you could get Views to work both with the Model and with a JSON object.

  • Pingback: Nina, My New Favorite Web (Micro)Framework | Adventures in HttpContext

  • Pingback: Blue Ray Plus - Latest Technology News