December 2008 Blog Posts
At the end of the year, it’s very common for bloggers to take a look back at their own blog and list their favorite 10 blog posts. I find that somewhat narcissistic, so you know I’m going to do that.
But before I do, I thought it would be great to list the top 10 blog posts by others I read in 2008. The only problem is, I have very bad short-term memory and I can’t seem to remember which ones I read that had a real impact on my thinking. I’ll have to try and keep better track in 2009.
So based on a cursory Google search and look through my Google Reader app, here are some of my favorite blog posts of 2008 by you all, I couldn’t even list 10. Please do comment with your own favorite blog posts, mine or otherwise of 2008.
Favorite Posts I Read
A while back, Ayende wrote up a weighted query for Subtext to determine the top posts. I updated it to only include mine published in 2008. Here are the top 5.
Milestones Moments
There are some posts that I personally liked because they represent important events that happened to me in 2008.
Ok, so maybe this post is pretty typical and doesn’t live up to the title I gave it. Oh well, I tried.
I’m sure I’m forgetting a whole lot of other important events that happened in 2008. I’m probably neglecting great blog posts that I read. But that’s the great thing about a blog, I’m confident people will point out my shortcomings in the comments to this post, and for that, I’m grateful. You all rock!
And with that, I leave you with this moment of zen, a photo taken near my house.

Dmitry, who’s the PUM for ASP.NET, recently wrote a blog post about an interesting approach he took using VB.NET XML Literals as a view engine for ASP.NET MVC.
Now before you VB haters dismiss this blog post and leave, bear with me for just a second. Dmitry and I had a conversation one day and he noted that there are a lot of similarities between our view engine hierarchy and and normal class hierarchies.
For example, a master page is not unlike a base class. Content placeholders within a master page are similar to abstract methods. Content placeholders with default content are like virtual methods. And so on…
So he thought it would be interesting to have a class be a view rather than a template file, and put together this VB demo. One thing he left out is what the view class actually looks like in Visual Studio, which I think is kinda cool (click on image for larger view).
Notice that this looks pretty similar to what you get in the default Index.aspx view. One advantage of this approach is that you’re always using VB rather than switching over to writing markup. So if you forget to close a tag, for example, you get immediate compilation errors.
Another advantage is that your “view” is now compiled into the same assembly as the rest of your code. Of course, this could also be a disadvantage depending how you look at it.
I was reading Jeff Atwood’s latest post, Programming: Love it or Leave it when I came across this part, emphasis mine.
Joel implied that good programmers love programming so much they’d do it for no pay at all. I won’t go quite that far, but I will note that the best programmers I’ve known have all had a lifelong passion for what they do. There's no way a minor economic blip would ever convince them they should do anything else. No way. No how.
Unlike Jeff, I will go that far. I love to code, and I do it for free all the time.
I don’t think Joel meant to imply that programmers would continue to write code for their current employers for free in lieu of any pay. What I think he meant was that programmers who love to code will code for fun as well as profit. They’ll write code outside of their paying jobs.
For example, I took the entire week off last week and spent lots of time with my family, which was wonderful (cue gratuitous picture of kid)! I trained my son in Ninja acrobatics.
I got my brother completely hooked on Desktop Tower Defense.

And tried to figure out what sort of mischief my son was involved in, as that face is as guilty as sin.
However, along with all that family fun, I spent nearly every minute of downtime hacking on Subtext. I went on a huge refactoring binge cleaning up stale code, separating concerns left and right, and replacing the old method of matching requests with ASP.NET Routing.
And it was huge fun!
And I’m not alone. I noticed several streams on Twitter of folks having fun writing code, such as Glenn Block sharing his learning in the open experiences, among others.
Developers I’ve worked with who really love to code, tend to do it for fun, as well as for work. Personally, I don’t think it’s unhealthy as long as it’s not the only thing you do for fun. And I’m not suggesting that if you don’t do it for fun, you don’t love to code. Some people work so much, they don’t have time to do it for fun, but would code for fun if they had copious free time.
As for me, I’ll say it again, I <3 to code.
Technorati Tags:
coding,
programming
A while ago ScottGu mentioned in his blog that we would try and have an ASP.NET MVC Release Candidate by the end of this year. My team worked very hard at it, but due to various unforeseeable circumstances, I’m afraid that’s not gonna happen. Heck, I couldn’t even get into the office yesterday because the massive dumping of snow. I hope to get in today a little later since I’m taking next week off to be with my family coming in from Alaska.
But do not fret, we’ll have something early next year to release. In the meanwhile, we gave some rough bits to Scott Guthrie to play with and he did not disappoint yet again with a a great detailed post on some upcoming new features both in the runtime and in tooling.
Often, it’s the little touches that get me excited, and I want to call one of those out, Views without Code-Behind. This was always possible, of course, but due to some incredible hacking down in the plumbings of ASP.NET , David Ebbo with some assistance from Eilon Lipton, figured out how to get it to work with generic types using your language specific syntax for generic types. If you recall, previously it required using that complex CLR Syntax within the Inherits attribute.
Keep in mind that they had to do this without touching the core ASP.NET bits since ASP.NET MVC is a bin-deployable out-of-band release. David provided some hints on how they did this within his blog in these two posts: ProcessGeneratedCode: A hidden gem for Control Builder writers and Creating a ControlBuilder for the page itself.
ASP.NET MVC Design Gallery
In the meanwhile, Stephen Walther has been busy putting together a fun new section of the ASP.NET MVC website called the ASP.NET MVC Design Gallery.
In one of my talks about ASP.NET MVC, I mentioned a site that went live with our default drab blue project template (the site has since redesigned its look entirely). The Design Gallery provides a place for the community to upload alternative designs for our default template.
Happy Holidays
Again, I apologize that we don’t have updated bits for you to play with, but we’ll have something next year! In the meanwhile, as the end of this year winds down, I hope it was a good one for you. It certainly was a good one for me. Enjoy your holidays, have a Merry Christmas, Hannukah, Kwanza, Winter Solstice, Over Consumption Day, whatever it is you celebrate or don’t celebrate. ;)
ASP.NET Routing is useful in many situations beyond ASP.NET MVC. For example, I often need to run a tiny bit of custom code in response to a specific request URL. Let’s look at how routing can help.
First, let’s do a quick review. When you define a route, you specify an instance of IRouteHandler associated with the route which is given a chance to figure out what to do when that route matches the request. This step is typically hidden from most developers who use the various extension methods such as MapRoute.
Once the route handler makes that decision, it returns an instance of IHttpHandler which ultimately processes the request.
There are many situations in which I just have a tiny bit of code I want to run and I’d rather not have to create both a custom route handler and http handler class.
So I started experimenting with some base handlers that would allow me to pass around delegates.
Warning: the code you are about to see may cause permanent blindness. This was done for fun and I’m not advocating you use the code as-is.
It works, but the readability of all these lambda expressions may cause confusion and insanity.
One common case I need to handle is permanently redirecting a set of URLs to another set of URLs. I wrote a simple extension method of RouteCollection to do just that. In my Global.asax.cs file I can write this:
routes.RedirectPermanently("home/{foo}.aspx", "~/home/{foo}");
This will permanently redirect all requests within the home directory containing the .aspx extension to the same URL without the extension. That’ll come in pretty handy for my blog in the future.
When you define a route, you have to specify an instance of IRouteHandler which handles matching requests. That instance in turn returns an IHttpHandler which ultimately handles the request. Let’s look at the simple implementation of this RedirectPermanently method.
public static Route RedirectPermanently(this RouteCollection routes,
string url, string targetUrl) {
Route route = new Route(url, new RedirectRouteHandler(targetUrl, true));
routes.Add(route);
return route;
}
Notice that we simply create a route using the RedirectRouteHandler. As we’ll see, I didn’t even need to do this, but it helped make the code a bit more readable. To make heads or tails of this, we need to look at that handler. Warning: Some funky looking code ahead!
public class RedirectRouteHandler : DelegateRouteHandler {
public RedirectRouteHandler(string targetUrl) : this(targetUrl, false) {
}
public RedirectRouteHandler(string targetUrl, bool permanently)
: base(requestContext => {
if (targetUrl.StartsWith("~/")) {
string virtualPath = targetUrl.Substring(2);
Route route = new Route(virtualPath, null);
var vpd = route.GetVirtualPath(requestContext,
requestContext.RouteData.Values);
if (vpd != null) {
targetUrl = "~/" + vpd.VirtualPath;
}
}
return new DelegateHttpHandler(httpContext =>
Redirect(httpContext, targetUrl, permanently), false);
}) {
TargetUrl = targetUrl;
}
private void Redirect(HttpContext context, string url, bool permanent) {
if (permanent) {
context.Response.Status = "301 Moved Permanently";
context.Response.StatusCode = 301;
context.Response.AddHeader("Location", url);
}
else {
context.Response.Redirect(url, false);
}
}
public string TargetUrl { get; private set; }
}
I bolded a portion of the code within the constructor. The bolded portion is a delegate (via a lambda expression) being passed to the base constructor. Rather than creating a custom IHttpHandler class, I am telling the base class what code I would want that http handler (if I had written one) to execute in order to process the request. I pass that code as a lambda expression to the base class.
I think in a production system, I’d probably manually implement RedirectRouteHandler. But while I’m having fun, let’s take it further.
Let’s look at the DelegateRouteHandler to understand this better.
public class DelegateRouteHandler : IRouteHandler {
public DelegateRouteHandler(Func<RequestContext, IHttpHandler> action) {
HttpHandlerAction = action;
}
public Func<RequestContext, IHttpHandler> HttpHandlerAction {
get;
private set;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
var action = HttpHandlerAction;
if (action == null) {
throw new InvalidOperationException("No action specified");
}
return action(requestContext);
}
}
Notice that the first constructor argument is a Func<RequestContext, IHttpHandler>. This is effectively the contract for an IRouteHandler. This alleviates the need to write new IRouteHandler classes, because we can instead just create an instance of DelegateRouteHandler directly passing in the code we would have put in the custom IRouteHandler implementation. Again, in this implementation, to make things clearer, I inherited from DelegateRouteHandler rather than instantiating it directly. To do that would have sent me to the 7th level of Hades immediately. As it stands, I’m only on the 4th level for what I’ve shown here.
The last thing we need to look at is the DelegateHttpHandler.
public class DelegateHttpHandler : IHttpHandler {
public DelegateHttpHandler(Action<HttpContext> action, bool isReusable) {
IsReusable = isReusable;
HttpHandlerAction = action;
}
public bool IsReusable {
get;
private set;
}
public Action<HttpContext> HttpHandlerAction {
get;
private set;
}
public void ProcessRequest(HttpContext context) {
var action = HttpHandlerAction;
if (action != null) {
action(context);
}
}
}
Again, you simply pass this class an Action<HttpContext> within the constructor which fulfills the contract for IHttpHandler.
The point of all this is to show that when you have interfaces with a single methods, they can often be transformed into a delegate by writing a helper implementation of that interface which accepts delegates that fulfill the same contract, or at least are close enough.
This would allow me to quickly hack up a new route handler without adding two new classes to my project. Of course, the syntax to do so is prohibitively dense that for the sake of those who have to read the code, I’d probably recommend just writing the new classes.
In any case, however you implement it, the Redirect and RedirectPermanent extension methods for handling routes is still quite useful.
Technorati Tags:
aspnetmvc,
routing
UPDATE: There’s a workaround mentioned in the Google Groups. It’s finally resolved.
Ever since I first started using FeedBurner, I was very happy with the service. It was exactly the type of service I like, fire and forget and it just worked. My bandwidth usage went down and I gained access to a lot of interesting stats about my feed.
When I was first considering it, others warned me about losing control over my RSS feed. That led me to pay for the MyBrand PRO feature which enabled me to burn my feed using my own domain name at http://feeds.haacked.com/haacked by simply creating a CNAME from feeds.haacked.com to feeds.feedburner.com.
The idea was that if I ever wanted to reclaim my feed because something happened to FeedBurner or because I simply wanted to change, I could simply remove the CNAME and serve up my feed itself.
That was the idea at least.
This week, I learned the fatal flaw in that plan. When Google bought FeedBurner, nothing really changed immediately, so I was completely fine with it. But recently, they decided to change the domain over to a google domain. I had assumed they would do a CNAME to their own domain for MyBrand users. Instead, I saw that they were redirecting users to their own domain, thus taking control away from me over my own feed and completely nullifying the whole point of the MyBrand service.
That’s right. People who were subscribed via my feeds.haacked.com domain were being redirected to a google domain.
Ok, perhaps I’m somewhat at fault for ignoring the email on November 25 announcing the transition, but I’m a busy guy and that didn’t leave me much time to plan the transition.
And even if I had, I would have still been screwed. I followed the instructions provided and set up a CNAME from feeds.haacked.com to haackedgmail.feedproxy.ghs.google.com and watched the next day as my subscriber count dropped from 11,000 to 827. I’ve since changed the CNAME back to the feedburner.com domain (I tried several variations of the CNAME beforehand) and am resigned to let the redirect happen for now.
In the meanwhile, I’ve set up a CNAME from feeds3.haacked.com to the one they gave me and it still doesn’t work. At the time I write this, http://feeds3.haacked.com/haacked gives a 404 error.
I’m very disappointed in the haphazard manner they’ve made this transition, but I’m willing to give a second chance if they’d only fix the damn MyBrand service.
Technorati Tags:
feedburner,
google
While at PDC, I met Louis DeJardin and we had some lively discussions on various topics around ASP.NET MVC. He kept bugging me about some view engine called Flint? No… Electricity? No… Spark!
I had heard of it, but never got around to actually playing with it until after the conference. And the verdict is, I really like it.
Spark is a view engine for both Monorail and ASP.NET MVC. It supports multiple content area layouts much like master pages, which is one thing that seems to be lacking in many other view engines I’ve seen, which only support a single content area, correct me if I’m wrong. Not only that, but he’s already included IronPython and IronRuby support.
But what I really like about it is the simple way you effectively data bind HTML elements to code. Let’s start with a simple example. Suppose you have an enumeration of products you’re passing to the view from your controller action. Here’s how you might render it in Spark.
<viewdata model="IEnumerable[[Product]]"/>
<ul class="products">
<li each="var product in ViewData.Model">${product.ProductName}</li>
</ul>
Note the each attribute of the <li> tag contains a code expression. This will repeat the <li> tag once per product. The <viewdata> element there declares the type of the ViewData.Model property.
Spark still supports using code nuggets <% %> when you absolutely need them. For example, when using the BeginForm method, I needed a using block, so I used the code nuggets.
Just for fun, I redid the views of my Northwind sample to replace all the ASPX views with Spark as a demonstartion of using an alternative view engine. Try it out.
UPDATE: Updated to the latest version of ASP.NET MVC and Spark as of ASP.NET MVC 1.0 RC 2.
I’m working to try and keep internal release notes up to date so that I don’t have this huge amount of work when we’re finally ready to release. Yeah, I’m always trying something new by giving procrastination a boot today.
These notes were sent to me by Jacques, a developer on the ASP.NET MVC feature team. I only cleaned them up slightly.
The sections below contain descriptions and possible solutions for known issues that may cause the installer to fail. The solutions have proven successful in most cases.
Visual Studio Add-ins
The ASP.NET MVC installer may fail when certain Visual Studio add-ins are already installed. The final steps of the installation installs and configures the MVC templates in Visual Studio. When the installer encounters a problem during these steps, the installation will be aborted and rolled back. MVC can be installed from a command prompt using msiexec to produce a log file as follows:
msiexec /i AspNetMVCBeta-setup.msi /q /l*v mvc.log
If an error occurred the log file will contain an error message similar to the example below.
MSI (s) (C4:40) [20:45:32:977]: Note: 1: 1722 2: VisualStudio_VSSetup_Command 3: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe 4: /setup
MSI (s) (C4:40) [20:45:32:979]: Product: Microsoft ASP.NET MVC Beta -- Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action VisualStudio_VSSetup_Command, location: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe, command: /setup
Error 1722. There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. Action VisualStudio_VSSetup_Command, location: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe, command: /setup
This error is usually accompanied by a corresponding event that will be logged in the Windows Event Viewer:
Faulting application devenv.exe, version 9.0.30729.1, time stamp 0x488f2b50, faulting module unknown, version 0.0.0.0, time stamp 0x00000000, exception code 0xc0000005, fault offset 0x006c0061, process id 0x10e0, application start time 0x01c9355ee383bf70
In most cases, removing the add-ins before installing MVC, and then reinstalling the add-ins, will resolve the problem. ASP.NET MVC installations have been known to run into problems when the following add-ins were already installed.:
- PowerCommands
- Clone Detective
Cryptographic Services
In a few isolated cases, the Windows Event Viewer may contain an Error event with event source CAPI2 and event ID 513. The event message will contain the following: Cryptograhpic Services failed while processing the OnIdentity() call in the System Writer Object.
The article at http://technet.microsoft.com/en-us/library/cc734021.aspx describes various steps a user can take to correct the problem, but in some cases simply stopping and restarting the Cryptographic services should allow the installation to proceed.