.NET Developers Search

The latest podcast of Hanselminutes mentioned a custom search engine focused on .NET topics. It’s using Google Custom Search, and at least for a search term like MSMQ, the searchdotnet.com results look a bit different than regular Google results. The creator of the site, Dan Appleman, has authored a number of books on Microsoft technologies (primarily .NET and VB). He seems to be going for a “quality vs. quantity” approach with the sites he includes as sources (which makes sense for this sort of niche search engine).

Lightroom: Day 1

If you love iPhoto, I warn you–stop reading now. Once you read even a little about what Adobe Lightroom can do, you’ll want to try it. Once you’ve tried Lightroom, you simply won’t be content with going back to iPhoto. I’m only 1 day into the 30-day trial of Lightroom, and I’m done with iPhoto. I haven’t even tried Apple’s Aperture yet. If you’re still reading, it’s already too late. I can’t be held responsible for the money you will almost certainly spend.

Metadata Browser

After importing around 200 photos into Lightroom, this was the first feature I played with. It lets you filter which pictures you see by any one of a number of variables, including lens (if you use more than one), aperture, shutter speed, and ISO speed rating. So two clicks let me see how all the photos I shot at a shutter speed of 1/500th second looked. Two more clicks, and I could see how everything I shot with my 50 f/1.4 looked, or how what I took with my zoom lens looked.

Quick Develop

This feature enables you to apply changes to crop ratio, white balance, and tone (including exposure) across multiple photos. So when I needed to change the white balance in a group of my shots, it was as simple as selecting the group, changing white balance to “Flash” from “As Shot”. The same is true of underexposed shots. My friend Sandro pointed out four photos that were underexposed. I simply selected the four he pointed out, and pressed the button for +1/3 of a stop until they were bright enough for my taste. In retrospect, a single click of the +1 stop button would have been even faster.


This is the step in Lightroom’s workflow where you make more detailed changes to individual photos. Each change you make to a photo shows up in a “History” widget to the left, so you can rollback individual changes with ease. I only cropped photos here, but I could have changed any number of things about them.


While this feature isn’t so much about the photos themselves as it is about how you can share them, this part of the workflow is where Lightroom really shines. Generating this page took a few clicks, and a couple of slider moves.  On top of that, I didn’t even have to use another application to upload it to the web–I did it directly from Lightroom.  There are quite a few different page templates to choose from.

The features I’ve described so far barely scratch the surface of what Lightroom can do.  One of the things that impresses me about Lightroom is not just the amount of things it does that iPhoto can’t (or does badly, *cough* iWeb *cough*) but how much less time it takes to handle hundreds of photos by comparison.

Outlook Lookout

While I wait for Google to fix their desktop search bug, I’m using Lookout (version to search Outlook.  I was under the distinct impression that Lookout got killed after Microsoft bought the vendor (Lookout Software),  especially when I read this post on Channel 9.

It looks like the helpdesk people at work squirreled away an old installation of it, because Googling for it brought back nothing but Windows Desktop Search links.

A brief note on version control, labeling, and deployments

One thing I didn’t realize about CruiseControl.NET until recently was that it automatically labels your builds.  It uses a ... naming scheme.  The way this helps with deployments is that you can always look figure out what you’ve deployed to production in the past–as long as you only deploy labeled builds.

We still need to get our continuous integration setup working again, but in the interim, manual labeling of releases is still helpful.

Exposing InnerException

This week, an application I work on started logging an exception that provided no help at all in debugging the problem. My usual practice of running the app in debug mode with production values in the config file failed to reproduce the error too. After a couple of days of checking a bunch of different areas of code (and still not solving the problem), Bob (a consultant from Intervention Technologies) gave me some code to get at all the InnerException values for a given Exception. Download the function from here.

StackTrace can be pretty large. Since we log to a database, I was worried about overrunning the column width. I also wasn’t keen on the idea of looking at so large a text block if an Exception was nesting four or five additional ones. So instead of implementing the code above, I changed the code to log at each level. Doing it this way adds a log entry for each InnerException. Because the log viewer I implemented displays the entries in reverse-chronological order, the root cause of a really gnarly exception displays at the top. The changes I made to global.asax looked like this.

The result of this work revealed that the app had been complaining about not being able to reach the SMTP server to send e-mail (which it needs to send users their passwords when they register or recover lost passwords).

Once we’d established that the change was working properly, it was time to refactor the code to make the functionality more broadly available. To accomplish this, I updated our Log4Net wrapper like this.

App_Code: Best In (Very) Small Doses

When I first started developing solutions on version 2.0 of the .NET Framework, I saw examples that had some logic in the App_Code folder. For things like base pages, I thought App_Code was perfect–and that’s how I use it today. When I started to see applications put their entire middle tiers in App_Code however, I thought that was a bad idea. Beyond not being able to unit test your components (and the consequences associated with a lack of unit testing, coverage, etc), it just seemed … wrong.

Fortunately, there are additional reasons to minimize the use of App_Code: