Apr 30

Out of the box, ASP.NET MVC uses weakly typed extension methods to generate various HTML elements (inputs, check boxes, select lists, etc). By weakly typed I mean they require strings, which are actually strings based on the properties of your view model. For instance, given this view model:

public class OrderViewModel
{
	public int Quantity { get; set; }
	public bool ApplyDiscount { get; set; }
}

You’d generate an input box for the quantity, using the standard HTML helper extensions, like so:

<%= Html.TextBox("Quantity") %>

Ew, strings. That’s so .NET 1.1, right? With .NET 3 we get Expressions and lambdas. Now lambdas are just more concise ways to define delegates (methods you can pass around as variables), so they’re nothing really new new. Expressions, for the purposes of this post, allow you to specify, in a compile safe manner, which property you want to use for something, which can then be parsed during run-time to get the property’s string name (suffice to say Expressions can do much more and form the foundation for LINQ To SQL). For instance, what if, instead of using the above TextBox method for the quantity product, we could do this:

<%= Html.TextBox(x => x.Quantity) %>

Rest assured it’d produce the same HTML in the end while giving us the type safety we’re looking for. What do I mean by type safety? I mean you can preform a rename refactoring on Quantity and you’d also rename the usage in the view (Resharper will actually do most rename refactorings on strings too, but it’s not 100% reliable – it’s a guess at best). That means less chance of something breaking (especially something you won’t find out about until runtime when your customers are in there), which means high quality, which is just cool.

OK, so we’re aware of what a strongly typed view would look like and the benefits of it. How can we do it? Well, we can roll our own (which has been done in a few places very nicely but is quite a bit of work), we can use the basic ones provided in the MVC Futures assembly (which provide pretty much the same functionality, look, and feel as the existing ones in System.Web.Mvc but with the strong typed goodness), or we can use the ones included in the open source MVC Contrib project. This is a project that provides a lot of really nice “glue” to help out with any ASP.NET MVC project, taking advantage of many of the extensibility points built into the framework already.

Unfortunately, it looks like the latest release download doesn’t include the Fluent Html assembly (fluent html is what most people use when referring to this strong typed HTML tag output because it’s a “fluent” interface, as you’ll see shortly). You’ll need to build the project from source, so grab the latest copy at http://mvccontrib.googlecode.com/svn/trunk, then run the ClickToBuild batch file in the root folder. It’ll do it’s thing, then when it’s finished you’ll need to grab the following files in the newly created buildnet-3.5.win32-MVCContrib-release folder:

  • MvcContrib.dll
  • MvcContrib.pdb (optional – provides line numbers if you need to debug anything)
  • MvcContrib.xml (method and parameter comments)
  • MvcContrib.FluentHtml.dll
  • MvcContrib.FluentHtml.pdb
  • MvcContrib.FluentHtml.xml

In the next part I’ll go over the basic usage of the library, then in the third part I’ll cover some of the cooler aspects, like tying it into validation and other things.

Part 2 and Part 3.

Apr 30

We’re using ASP.NET MVC on my current project at work, and we’re heavily exploring jQuery and other client side tools for AJAX effects. One of the first areas where we needed it was a screen where the user enters a zip code and a list of various values get returned based on that code. We got it working just fine rather quickly, but only by slinging some nasty looking spaghetti code in the JavaScript, so we started looking around for a possible solution.

One of the first things we stumbled on was jTemplates, a client side templating plug-in for jQuery. Awesomeness. So lets say we have the following action on our Employee controller:

public ActionResult LookupPeopleByZip(string zip)
{
	var peopleInZip = new List
		{
			new Person
				{
					Name = "John",
					Age = 25
				},
			new Person
				{
					Name = "Jane",
					Age = 30
				},
			new Person
				{
					Name = "Mike",
					Age = 21
				}
		};
 
	return Json(peopleInZip);
}

This creates a simple list of Person objects, uses the built-in ASP.NET MVC JSON result builder to serialize the object graph, and returns that JSON string. Now, let’s look at one possible, and probably more common, way to display these results in a table from an AJAX call:

<script type="text/javascript">
	$(document).ready(function() {
		$("#search").click(function() {
			var url = 'http://localhost:35125/Standard/LookupPeopleByZip/' + $("#zipCode").val();
 
			$.getJSON(url,
				function(allMatches) {
					var matchCount = 0;
 
					var tableHtml = '<table>' +
									'<tr>' +
										'<th>Name</th>' +
										'<th>Age</th>' +
									'</tr>';
 
					for (var i in allMatches) {
						matchCount++;
 
						tableHtml += '<tr>' +
									'<td>' + allMatches[i].Name + '</td>' +
									'<td>' + allMatches[i].Age + '</td>' +
								 '</tr>';
					}
 
					tableHtml += '</table>';
 
					var headerHtml = '<h3>Matches: ' + matchCount + '</h3>';
 
					$("#searchResults").html(headerHtml + tableHtml);
				});
		});
	});
</script>

When the search button is clicked, we use jQuery’s getJSON method to call out to our action depicted above. The resulting JSON string is constructed into an object graph and passed into our call back method (named allMatches above). We then piece meal our HTML together, looping through the object as needed and writing out the properties.

In the solution download at the end, you’ll see it runs just fine. Snappy and everything. Damn that’s some ugly Javascript code though, isn’t it? This is all for a very simple two column table – just imagine something of even moderate complexity here. Instead, let’s take a look at the jTemplates solution:

<script type="text/javascript">
	$(document).ready(function() {
		$("#search").click(function() {
			var url = 'http://localhost:35125/JTemplates/LookupPeopleByZip/' + $("#zipCode").val();
 
			$.getJSON(url,
				function(allMatches) {
					$('#searchResults').setTemplateURL('/Content/ResultTemplate.html');
					$('#searchResults').processTemplate(allMatches);
				});
		});
	});
</script>

Just a wee-bit smaller, wouldn’t you say? This code is mostly the same as the original, but instead of building the needed HTML template inline, it uses the jTemplates provided methods on the jQuery selector to set the location for our template, and execute it with our allMatches collection. The template referenced above, ResultTemplate.html, is a basic HTML snippet intermingled with a very minimalistic script like language that jTemplates parses out and updates appropriately:

<h3>Matches: {$T.length}</h3>
 
<table>
	<tr>
		<th>Name</th>
		<th>Age</th>
	</tr>
 
	{#foreach $T as match}
		<tr>
			<td>{$T.match.Name}</td>
			<td>{$T.match.Age}</td>
		</tr>
	{#/for}
</table>

The syntax is actually pretty similar to the Spark view engine. It simply loops through the passed in parameter ($T) and prints out the needed properties. Notice there’s a few extra properties dangling off the parameter too, such as length, used to show the match count at the top.

That’s pretty much the basics. Sort of an output only MVC pattern for Javascript (with the JSON return being the model, the return call method being the controller, and jTemplates providing the view engine). If you take a look through the jTemplates site you’ll see there’s quite a bit more to it if needed. Its come in handy in a few places on our project so far. Grab the sample solution here.

Apr 8
Freedom or mentoring?
icon1 Darrell Mozingo | icon2 Musings | icon4 April 8th, 2009| icon36 Comments »

Let’s take a hypothetical here and say you’re looking at two jobs. They’re at roughly similar companies which we’ll call Company A and Company B (I know, I know, original, right?). You’d be working on similar projects at either and they both have comparable co-workers. For all intents and purposes they’re equal, save for one glaring difference:

  • Company A gives you more freedom to “explore”. You’re more or less given time to read up on things, try new technologies & methodologies knowing full well some will fail and basically waste time (and given some extra slack in your schedule to compensate), get some extra training here and there, and not have a pink slip waived in front of you if you happen to let a few bugs through to production.
  • Company B has one or more senior developers that honestly love their craft, push continous learning, and can mentor you in advanced – and “proper” – directions and techniques. Test driven development? Check. SOLID principals and their real-world application? Check. Domain driven design? Check. I’m not just talking about guys that have read up on these topics either, but that have years of experience in them and a metric crap load of failures under their belts that they’re willing to share inorder to help insure you don’t fall into them too. They take pride in all aspects of their job and won’t stand for letting things slide.

Which would you choose?

It’s tough. The benefits Company A provides could get you to the same end goal as Company B, albeit at a slower pace. Company B would presumably be stricter on slip-ups and time management, so if you’re using a technology you’re not terribly interested in or you’re taking a route you don’t agree with, there’s not much you can do without working on your dime.

You’re not guaranteed to ever reach that same end goal with Company A as you would with Company B, though. Self learning is a difficult, slippery slope. You have to encounter all those failures yourself and actually overcome them. Granted, failing for yourself teaches you something more than just hearing a warning from a mentor, but those failures take time, and I believe there’s a quote about these situations… something along the lines of “Those who fail to learn from history, are doomed to repeat it”, I believe.

Me, personally? I’m not sure. I can see it both ways, though I’ve only had the pleasure (?) of working with companys similar Company A. It’s a tough decision, and my answer probably depends on what day you ask me. I know I’d like to see what the other side of the fence has to offer though.

What’s your take?