Someone's having a firework party just down the road. Not sure why -- I know it's the Fourth of July, but this isn't America! 2 hrs ago

October 2008

27
Oct

Unit testing URL generation and Html.ActionLink in ASP.NET MVC

As I’ve been working with ASP.NET MVC lately on a couple of websites, the one thing I’ve found the hardest to get used to is the routing engine. Getting it set up to parse your URL to give you a route is straightforward enough — the hard, and often confusing, part is the helper functions such as Html.ActionLink that generate URLs from route data. Sometimes the URLs look different to what you expect, but they work nonetheless; at other times, they are just plain wrong, especially if you have a complex routing table set up.

The logic behind constructing the URLs is fairly complex, and depends not only on the route data that you pass into the ActionLink method, but also on the route data that comes from the original URL that you used to access the page in the first place. If you have routes that are any more complex than the fairly trivial examples that come in the out of the box application templates, it can quickly get pretty confusing. Furthermore, chopping and changing the order in which you register your routes can get things totally out of kilter, so you really need a comprehensive suite of unit tests to be able to tackle it with any hope of retaining your sanity whatsoever.

The subject of unit testing your routes to make sure that you are getting the correct route data out of them has been covered by Phil Haack and Stephen Walther, so I won’t go into any further detail about that aspect here. However, I’m going to expand a bit on Phil’s methods to show how to test things the other way round: making sure that when you pass some route data in to Html.ActionLink, it gives you the URL that you expect.

As with Phil’s sample code, I’ve used Moq to mock the context, request and response, and I’m using Eilon Lipton’s technique of using an anonymous class as a dictionary literal. You can download the code as a Visual Studio solution if you want to get up and running with it straight away. Here’s a quick look at the methods that do all the work:

string FindUrlToRoute(string currentPage, object routeData)
{
	var mockContext = new Mock<HttpContextBase>();
	var mockRequest = new Mock<HttpRequestBase>();
	var mockResponse = new Mock<HttpResponseBase>();

	mockContext.Expect(c => c.Request).Returns(mockRequest.Object);
	mockContext.Expect(c => c.Response).Returns(mockResponse.Object);
	mockRequest.Expect(c => c.AppRelativeCurrentExecutionFilePath)
		.Returns(currentPage);
	mockResponse
		.Expect(c => c.ApplyAppPathModifier(It.IsAny<string>()))
		.Returns((string s) => s);

	var route = routes.GetRouteData(mockContext.Object);

	var requestContext 
		= new RequestContext(mockContext.Object, route);
	var url = new UrlHelper(requestContext);
	var dict = new RouteValueDictionary();

	foreach (PropertyValue property in GetProperties(routeData)) {
		dict[property.Name] = property.Value;
	}

	var path = routes.GetVirtualPath(requestContext, dict);
	return (path != null ? path.VirtualPath : null);
}

protected void AssertRouteUrl(string currentPage, string expectedUrl, 
	object routeData)
{
	var str = FindUrlToRoute(currentPage, routeData);
	Assert.AreEqual(expectedUrl, str, "URL was wrong!");
}

The sharp eyed among you will note that I am not actually calling Html.ActionLink() itself, but a different method, routes.GetVirtualPath. When you construct an action link, or when you use Url.Action(...) in your views, ASP.NET MVC ends up one way or another running your data through the GetVirtualPath method of your route table. You have to mock the Response.ApplyAppPathModifier method — a fact that wasn’t immediately obvious, and it took a bit of digging around in the System.Web.Routing assembly with Reflector to find out exactly what needed to be done.

You can then check to see whether you are getting the correct URL out by calling in to the AssertRouteUrl method as follows:

[Test]
public void TestBlogPath()
{
	AssertRouteUrl(
		/*
		 * currentPage is an app-relative URL, so it must be
		 * prefixed with a tilde (~). Note that this is required
		 * and must point to a valid route.
		 */
		"~/blog/2008/10/25",
		/*
		 * expectedUrl, on the other hand, is an absolute path,
		 * so it shouldn't.
		 */
		"/blog/2008/10/10",
		/*
		 * The route data. Note that you specify your controller and
		 * action here as the controller and action properties 
		 * respectively.
		 */
		new { 
			controller = "blog",
			action = "index",
			year = "2008",
			month = "10",
			day = "10"
		}
	);
}

Download: Unit testing route URL generation – Visual Studio solution

17
Oct

In defence of 24 hours

The Sams Teach Yourself … in 24 hours series gets a bit of a bashing from some people. The criticism is that you can’t learn to be a programmer, let alone a good one, in only 24 hours, and by publishing books with titles such as these, they cheapen our craft. People wander into a bookshop, pick up a copy of Teach Yourself PHP in 24 hours or something, and the next day they are copying and pasting SQL injection vulnerabilities from all over the web into what they hope will be The Next Facebook. Or so the thinking goes.

Now people who say this kind of thing have a valid point. You can’t learn to be a good programmer overnight — it takes years of experience, trial and error, constantly honing your skills, and so on, and I don’t think you’ll ever reach a point where you stop learning. However, I don’t think it’s fair to turn this point into a criticism of books such as the 24 hours series. To be sure, these books won’t turn you into an expert programmer in a weekend, but if you think that’s what they’re all about, you’ve completely misunderstood the title. Their aim is to give you enough knowledge to bootstrap your understanding of the subject in that period of time to a point where you can actually start to Get Things Done, and then give you a platform to build on.

Teach Yourself XML in 24 hoursIn that respect, I think they play a very important role. Whenever I come to a completely new technology, I see a mysterious black box, with everything hidden away behind a facade of whatever user interface you have, and if that happens to me as a particularly techno-savvy type, it’s certainly going to happen to lesser mortals as well. However, I often find that it just takes a little bit of an idea of what’s going on under the hood for me to get started finding my way around it in earnest. Somehow, the first part of the learning curve often seems the steepest.

There’s another reason why they’re important too. Computer programming these days — certainly, programming in the Real World — often requires you to get a handle on new technologies and languages very quickly. It’s a fast paced world, with new technologies coming out left, right and centre, and if you don’t keep up you’ll fall behind. Add a few over-enthusiastic sales guys into the mix, convincing the clients that you’re the world’s greatest SharePoint expert on the basis of the fact that you threw a default installation of MOSS 2007 onto a server and set up a couple of custom lists, and things get all the more interesting. Very often, you need to get up to speed with something in only 24 hours.

In this respect, I’ve found the 24 hours books to be some of the best introductory texts on computer programming related subjects that you can get. I originally learned XML from Michael Morrison’s Teach Yourself XML in 24 hours. I have two books on UML: Martin Fowler’s UML Distilled and Joseph Schmuller’s Teach Yourself UML in 24 hours, and I find Schmuller’s book the easier and clearer of the two to follow. It doesn’t particularly dumb the subject down either — both books cover the same material in similar depth. Given that Martin Fowler is one of the best tech writers around today, that speaks quite favourably for Joseph Schmuller.

I somehow wonder if there’s an element of snobbery involved in criticising books such as these. It seems to me that most of the criticism comes from very experienced and knowledgeable computer science-y types — the kind of people who think that Scheme is the best language to start with for teaching programming to ten year olds. It’s a bit like the world of church music: some traditionalist classical musicians get very dismissive of modern Charismatic worship albums. You can easily understand why: if you’ve spent several years studying for multiple degrees in music or computer science, no doubt working up a massive student loan in the process, you aren’t going to take too kindly to the idea that someone can be just as successful in your field without having gone to the same amount of expense and trouble.

So don’t be embarrassed about reading books in the 24 hours series. Everyone has to start somewhere with new technologies, and for getting started, these books are every bit as good as any.

01
Oct

ASP.NET MVC + jQuery – can things get any better for web developers?

Microsoft’s recent decision to include jQuery in the ASP.NET development stack is pretty exciting news. I’ve been using jQuery for a while now, and all I can say about it is that it makes JavaScript fun. You can use it to add some pretty impressive effects to your web pages with only a couple of lines of code, and you have less to worry about as far as the idiosyncrasies of cross-browser detection are concerned. In the past year or so it’s become pretty popular and even something of a de facto standard in many ways, probably best described as JavaScript’s answer to Linq. If you’re a web developer and you haven’t yet come across it, I really would encourage you to check it out — you’ll love it, even if you hate JavaScript.

Hopefully this will attract some more talent back to the .NET platform. It’s been the case for a while now that the best, most passionate web developers — the ones who come up with the all-singing, all-dancing Ajax-y websites and eye candy — have generally been shunning the Microsoft stack in favour of PHP, Django and Ruby on Rails. You can easily understand why — the web forms postback model may be good for simple, fairly generic things, but if you really want to make your website sing, it has restrictions and leaky abstractions that get in the way a lot, such as the limitation of one server-side form per page, or the convoluted id attributes that it sticks in all over the place making CSS and DOM manipulation a major headache, or the monster that is view state.

However, with the ASP.NET MVC framework on the go, we have finally got back the control over our HTML that we need, and now with jQuery forming an official part of it, ASP.NET is becoming an even more exciting prospect again. It’s especially so since in many ways you can really push the boundaries with .NET a lot further than with most other frameworks. Languages such as PHP or Ruby are good in themselves, but they do have their limitations, and it’s not a good idea to try to use them for image manipulation, or genetic algorithms, or Bayesian spam filtering, for instance — they are just too slow for computationally intensive stuff such as that, and in those cases you would need to drop down to C++. On the other hand, in C#, you can do it all in one integrated end-to-end framework, and with Visual Studio, you have what is probably the best IDE on the market to help you on your way.

I’m looking forward to seeing a lot more all-singing, all-dancing websites written in ASP.NET.