May 2011 Blog Posts

Random Thought Friday

I’m reading through the archives of a blog where the author posts something random every Friday (yesterday was Thursday, and tomorrow is Saturday). His Friday posts are completely unrelated to the main theme and content of his blog.

I like that idea a lot. I don’t blog as much as I used to mostly because I feel the need to spend so much time on each blog post. A lot of the posts I write take a bit of research and experimentation before I’m ready to post them.

But a random thought? I can pull one of those out of my ascot any day of the week, and twice on Friday. But I’ll only do it once.

And yes, thanks for asking, but the thought has occurred to me that I already have another medium where I post random thoughts 7 days a week, Twitter (I’m @haacked on Twitter).

But my twist on this is that every Friday, I’ll post something random, funny, amusing, or whatever in this blog post, and I’ll use more than 140 characters but I’ll always end the post with something I appreciated either during the week, or in general.

This Friday’s random thought is about starting a random thought Friday blog series and whether this will end up being a one post series like the rest. So there, I’ve done that part.

And the thing I appreciate this past week is how nice it was to take a day off and spend it with my wife. Oh, and Instagram. I appreciate Instagram a lot. Perhaps too much. I’ll try easing off the Tilt-Shift from now on.

my-lovely-wife

Here’s where I violate my wife’s privacy and post a picture of her on a ferry to Bainbridge Island on my blog. We had a really nice outing on Tuesday.

Bin Deploying ASP.NET MVC 3

When you build an ASP.NET MVC 3 application and are ready to deploy it to your hosting provider, there are a set of assemblies you’ll need to include with your application for it to run properly, unless they are already installed in the Global Assembly Cache (GAC) on the server.

In previous versions of ASP.NET MVC, this set of assemblies was rather small. In fact, it was only one assembly, System.Web.Mvc.dll, though in the case of ASP.NET MVC 1.0, if you didn’t have SP1 of .NET 3.5 installed, you would have also needed to deploy System.Web.Abstractions.dll and System.Web.Routing.dll.

But ASP.NET MVC 3 makes use of technology shared with the new ASP.NET Web Pages product such as Razor. If you’re not familiar with ASP.NET Web Pages and how it fits in with Web Matrix and ASP.NET MVC, read David Ebbo’s blog post, How WebMatrix, Razor, ASP.NET Web Pages, and MVC fit together.

If your server doesn’t have ASP.NET MVC 3 installed, you’ll need to make sure the following set of assemblies are deployed in the bin folder of your web application:

  • Microsoft.Web.Infrastructure.dll
  • System.Web.Helpers.dll
  • System.Web.Mvc.dll
  • System.Web.Razor.dll
  • System.Web.WebPages.Deployment.dll
  • System.Web.WebPages.dll
  • System.Web.WebPages.Razor.dll

In this case, it’s not as simple as looking at your list of assembly references and setting Copy Local to True as I’ve instructed in the past.

As you can see in the following screenshot, not every assembly is referenced. Not all of these assemblies are meant to be programmed against so it’s not necessary to actually reference each of these assemblies. They just need to be available on the machine either from the GAC or in the bin folder.

referenced-assemblies

But the Visual Web Developer team has you covered. They added a feature specifically for adding these deployable assemblies. Right click on the project and select Add Deployable Assemblies and you’ll see the following dialog.

add-deployable-assemblies

When building an ASP.NET MVC application, you only need to check the first option. Ignore the fact that the second one says “Razor”. “ASP.NET Web Pages with Razor syntax”was the official full name of the product we simply call ASP.NET Web Pages now. Yeah, it’s confusing.

Note that there’s also an option for SQL Server Compact, but that’s not strictly necessary if you’ve installed SQL Server Compact via NuGet.

So what happens when you click “OK”?

bin-deployable-assemlies

A special folder named _bin_deployableAssemblies is created and the necessary assemblies are copied into this folder. Web projects have a built in build task that copies any assemblies in this folder into the bin folder when the project is compiled.

Note that this dialog did not add any assembly references to these assemblies. That ensures that the types in these assemblies don’t pollute Intellisense, while still being available to your deployed application. If you actually need to use a type in one of these assemblies, you’re free to reference them.

So here’s the kicker. If you’re building a web application, and you need an assembly deployed but don’t want it referenced and don’t want it checked into the bin directory, you can simply add this folder yourself and put your own assemblies in here.

If you’ve ever run into a problem where an ASP.NET MVC site you developed locally doesn’t work when you deploy it, this dialog may be just the ticket to fix it.

An Obsessive Compulsive Guide To Source Code Formatting

Most developers I know are pretty anal about the formatting of their source code. I used to think I was pretty obsessive compulsive about it, but then I joined Microsoft and faced a whole new level of OCD (Obsessive Compulsive Disorder). For example, many require all using statements to be sorted and unused statements to be removed, which was something I never cared much about in the past.

There’s no shortcut that I know of for removing unused using statements. Simply right click in the editor and select Organize Usings > Remove and Sort in the context menu.

SubtextSolution - Microsoft Visual Studio (Administrator) (2)

In Visual Studio, you can specify how you want code formatted by launching the Options dialog via Tools > Options and then select the Text Editor node. Look under the language you care about and there are multiple formatting options providing hours of fun fodder for religious debates.

Options

Once you have the settings just the way you want them, you can select the Edit > Advanced > Format Document (or simply use the shortcut CTRL + K, CTRL + D ) to format the document according to your conventions.

The problem with this approach is it’s pretty darn manual. You’ll have to remember to do it all the time, which if you really have OCD, is probably not much of a problem.

However, for those that keep forgetting these two steps and would like to avoid facing the wrath of nitpicky code reviewers (try submitting a patch to NuGet to experience the fun), you can install the Power Commands for Visual Studio via the Visual Studio Extension manager which provides an option to both format the document and sort and remove using statements every time you save the document.

I’m actually not a fan of having using statements removed on every save because I save often and it tends to remove namespaces containing extension methods that I will need, but haven’t yet used, such as System.Linq.

Formatting Every Document

Also, if you have a large solution with many collaborators, the source code can start to drift away from your OCD ideals over time. That’s why it would be nice to have a way of applying formatting to every document in your solution.

One approach is to purchase ReSharper, which I’m pretty sure can reformat an entire solution and adds a lot more knobs you can tweak for the formatting.

But for you cheap bastards, there are a couple of free approaches you can make. One approach is to write a Macro, like Brian Schmitt did. His doesn’t sort and remove using statements, but it’s a one line addition to add that.

Of course, the approach I was interested in trying was to use Powershell to do it within the NuGet Package Manager Console. A couple nights ago I was chatting with my co-worker and hacker extraordinaire, David Fowler, way too late at night about doing this and we decided to have a race to see who could implement it first.

I knew I had no chance unless I cheated so I wrote this monstrosity (I won’t even post it here I’m so ashamed). David calls it “PM code”, which in this case was well deserved as it was simply a proof of concept, but also because it’s wrong. It doesn’t traverse the files recursively. But hey, I was first! But I at least gave him the code needed to actually format the document.

It was very late and I went to sleep knowing in the morning, I’d see something elegant from David. I was not disappointed as he posted this gist.

He wrote a generic command named Recurse-Project that recursively traverses every item in every project within a solution and calls an action against each item.

That allowed him to easily write Format-Document which leverages Recurse-Project and automates calling into Visual Studio’s Format Document command.

function Format-Document {
  param(
    [parameter(ValueFromPipelineByPropertyName = $true)]
    [string[]]$ProjectName
  )
  Process {
    $ProjectName | %{ 
      Recurse-Project -ProjectName $_ -Action {
        param($item)
        if($item.Type -eq 'Folder' -or !$item.Language) {
          return
        }
    
        $win = $item.ProjectItem.Open('{7651A701-06E5-11D1-8EBD-00A0C90F26EA}')
        if ($win) {
          Write-Host "Processing `"$($item.ProjectItem.Name)`""
          [System.Threading.Thread]::Sleep(100)
          $win.Activate()
          $item.ProjectItem.Document.DTE.ExecuteCommand('Edit.FormatDocument')
          $item.ProjectItem.Document.DTE.ExecuteCommand('Edit.RemoveAndSort')
          $win.Close(1)
        }
      }
    }
  }
}

Adding Commands to NuGet Powershell Profile

Great! He did the work for me. So what’s the best way to make use of his command? I could add it to a NuGet package, but that would then require that I install the package first any time I wanted to use the package. That’s not very usable. NuGet doesn’t yet support installing PS scripts at the machine level, though it’s something we’re considering.

To get this command available on my machine so I can run it no matter which solution is open, I need to set up my NuGet-specific Powershell profile as documented here.

The NuGet Powershell profile script is located at:

%UserProfile%\Documents\WindowsPowerShell\NuPack_profile.ps1

The easiest way to find the profile file is to type $profile within the NuGet Package Manager Console. The profile file doesn't necessarily exist by default, but it’s easy enough to create it. The following screenshot shows a session where I did just that.

nuget-ps-profile

The mkdir –force (split-path $profile) command creates the WindowsPowershell directory if it doesn’t already exist.

Then simply attempting to open the script in Notepad prompts you to create the file if it doesn’t already exist. Within the profile file, you can change PowerShell settings or add new commands you might find useful.

For example, you can cut and paste the code in David’s gist and put it in here. Just make sure to omit the first example line in the gist which simply prints all project items to the console.

When you close and re-open Visual Studio, the Format-Document command will be available in the NuGet Package Manager Console. When you run the command, it will open each file and run the format command on it. It’s rather fun to watch as it feels like a ghost has taken over Visual Studio.

The script has a Thread.Sleep call for 100ms to work around a timing issue when automating Visual Studio. It can take a brief moment after you open the document before you can activate it. It doesn’t hurt anything to choose a lower number. It only means you may get the occasional error when formatting a document, but the script will simply move to the next document.

The following screenshot shows the script in action.

formatting-documents

With this in place, you can now indulge your OCD and run the Format-Document command to clean up your entire solution. I just ran it against Subtext and now can become the whitespace Nazi I’ve always wanted to be.

Making Let Me Bing That For You Open Source

Almost two years ago, I announced the launch of http://letmebingthatforyou.com/, a blatant and obvious rip-off of the Let me Google that for you website.

The initial site was created by Maarten Balliauw and Juliën Hanssens in response to a call for help I made. It was just something we did for fun. I’ve been maintaining the site privately always intending to spend some time to refresh the code and open source it.

Just recently, I upgraded the site to ASP.NET MVC 3, refactored a bunch of code, and moved the site to AppHarbor.

Why AppHarbor?

I’ve heard such good things about how easy it is to deploy to AppHarbor so I wanted to try it out firsthand myself, and this small little project seemed like a perfect fit.

I had been working on the code in a private Mercurial repository so it was trivially easy for me to push it to a BitBucket repository. From there it’s really easy to integrate the BitBucket account with AppHarbor.

So now, my deployment workflow is really easy when working on this simple project:

  1. Make some changes and commit them into my local HG (Mercurial) repository. I have my local repository syncing to all my machines using Live Mesh.
  2. At some point, when I’m ready to publish the changes, I run the hg push command on my repository.
  3. That’s it! AppHarbor builds my project and if all the unit tests pass, it deploys it live.

I’m not planning to spend a lot of time on Let Me Bing That For You. It’s just a fun little side project that allows me to play around with ASP.NET MVC 3, jQuery, etc. If you want to look at the source, or contribute a patch, check it out on BitBucket.

New NuGet Documentation Site

It’s a common refrain you hear when it comes to documentation for open source projects. It typically sucks! In part, because nobody wants to work on docs. But also in part because good documentation is challenging to write.

What is good documentation in the first place? The following is a list of some qualities that make for great documentation. This list is by no means complete. Good docs are…

  • Written for the right audience
  • Comprehensive and accurate
  • Easily browsable and searchable
  • Written in a clear and concise language
  • Laid out in a readable format
  • Versioned with the source code

While it’s challenging to write and maintain great documentation, my co-worker Matthew was up to the challenge of building a simple Markdown based system to help us manage our documentation. Read about our new docs site in his blog post, Introducing NuGet Docs: Community Driven Documentation.

Our goal in the long run is to have a great set of docs for NuGet with help from the community. So if you’re interested in helping out, please visit our NuGet Docs project page and let us know. It’s a separate repository with its own Mercurial repository so we can give a lot more people write access directly to the repository.

So please, if you’re looking for a low commitment easy way to get a toe in the waters with open source in general or with NuGet, consider helping us with our docs. It’s a great way to get started with OSS. It’s how I got my start a long time ago by contributing docs to RSS Bandit.

Localized Releases of ASP.NET MVC 3 Tools Update

In April we announced the release of ASP.NET MVC 3 Tools Update which added Scaffolding, HTML 5 project templates, Modernizr, and EF Code First Magic Unicorn Edition.

Today, just shy of one month later I’m happy to announce that this release is now available in nine other languages via the Web Platform Installer (Web PI).

We’ve also included release notes translated into the nine languages as well.

The best way to install the language specific version of ASP.NET MVC 3 is via the Web Platform installer because it will chain in the full installer. If you install the language specific version directly from the Download Details page, you’ll need to run two installers, the full installer and then the language pack installer.

Compiling MVC Views In A Build Environment

ASP.NET MVC project templates include support for precompiling views, which is useful for finding syntax errors within your views at build time rather than at runtime.

In case you missed the memo, the following outline how to enable this feature.

  • Right click on your ASP.NET MVC project in the Solution Explorer
  • Select Unload Project in the context menu. Your project will show up as unavailableunavailable-project
  • Right click on the project again and select Edit ProjectName.csproj.

This will bring up the project file within Visual Studio. Search for the entry <MvcBuildViews> and set the value to true. Then right click on the project again and select Reload Project.

Compiling in a build environment

If you search for MvcBuildViews on the web, you’ll notice a lot of people having problems when attempting to build their projects in a build environment. For example, this StackOverflow question describes an issue when compiling MVC on a TFS Build. I had an issue when trying to deploy an ASP.NET MVC 3 application to AppHarbor.

It turns out we had a bug in our project templates in earlier versions of ASP.NET MVC that we fixed in ASP.NET MVC 3 Tools Update.

But if you created your project using an older version of ASP.NET MVC including ASP.NET MVC 3 RTM (the one before the Tools Update), your csproj/vbproj file will still have this bug.

To fix this, look for the following element within your project file:

<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)\..\$(ProjectName)" />
</Target>

And replace it with the following.

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

 

 

After I did that, I was able to deploy my application to AppHarbor without any problems.

Going back to the StackOverflow question I mentioned earlier, notice that the accepted answer is not the best answer. Jim Lamb provided a better answer and is the one who provided the solution that we use in ASP.NET MVC 3 Tools Update. Thanks Jim!

Single Package Version per Solution

Not too long ago, I posted a survey on my blog asking a set of questions meant to gather information that would help the NuGet team make a decision about a rather deep change.

You can see the results of the survey here.

If there’s one question that got to the heart of the matter, it’s this one.

survey-question-result

We’re considering a feature that would only allow a single package version per solution. As you can see by the response to the question, that would fit what most people need just fine, though there are a small number of folks that might run into problems with this behavior.

One variant of this idea would allow multiple package versions if the package doesn’t contain any assemblies (for example, a JavaScript package like jQuery).

Thanks again for filling out the survey. We think we have a pretty good idea of how to proceed at this point, but there’s always room for more feedback. If you want to provide more feedback on this proposed change, please review the spec here and post your thoughts in our discussion forum in the thread dedicated to this change.

The spec describes what pain point we’re trying to solve and shows a few examples of how the behavior change would affect common scenarios, so it’s worth taking a look at.