Tuesday, January 18, 2011

How to Deploy an ASP.NET MVC 3 App to Web Hosting with "\bin Deployment"

Already know what "/bin deployment" means, and just looking for the list of assemblies you need to include for MVC 3? Skip to the end.

Since ASP.NET MVC 3 was released last week, I've had several folks ask me how they can deploy their MVC 3 apps to a web hosting service. They asked because when they attempted to upload their app's files, they saw this error (or one similar to it):


What's the Problem?

When you install MVC 3 on your local machine, a number of assemblies are registered in the GAC. MVC 3 needs these assemblies. Unless your web hosting service has installed MVC 3 on their servers (and many haven't, yet), those assemblies won't be there, and you'll see an error similar to the one above.

What's the Solution?

As with previous versions of MVC, we suggest you solve this with what we call "\bin deployment." Bin Deployment is just a fancy term that means "include the MVC assembly (and its dependencies) in your web application's /bin folder." It's not hard to prepare your project for Bin Deployment, but there are a few more assemblies involved compared to MVC 2. I'll show you what you need to do, step by step.

Step 1: Add Explicit References for MVC and Its Dependencies

Your MVC app's project probably won't have references to all of the assemblies it needs, because they're in the GAC. So you need to add them. Here is the list (they'll all be available in the .NET tab of the Add Reference dialog):
  • Microsoft.Web.Infrastructure
  • System.Web.Helpers
  • System.Web.Mvc
  • System.Web.Razor
  • System.Web.WebPages
  • System.Web.WebPages.Deployment
  • System.Web.WebPages.Razor


Step 2: Change Each Reference's Copy Local Property to True

After adding the references, you need to set the Copy Local property for each of the references you just added to True, as pictured below.


Step 3: Re-Build and Deploy as You Normally Would

Now, when you build your app, the MVC assembly and its dependencies will be copied to the /bin directory, allowing you to deploy as you normally would.

I hope this helps.

If you have any questions or concerns about this 'blog post, or in general, please send an email to drewmi at microsoft dot com. I'm also on Twitter at http://twitter.com/anglicangeek.

Friday, January 14, 2011

How To Publish an ASP.NET MVC 3 App to Windows Azure

With the final, "RTM" version of ASP.NET MVC 3 shipping today, I've had a number of people ask me how to publish an MVC 3 app to Windows Azure. It's a bit more complicated than publishing an MVC 2 app, at least at this time of writing. I'll walk you through the process.

Note: You need to have installed ASP.NET MVC 3 and Windows Azure Tools 1.3 to follow this process.

0. Upgrade Your MVC 2 App
If you're starting with an MVC 2 app, you'll need to upgrade it first. I won't describe the upgrade process here, because we've already documented it in the release notes. Also, a couple of the MVC team's developers built an upgrade tool to make the process easier, so you might try that instead of manually upgrading your app's project.

If you aren't starting from an existing MVC 2 app, just create a new MVC 3 app before moving to the first step.

1. Create the Windows Azure Project
Add a new Windows Azure Project in the same solution as your MVC 3 app. When you see the New Windows Azure Project dialog (pictured below), just click OK without adding any roles.




Why didn't I have you add any roles? Because the 1.3 version of the Azure tools doesn't have support for MVC 3, and therefore it isn't in the list of available web role types. You'll need to add your MVC 3 app after-the-fact, which you'll do in the next step.

2. Add the MVC 3 App as a Web Role
To add your MVC app as an Azure web role, right-click the Roles folder in the Azure project, select Add, then select Web Role Project in solution (as pictured below).


Your MVC 3 app will be in the list of projects on the next dialog. Select it and click OK. Verify that your MVC 3 app now is listed in the Roles folder.



You might think you could publish now, but the role would fail to start because MVC 3 has dependencies that don't exist in the Azure hosted service environment. We'll work around that in the next step.

3. Prepare Assemblies for "Bin Deployment"
The Azure hosted service environment doesn't have MVC 3 installed, so you effectively need to prepare what we call a "bin deployment" for your MVC 3 app, which simply means that MVC and all of the assemblies (DLLs) upon which it depends are bundled (included) with your app, locally in the ~\bin folder.

First, make sure all of the following assemblies are added as references to your MVC 3 app (some may already be added as references to your app, but not all of them will):

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



Next, for each of those assemblies, open the Properties pane (right-click the reference, then click Properties) and change the Copy Local setting to True.



Build your solution to check for errors before moving to the next step, which is actually publishing to Azure.

4. Publish as Normal
You should now be able to publish your Windows Azure project, which includes your MVC 3 app, as you would normally with any other type of web role.



Note: I've seen an odd problem, albeit not consistently, when deploying an MVC 3 app to Azure where the role takes a very long time to reach the ready state, after cycling from starting, to stopping, to recycling, and back again several times. If you encounter this problem, you might try stopping the deployment and re-deploying; that seemed to help me.

I hope this helps.

If you have any questions or concerns about this 'blog post, or in general, please send an email to me at drewmi <at> microsoft <dot> com. I'm also on Twitter at http://twitter.com/anglicangeek.

Friday, November 12, 2010

How to Uninstall Microsoft ASP.NET MVC 3 RC

Scott Guthrie 'blogged about some install problems some folks are having with our RC release of Microsoft ASP.NET MVC 3. One problem is that MVC 3 and the Async CTP do not work side-by-side. If you've installed both, you now need to uninstall both to get back into a state where you can install one or the other.


But uninstalling MVC 3 RC isn't as simple as uninstalling everything labeled 'ASP.NET MVC 3' in Programs and Features. MVC 3 RC also installs ASP.NET Web Pages (upon which it depends), NuGet, and a Visual Studio update that adds tools support for the Razor view engine. So, to completely uninstall MVC 3 RC, you actually need to uninstall all of the following:

  • Microsoft ASP.NET MVC 3
  • Microsoft ASP.NET MVC 3 - Visual Studio 2010 Tools (only installed when you have Visual Studio 2010)
  • Microsoft ASP.NET MVC 3 - VWD Express 2010 Tools (only installed if you have Visual Web Developer 2010 Express)
  • Microsoft ASP.NET Web Pages
  • Microsoft ASP.NET Web Pages - Visual Studio 2010 Tools (only installed when you have Visual Studio 2010)
  • Microsoft ASP.NET Web Pages - VWD Express 2010 Tools (only installed if you have Visual Web Developer 2010 Express)
  • NuGet
  • Update for Microsoft Visual Studio 2010 -  (KB2385361) (only installed when you have Visual Studio 2010)
  • Update for Microsoft Visual Web Developer 2010 Express -  (KB2385361) (only installed if you have Visual Web Developer 2010 Express)
N.B., the last two are installed as updates, not products; you'll need to switch to the 'View installed updates' section to uninstall them.

Windows 7 Walk-through

Here is a step-by-step walk-through of how to completely uninstall ASP.NET MVC 3 RC on Windows 7 (the steps and screens will differ on other versions of Windows, but the the idea, and actions you must take, are essentially the same):
  1. Open the Control Panel (Click Start, then click Control Panel)
  2. If you're in Category view, click 'Uninstall a program'; otherwise, click 'Program and Features'
  3. Uninstall everything that includes the phrase 'ASP.NET MVC 3'
  4. Uninstall everything that includes the phrase 'ASP.NET Web Pages'
  5. Uninstall 'NuGet'
  6. Switch to the 'View installed updates' section
  7. Uninstall everything that includes the phrase 'KB2385361'
ASP.NET MVC 3 RC should now be completely uninstalled.

Automating the Uninstallation

If you don't want to take all those manual steps, open a Visual Studio command prompt* with Administrator privilege and run all of the following commands (I suggest you copy and paste them):

  • wmic product where name="Microsoft ASP.NET MVC 3" call uninstall
  • wmic product where name="Microsoft ASP.NET MVC 3 - Visual Studio 2010 Tools" call uninstall
  • wmic product where name="Microsoft ASP.NET MVC 3 - VWD Express 2010 Tools" call uninstall
  • wmic product where name="Microsoft ASP.NET Web Pages" call uninstall
  • wmic product where name="Microsoft ASP.NET Web Pages - Visual Studio 2010 Tools" call uninstall
  • wmic product where name="Microsoft ASP.NET Web Pages - VWD Express 2010 Tools" call uninstall
  • wmic product where name="NuGet" call uninstall
  • msiexec /package {BC0464FA-A0BA-3E38-85BF-DC5B3A401F48} /uninstall {3069D446-63C5-38F4-9D28-41858024419C}
  • msiexec /package {85076DFF-7A17-3566-9CC0-488E6E6D4494} /uninstall {3069D446-63C5-38F4-9D28-41858024419C}
* if you don't know what a Visual Studio command prompt is, or how to open it, I suggest you use the manual steps.

I hope this helps.

Cheers,

Friday, July 2, 2010

Assign Multiple Class Names to an HAML Element

Let's say you want to convert the following HTML to HAML:

This is an out-of-character message.

In HAML, instead of joining the class names with spaces, you chain them with dots:

%div.message.ooc This is an out-of-character message.

If you've used HAML for a significant amount of time, you likely already know this. Sadly, as many times as I've used class name chains in HAML, it seems enough time has lapsed that I've forgotten the syntax, and I have to look it up again.

Friday, May 21, 2010

Kata Two: The Pair Combinator

This is the second in a series of code katas prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let Dave Thomas, who coined the term, explain its meaning.

Per request, I will target client-side JavaScript for our first few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is somewhat limiting, you can easily adapt this kata to other languages, frameworks, or environments.

I consider pair programming a fundamental part of the practice of crafting software. It's not as critical to me as, for instance, test-driven development, but I will always pair when possible. While I might not force pairing on an engineering team, I think it's quite reasonable to require some pair programming in the dojo. So I've decided that the dojo's middle hour (of three) will be paired repetitions (and pairing is certainly permissible in the first and last hour as well).

I also encourage the so-called practice of promiscuous pairing, which is changing your pairing partner frequently, after short periods of time.This works very well in a code dojo, thanks to the repetitive nature of code katas. But my experience is that, if you leave pair rotation and combinations up to folks, they tend to stay with their current partner too long. I decided to assign pairs during the middle hour, and that gave me the idea for the second kata: The Pair Combinator.

The Form

Write a web page, using only HTML and client-side JavaScript, that takes as input any number of programmer's names and the number of pairings, and produces as output pair combinations, duplicating combinations only when needed..

The manner by which input is captured, and output is displayed, is left to your creativity, provided it can be accomplished in HTML and client-side JavaScript alone.

You may use a JavaScript library, such as jQuery. You must practice TDD. You may ask anyone in the dojo to pair with you; if they aren't already paired, they must agree.

The Focus

There are several facets of this kata on which you could focus:
  • TDD
  • The user interface
  • The combinatorial algorithm
  • Manipulating the page with JavaScript
Of course, you don't have to focus on just one facet, but I found it helpful to be very deliberate and explicit about what I was focusing on for each repetition. Even though this is a relatively small problem (and page), there are many different ways to craft it. I think it's important to focus on that freedom, and the room it affords for iterative improvement. For instance, I've written discussion forums ten or more times during my career, and each time what I produce is better in some way than the last. So focus keenly on how you can improve iteration-to-iteration, in one or more of the facets.

Repeating the Kata

As with all katas, I suggest you delete all the code, both unit tests and product, between repetitions.

I think this kata is a good candidate for a time limit. On the first practice, take as much time as you need to finish. On subsequent repetitions, give yourself less time, and then shave more and more time off the limit until you can't quite finish. (And, as with any timed kata, it's important not to rush, sacrificing the quality of the form and action.)

Other ideas:
  • Try a new JavaScript framework, or none at all, for a repetition.
  • Try different implementations; not only in code, but also in the user interface (for instance, displaying results in a table versus a list).
  • Think about missing features that still stay true to the page's purpose.
Cheers,
Drew (twitter.com/anglicangeek)

If you practice this kata, please share your experience in the comments.

Thursday, May 20, 2010

Kata One: Red, Green, Refactor (or Next Test) in JavaScript

This is the first in a series of code katas prepared for an internal code dojo I host for the ASP.NET QA team. I share it hoping that others will practice it, and then share their own experiences in the comments. What's a code kata? I'll let Dave Thomas, who coined the term, explain its meaning.

As requested, I will target client-side JavaScript for our first few code katas, so that jQuery (or another JavaScript framework) may be used. While such a target is somewhat limiting, you can easily adapt this kata to other languages, frameworks, or environments.

The Preparation

Choose a JavaScript unit testing framework to use for this kata, such as jQuery's QUnit. Have the editor and browser of your choice ready to program client-side (i.e., browser-based) JavaScript.

The Form

Implement a JavaScript function that ordinalizes a number using test-driven development (TDD). Ordinalizing a number means converting it to its ordinal equivalent; e.g., 1 to 1st, 11 to 11th, 42 to 42nd. The function's specification and algorithm is less important than strictly adhering to the red, green, refactor (or next test)  continuous cycle of TDD. That cycle is:
  1. Write a failing test that specifies a single behavior of the unit you are developing.
  2. Write only enough code in the unit your are developing to make the test pass. Then ensure that all other tests still pass, as well.
  3. Examine all of the unit's code thus far written. Can it be improved? If so, make a single improvement and then run all of your tests again. Continue making improvements, one at a time, until you see no more need for improvement.
  4. Repeat the above steps for the unit's next behavior, starting with a new, failing test.
When I first started practicing TDD, I struggled to determine what tests to write first, or even at all. If you are struggling as I did, I suggest starting with these three tests:
  1. It will ordinalize 1 to 1st
  2. It will ordinalize 11 to 11th
  3. It will throw if the number argument is null
Keep adding tests, one at at time. The kata is complete when you feel you have completely specified (designed) the ordinalize function via unit tests, and all of those unit tests pass.

The Focus

In my early TDD days, I also struggled to write only enough code to satisfy the current unit test. For instance, imagine I am writing the code to make test #3 above pass. All that is required is: if (num === null) { throw "Number is null!"; }. But I can anticipate that, for instance, an array or string should throw an error, as well. So I'm tempted to write: if (typeof(num) !== 'number') { throw "num is not a number!"; }. This would make test #3 pass, but it might come at the expense of writing the other tests. And maybe I'm adding behaviors I won't actually need. (Of course, there comes a time where some generalization and anticipation makes sense, and learning when and how best to generalize is one aspect of mastering TDD.)

As you practice this kata's form, focus on writing only enough code to make the current unit test pass. Make the smallest change that makes sense. Also focus on completely specifying the ordinalize function's behavior. The first time I practiced this kata I ended with 7 tests; the last time, 18; and, the highest, nearly 30 (which I felt was over-specifying.) Find what works for you, keeping your focus on the quality of the behaviors, and be open to experimenting from repetition to repetition.

Repeating the Kata

Repeat this kata 3-5 times each time you practice it.

I suggest that you delete all the code you write, both the unit tests the ordinalize function, between each repetition of this kata. I know the temptation to save your work for reference is strong, but you'll benefit more from focusing on the form and the action of the kata, not the product. It's also much easier to walk a new road when the old road is out of sight, and one of the reasons we repeat katas is to vary the form (within its boundaries).

Deleting the code between repetitions doesn't mean you can't take notes. In fact, I've found that taking notes during the kata can be helpful (albeit sometimes distracting), and after finishing a kata, I usually examine the product after a 5-minute water-cooler break, noting what I liked, what I disliked, and what things I want to consider for future repetitions. Then, I issue the cleansing Cmd+A, Del.

Here are some other ideas to consider when repeating this kata:
  • Consider adding a time limit to a repetition, such as 10 or 15 minutes
  • Change the function to test, keeping the keen focus on the TDD cycle; for instance, instead of an ordinalize function, try an email validator (sans regular expression), a color name to hex converter that uses shortcuts (e.g., red to #f00), or a function that calculates the date of Easter using a Computus such as the Golden Number; try to choose something you could TDD in 15 minutes
  • Compare your unit tests with another programmer's before you delete the code; how do your tests compare? What can you learn from the differences? What can you learn from their unit tests?
  • Pair with another programmer, alternating who writes the test and who writes the code to make it pass; how do the unit tests produced while pairing differ from those produced alone?
  • Use a different unit testing framework, or perhaps a BDD framework; how do your tests differ? How was the experience different?
  • Don't use a unit test framework at all; this means you'll have to develop a way to run tests, define tests, and report the results; how does this experience compare to using a test framework? Do your tests look different?
Cheers,
Drew (twitter.com/anglicangeek)

If you practice this kata, please share your experience in the comments.

Wednesday, May 19, 2010

Stubbing Node Code for TDD

I've been furiously hacking with Node to build Campaign Narrative, a website for hosting and playing role-playing games online. I'm storing data in MongoDB, so I'm building a small library to use the Repository pattern on top of it. Once I had something that worked, I decided to toss my spike code and do it for real (via TDD). That's when I realized I had a problem.

The Problem
My repository library uses the node-mongodb-native library. I need to stub lots of stuff in node-mongodb-native to TDD my repository code. I tried several approaches: changing and extending prototypes, global redefinition, unshifting a folder of stubs into the require paths; none of it worked (or didn't work in a way that made me happy). Because I'd been hacking Ruby very recently, I was approaching the problem from that perspective. Then I wondered, how would I handle this in .NET? I'd use dependency injection.

My Solution
I decided to use an (admittedly very crude) form of constructor injection so I could stub my dependencies. Here is an excerpt from my mongodb_repository.js library:
require("lib/prototypes");
exports.MongoDBRepository = function(config, collectionName, deps) {
  var config = config || {};
  config.merge({
    host: "127.0.0.1",
    port: 27017
  });
  
  deps = deps || {
    Server: require('mongodb/connection').Server,
    Db: require('mongodb/db').Db
  };
  
  this.collectionName = collectionName;
  this.server = new deps.Server(config.host, config.port, {});
  this.db = new deps.Db(config.dbName, this.server)
  
  this.db.open(function(){});
};
You'll notice the third argument of my constructor function, deps. By wrapping all of my dependencies in this deps object (instead of the typical, module-level var dep = require("dep"), I can easily pass stubs in for the dependencies in my test code.

Here is an excerpt of application code that creates a repository object, without passing in deps:
var repositoryConfig = {
  host:   process.env['mongodb-host']   || "127.0.0.1",
  port:   process.env['mongodb-port']   || 27017,
  dbName: process.env['mongodb-name']   || "development" 
};

var accountRepo = new Repository(repositoryConfig, "accounts");
And here is an excerpt from my spec, which passes in stubs for deps:
the("Repository constructor function", function(will) {

  will("use a default host of 127.0.0.1 if no host is provided", function (done) {
    var stubs = {
      Server: function(host, port, options) {
        assert.equal("127.0.0.1", host);
        done();
      },
      Db: function(dbName, server) {}
    };
    stubs.Db.prototype.open = function(callback){ };    
    new Repository(null, "theCollection", stubs);
  });

});
One of the things I really like about this approach is that my tests are that much more intention-revealing, in that it's very clear what is being stubbed. I know it's a small, simple thing, but it makes me happy. I also like that I don't need any special stubbing library.

This approach works just as well with Node's built-in modules. For example, I stub the sys module for the puts function in my Willful spec'ing framework.

How do you stub with Node? Please share your own approach with me!

Cheers,
Drew (twitter.com/anglicangeek)