, mvc, code comments edit

Download the sample project to play with the code as you read this blog post.

Using the DefaultModelBinder in ASP.NET MVC, you can bind submitted form values to arguments of an action method. But what if that argument is a collection? Can you bind a posted form to an ICollection<T>?

Sure thing! It’s really easy if you’re posting a bunch of primitive types. For example, suppose you have the following action method.

public ActionResult UpdateInts(ICollection<int> ints) {

  return View(ints);

You can bind to that by simply submitting a bunch of form fields each having the same name. For example, here’s an example of a form that would bind to this, assuming you keep each value a proper integer.

<form method="post" action="/Home/UpdateInts">
    <input type="text" name="ints" value="1" />
    <input type="text" name="ints" value="4" />
    <input type="text" name="ints" value="2" />
    <input type="text" name="ints" value="8" />
    <input type="submit" />

If you were to take fiddler and look at what data actually gets posted when clicking the submit button, you’d see the following.


The default model binder sees all these name/value pairs with the same name and converts that to a collection with the key ints, which is then matched up with the ints parameter to your action method. Pretty simple!

Where it gets trickier is when you want to post a list of complex types. Suppose you have the following class and action method.

public class Book {
    public string Title { get; set; }
    public string Author { get; set; }
    public DateTime DatePublished { get; set; }

//Action method on HomeController
public ActionResult UpdateProducts(ICollection<Book> books) {
    return View(books);

You might think we could simply post the following to that action method:

Title=title+one&Author=author+one&DateTime=1/23/1975 &Title=author+two&Author=author+two&DateTime=6/6/2007…

Notice how we simply repeat each property of the book in the form post data? Unfortunately, that wouldn’t be a very robust approach. One reason is that we can’t distinguish from the fact that there may well be another Title input unrelated to our list of books which could throw off our binding.

Another reason is that the checkbox input does not submit a value if it isn’t checked. Most input fields, when left blank, will submit the field name with a blank value. With a checkbox, neither the name nor value is submitted if it’s unchecked! This again can throw off the ability of the model binder to match up submitted form values to the correct object in the list.

To bind complex objects, we need to provide an index for each item, rather than relying on the order of items. This ensures we can unambiguously match up the submitted properties with the correct object.

Here’s an example of a form that submits three books.

<form method="post" action="/Home/Create">

    <input type="text" name="[0].Title" value="Curious George" />
    <input type="text" name="[0].Author" value="H.A. Rey" />
    <input type="text" name="[0].DatePublished" value="2/23/1973" />
    <input type="text" name="[1].Title" value="Code Complete" />
    <input type="text" name="[1].Author" value="Steve McConnell" />
    <input type="text" name="[1].DatePublished" value="6/9/2004" />
    <input type="text" name="[2].Title" value="The Two Towers" />
    <input type="text" name="[2].Author" value="JRR Tolkien" />
    <input type="text" name="[2].DatePublished" value="6/1/2005" />
    <input type="submit" />

Note that the index must be an unbroken sequence of integers starting at 0 and increasing by 1 for each element.

The new expression based helpers in ASP.NET MVC 2 will produce the correct format within a for loop. Here’s an example of a view that outputs this format:

<%@ Page Inherits="ViewPage<IList<Book>>" %>

<% for (int i = 0; i < 3; i++) { %>

  <%: Html.TextBoxFor(m => m[i].Title) %>
  <%: Html.TextBoxFor(m => m[i].Author) %>
  <%: Html.TextBoxFor(m => m[i].DatePublished) %> 

<% } %>

It also works with our templated helpers. For example, we can take the part inside the for loop and put it in a Books.ascx editor template.

<%@ Control Inherits="ViewUserControl<Book>" %>

<%: Html.TextBoxFor(m => m.Title) %>
<%: Html.TextBoxFor(m => m.Author) %>
<%: Html.TextBoxFor(m => m.DatePublished) %> 

Just add a folder named EditorTemplates within the Views/Shared folder and add Books.ascx to this folder.

Now change the original view to look like:

<%@ Page Inherits="ViewPage<IList<Book>>" %>

<% for (int i = 0; i < 3; i++) { %>

  <%: Html.EditorFor(m => m[i]) %>

<% } %>

Non-Sequential Indices

Well that’s all great and all, but what happens when you can’t guarantee that the submitted values will maintain a sequential index? For example, suppose you want to allow deleting rows before submitting a list of books via JavaScript.

The good news is that by introducing an extra hidden input, you can allow for arbitrary indices. In the example below, we provide a hidden input with the .Index suffix for each item we need to bind to the list. The name of each of these hidden inputs are the same, so as described earlier, this will give the model binder a nice collection of indices to look for when binding to the list.

<form method="post" action="/Home/Create">

    <input type="hidden" name="products.Index" value="cold" />
    <input type="text" name="products[cold].Name" value="Beer" />
    <input type="text" name="products[cold].Price" value="7.32" />
    <input type="hidden" name="products.Index" value="123" />
    <input type="text" name="products[123].Name" value="Chips" />
    <input type="text" name="products[123].Price" value="2.23" />
    <input type="hidden" name="products.Index" value="caliente" />
    <input type="text" name="products[caliente].Name" value="Salsa" />
    <input type="text" name="products[caliente].Price" value="1.23" />
    <input type="submit" />

Unfortunately, we don’t have a helper for generating these hidden inputs. However, I’ve hacked together an extension method which can render this out for you.

When you’re creating a form to bind a list, add the following hidden input and it will add the appropriate hidden input to allow for a broken sequence of indices. Use at your own risk!I’ve only tested this in a couple of scenarios. I’ve included a sample project with multiple samples of binding to a list which includes the source code for this helper.

<%: Html.HiddenIndexerInputForModel() %>

This is something we may consider adding to a future version of ASP.NET MVC. In the meanwhile, give it a whirl and let us know how it works out for you.

Technorati Tags: aspnetmvc,modelbinders

personal comments edit

I just can’t help myself. I said I wouldn’t be one of those parents, but forget it. I am one of those parents. I think my kid is adorable, so sue me. Check out Cody’s halloween costume. He’s with his BFF Forever, Alex the Panda.

Meet, Codysaurus!


Coming to terrorize a neighborhood near you., mvc comments edit

Today we finally officially released the beta of ASP.NET MVC (go download it already!).

True, the release has actually been available online since yesterday as it was announced in a Keynote at VSLive by Scott Hanselman, but that was intended to be a special treat for attendees in what ended up being the worst kept secret in .NET-dom.

As usual, to get all the details, check out the latest epic installment on ScottGu’s blog. Scott Hanselman also has a great blog post with good coverage as well.

As I warned before, we no longer bundle the Mvc Futures assembly (Microsoft.Web.Mvc.dll). However, we did just publish a release of this assembly updated for Beta on CodePlex. Source code for the Beta and Futures releases will be pushed to CodePlex shortly. Sorry about the delay but there’s so much work to be done here. :)

One very exciting element to this release is that we’ve included JQuery (as I mentioned before) and are indeed the first Microsoft product to include it. One of the first Microsoft products (AFAIK) to bundle a third-party open source component.

The following list (each a link to the GU’s blog) show’s what’s new in the Beta.

What’s new in ASP.NET MVC Beta?

I hope you enjoy this release and the plan from here on out is primarily to focus on stabilization. This means fixing bugs, making design change requests which we feel hit meet a high bar, and getting the product ready for RTM. However, as Scott mentioned, there are a few new features we’re planning, especially with Visual Studio tooling.

personal comments edit

bowl-mm Today marks my one year anniversary at Microsoft. Tradition dictates that I bring in a pound of M&Ms for each year that I’ve been an employee. I’m going to buck that trend (because I like bucking things) and bring in 1 kilo of Japanese candies. Since I just returned from a trip to Japan and it is also customary to bring gifts back from a trip, this ends up killing two birds with one stone. Software is not the only place to apply the DRY principle.

Looking back at when I first was hired and later at my first days when I drank from the firehose, working here feels a lot different now than it did then. I finally feel a lot more settled at Microsoft, though there are still many days when I feel like a new hire, or even as a bit of an outsider.

The other day in an IM chat with Scott Hanselman, he made some comment about how us Microsofties love our app_codeApp_Data directory. Hey man, his badge is just as blue as mine, but I understand the sentiment. Guys like us are referred to as “industry hires” as opposed to college hires. Many of the developers here happen to be college hires. The theory is that industry hires will bring a fresh perspective, but I think we just mostly get in everyone’s way and stir up trouble.

So what have I done in this past year?

I’ve spoken at five conferences (Tech-Ed Hong Kong, TechReady 6 and 7, DevScovery, MVP Global Summit) and two internal TAP events. I’ve attended two other conferences (Mix 08, Google IO). For the most part, I think I’ve gotten over my stage fright, which was intense in the beginning. Hopefully, I’ve also improved as a speaker, but I still cringe when I hear myself speak.

I’ve been involved in around four or five ASP.NET MVC preview releases (I’ve lost count) as well as the release of ASP.NET 3.5 SP1 (ASP.NET Routing feature) and a CodePlex release of ASP.NET Dynamic Languages support. I’m particularly excited about taking ownership of our DLR support for ASP.NET and hope that in the new year I can push that forward.

I’ve also been involved in division wide efforts to help other teams understand Test Driven Development so that our products moving forward will take TDD into consideration in the design of their products.

Amidst all this, I even found some time to get Subtext 2.0 out the door. Open source software remains a passion for me and I’m very excited about all the progressive changes that have happened here in the past year from us including JQuery in our offering to the opening up of licensing in various products such as MEF.

What’s Next For Me?

I think I’ll stay here for a while. My wife and I really like it in Bellevue and so far, I’m really enjoying the work here. In the next year, I’ll be taking on more responsibilities. I’ll be taking ownership for driving our TDD efforts, hoping to obtain a few small wins here and there. Baby steps.

I’ll also keep driving ASP.NET MVC towards RTM and put together a plan and strategy together for our Dynamic Languages effort.

I’m still trying to wrap my head around the PM role here at Microsoft. My managers never fail to remind me that while I’m doing fine at the technical and community side of things, I really need to improve the project management side of things. Understandable, I’m doing great at the fun stuff, but not so good at the part that I don’t find so fun. :)

In any case, as I did before, I want to thank many of you for helping me with my job. There have been many large design improvements to ASP.NET MVC that quite possibly wouldn’t have happened were it not for your constant feedback. It really is appreciated. comments edit

I’ve used the term “drinking from the fire hose” when describing my first days at Microsoft. However, I believe that a lot of our customers feel this way when approaching the plethora of options for web application development on the Microsoft stack.

This is feedback we’ve received from many sources and as Scott Hanselman pointed out, there’s a concerted effort to make things easier to find and understand here. Much of these efforts will take time to see fruition, but some of them are happening now.

The new Microsoft Web Platform Installer Beta can get you up and running developing on ASP.NET in two easy clicks.

First, you select an option from the first screen. Obviously, if you choose the Your Choice option, it’ll take more than two clicks.


I chose the ASP.NET Developer option and clicked Next.


The second screen lets you choose to accept the licensing terms. This is nice in that you don’t have to go and click through 20 different EULAs.


Once you click I Accept the installer begins.

If you want more control, you can choose Your Choiceat the first screen which takes you to a screen that lets you choose all sorts of options.


This is a great tool for someone who wants to quickly get started learning and developing on ASP.NET. You’ll notice that it doesn’t include ASP.NET MVC yet. Don’t worry, it will once we have a proper beta release.

If you run into any problems with it, be sure to report it on their forums. For more information, be sure to read the announcement on Bill Staple’s blog.

In case you missed my first link to the beta for the installer, it’s here.

code comments edit

UPDATE: Pretty much disregard this entire post, except as a reminder that it’s easy to make a mistake with DOCTYPEs and markup. As many people have told me, I had an error I didn’t notice in the original HTML. I forgot to close the SELECT tag. I’ll leave the post as-is.

Not only that, the DOCTYPE is not specified in the document, which causes IE to render in Quirks mode, not standards mode. So I guess the bug is in IE 7 rendering.

So this is a case of PEBKAC, the bug is in the HTML, not the browser.

Here’s an example of the HTML with the SELECT tag properly closed and the proper DOCTYPE. It renders correctly in FireFox 3 and IE 8.

In testing our helper methods for rendering a <select /> element which has some styling applied to it if the element has a validation error, a developer on the MVC team found an interesting bug in how browsers render a select element with a border applied to it via CSS. Check out the following HTML.

<style type="text/css">
select {
border: 1px solid #ff0000;
color: #ff0000;
<select >

Here’s how IE 8 renders it. Notice there’s no border. UPDATE: According to people on twitter, this is because I left out the doctype, so IE8 rendered it in old quirks mode, not standards mode.


Here’s Firefox 3. There’s a border, but there’s two drop-down arrows.


Here’s Google Chrome, which gets it right. Since Google Chrome uses the Safari Webkit rendering engine, I believe Safari gets it right as well. I didn’t test it personally, but Opera gets it right too.


Now if you add the following meta tag to the <head /> section of the HTML.

<meta http-equiv='X-UA-Compatible' content='IE=8'>

IE 8 now renders correctly.


You can see for yourself by pointing your browser to an example with the meta tag and without it.

personal comments edit

Just got back from our trip to latest Japan yesterday morning. On previous trips, I ate really great Yakitori, ate Blowfish and lived to tell about it, celebrated the new year, , learned about ritual suicide and played around with sharp swords, visited a temple in the midst of old Tokyo, and visited the hotel from Spirited Away.

PalaceThis trip was mostly a relaxing affair consisting of eating good food and lying around doing as much nothing as we could muster. Unfortunately, travelling with a 15 month old child meant that the amount of actual relaxation to be had was certain to be capped.

The most exciting part of the trip was my first ever visit to Kyoto, a beautiful city full of Shinto shrines and beautiful temples. It is also the namesake of the Kyoto Protocol.

Japan Trip
763I’ve uploaded a fair amount of photos to FaceBook, but I thought I’d share a few here along with a brief commentary. These first two shots are of a stunning building covered in gold leaf. The leaf is very securely fastened to the building. Don’t ask me how I know that.

Apparently, there’s a silver temple in Kyoto as well, but the guy building it ran out of money before it was ever covered in silver.

While in Kyoto, we stayed at the Westin Miyako Kyoto. They have two types of rooms, the traditional western style you all know and love, and the Japanese style as seen in this next photo, exquisitely modeled by my son. These consist of a single large simple room. At night, they put away the table and chairs and lay down tatami mats.

Japan Trip

Thankfully, the toilet was western style because I’m not so talented at squatting.

The landscaping and natural beauty of many of the shrines and temples were simply astounding. And it’s no accident. We saw one guy painstakingly hand picking out tiny little weeds on a huge lawn.

Japan Trip
674One of the highlights of this trip was meeting Cody’s cousin, Rio, for the first time.

Japan Trip

 Japan Trip
802 Japan Trip

As you can see in the photo, she’s already learned the fine art of giving a Wet-u Wirry (Wet Willy in English). Perhaps that’s payback for all the bear hugs Cody attempted to give her which ended becoming football tackles.

In any case, if you’re ever taking a long trip to Japan, be sure to try and fit Kyoto into your itinerary. I really love Tokyo for its Blade Runneresque hyper neon modernism, which makes a visit to Kyoto so complementary for its ancient feeling.

comments edit

I had a bit of a rough start to my first Tech-Ed Hong Kong last week. Pretty much every day while I was in Japan, I dutifully pulled out the laptop (despite my lack of internet connection) and made sure it still worked fine.

Things seemed to be looking up when I got a free business class upgrade on the way to Hong Kong from Tokyo for giving up my seat. It meant taking a longer flight, but I had a really enjoyable flight. But while waiting in the airport lounge, I decided to take advantage of the free Wi-Fi there, but couldn’t get my computer screen to display anything. Hoping it was some weird hibernation issue, I put my laptop away and decided to wait till I was in HK.

Japan Trip
883 Sure enough, the screen still didn’t work. Fortunately, I follow rule #1 of the Joel Test for all my presentations and keep it all in source control using a private instance of Subversion. A member of Microsoft Hong Kong kindly lent me his laptop (thank you!) and I got it into more-or-less working order, as you can see from this shot of the room just before I began my first talk on ASP.NET MVC.

Even so, working on an unfamiliar laptop is still a pain and there were a few hitches in demos where I wasn’t sure how to change various display modes quickly on the laptop.

Since my talks were all in the morning, it gave me time to travel around a bit.

Japan Trip
889 Japan Trip

I took a tram up to Victoria Peak to get an eye catching panoramic view of the city, though the day I chose to go was not as beautiful as the next two days.

On the first night, there was a little Microsoft get-together for MVPs and employees at Cenna Bar and Lounge. The entrance to the place is practically hidden via a non-descript doorway on this street. You walk in, and take the lift up to the 23rd floor and suddenly you’re in this small but hip little bar.

Seems like a lot of cool places are hidden away up high in these buildings.

Japan Trip
918 Japan Trip

I really enjoyed the opportunity to have some great conversations with various Chinese people, as many of the attendees were from mainland China. In our conversations I realized that certain stereotypes we tend to have over in the U.S. are completely not valid. In principle, I know this is usually the case, but it often takes engaging in very interesting conversations for that to really hit home.

Japan Trip
926   Japan Trip

Japan Trip
928 Japan Trip

Afterwards, a small group of us went shopping. There is no sales tax on most items in Hong Kong, so it’s a popular place for Chinese shoppers. I merely tagged along for the experience.

The next day I did some more sight-seeing around the city, taking a Star Ferry across to Kowloon and then walking around the Central and Wan-Chai districts afterwards.

Japan Trip
937  Japan Trip

 Japan Trip
952 Japan Trip

On the last evening, I met up with an old friend from college from Hong Kong for a night on the town in which we mixed and mingled with the local denizens.

Japan Trip
962 Japan Trip

Japan Trip
974 Japan Trip

Notice that Microsoft’s LINQ technology is so popular that there’s a bar named after it. I believe another bar called “to SQL” was just around the corner.

As a strategy to beat jet lag, I ended up staying out all night until it was time to catch a cab to the airport, stopping at my hotel room to quickly grab my things. I’ll let you know tomorrow if it worked.

personal,, mvc comments edit

Where have I been? ;) You probably heard the news already from the GU already, but just in case, we will be shipping JQuery with Visual Studio. ASP.NET MVC will have the privilege of being one of the first products to include JQuery. I am glad we finally announced this because I got tired of stifling my mouth everytime someone suggested we just include JQuery. :)

As you can see from demos I’ve done in the past, JQuery will fit nicely with the ASP.NET MVC style of development.

personal comments edit

The internet access I had at my mother-in-law’s last time I was in Japan turned out to be a fluke. I am at a Japanese Manga and Internet cafe (because those three things go so well together) right now typing this out. I’ve received a lot of comments and questions via my blog and once I get to Hong Kong, I will do my best to answer.

No promises though as I hear that the pool at the hotel is nice and I do have three talks to prepare. I must admit that not having daily internet access is probably a good thing for me as I’m a total online junkie. :)

The next time we visit, I need to remember to bring more reading material. I brought two books on Poker and am tired of reading about it. ;)

Technorati Tags: japan,tokyo, dlr comments edit

This afternoon we released a refresh of our DLR/IronPython support for ASP.NET, now called “ASP.NET Dynamic Language Support”, on our CodePlex site.

This was originally part of our July 2007 ASP.NET Futures package, along with several other features. As updates to these features were made available, we would have liked to remove them from the package, but we wanted to wait till everything within the package was updated.

Well that time has come. This CodePlex release contains two exceedingly simple sample applications, one for WebForms and one for ASP.NET MVC. It’s compiled against the latest DLR assemblies, and our goal is to continue to push it forward fixing bugs here and there. Keep in mind that this initial refresh is pretty barebones and doesn’t contain everything that the original package contained because certain features (such as the project system) are still being updated.

I won’t go too deeply into the specifics of how to use it. Instead, be sure to check out David Ebbo’s whitepaper on IronPython and ASP.NET which was written a while ago, but still mostly relevant. Also, Jimmy Schementi from the DLR team has written a nice brief write-up on this release.

I have the pleasure of taking over as the PM for this feature (in MS parlance we’d say I “own” this feature now) which nicely complements my duties as the PM for ASP.NET MVC. If you’ve followed my blog, you know I have an interest in dynamic languages and now I can channel that interest into work time, rather than on my own time. :)

This initial release only has IronPython support, but IronRuby support will be coming soon. This gives me an opportunity to learn a bit about Python, and let me tell you, the fact that whitespace matters in this language can be nice within a normal code file, but a real pain within a view.

One nice thing about this implementation above and beyond my old IronRuby prototype is that it has true support for a file, the IronPython equivalent for Global.asax.cs. This allowed me to define my routes in IronPython directly in that file rather than reading in a separate file. I did implement some helper methods in C# that make it easy to define routes using a Python dictionary.

personal comments edit

If you happen to be in Asia around October 8-10, I’ll be speaking at Tech-Ed Hong Kong. Come by and say hi. I’m giving three talks, one on each day.

Date Time Talk
October 8 11:45 AM – 1:00 PM ASP.NET MVC  - An alternative approach to building Web Applications
October 9 11:00 AM – 12:15 PM Developing Data Driven Applications Using ASP.NET Dynamic Data
October 10 9:30 AM – 10:45 AM Write better designed code with Test Driven Development

hong_kongI’m hoping to have a little time after some of my talks to go do a little sight-seeing around Hong Kong. The trip to Hong Kong is actually a side trip from Japan where my wife and kid will stay while I go and and speak at this conference. I’m looking forward to the vacation, but wish I had scheduled the vacation part after the conference, rather than before. Lesson learned!

Technorati Tags: conferences,aspnetmvc,tdd,dynamic data, mvc comments edit

pdc2008 First of all, I want to congratulate Jeff Atwood, Joel Spolsky, and their team for the release of If you haven’t tried it out, I highly recommend giving it a shot. Be prepared, it’s addicting.

Besides my 959 reputation score (which is actually pretty weak), the other thing about StackOverflow that excites me is that it’s built using ASP.NET MVC. So far, Jeff has mostly praised the experience of using ASP.NET MVC, though he’s had a few pain points that I’m now well aware of. :)

LogoI like StackOverflow so much that I asked Jeff to take a 10-15 minute slice of my ASP.NET MVC talk at PDC to talk about his experiences building StackOverflow using ASP.NET MVC. Having a demonstration of a real-world application using ASP.NET MVC will be a nice complement to my overview talk. For the rest of the talk, he’ll be my code monkey.

By the way, if you’re planning to attend PDC, please navigate to the link to my talk and leave a comment with any requests for things you’d love to hear me talk about. I am currently planning to give the general overview, but perhaps some of you want to hear more anecdotes from the product team, or more details about specific features.

Technorati Tags: aspnetmvc,stackoverflow,pdc2008 mvc, comments edit

UPDATE: The MVC Futures assembly, Microsoft.Web.Mvc is available on CodePlex.

Wanted to provide a quick heads up about the MvcFutures assembly within ASP.NET MVC CodePlex Preview 5. As mentioned in various places, this assembly contains various experimental features we are considering for future versions of ASP.NET MVC.

When we release the BETA for ASP.NET MVC, it will not automatically be included in the project template by the installer. We’ve included it in the various previews for convenience, but we want the BETA installer to be as close to the RTM installer experience as possible.

We will make sure that the assembly remains available on CodePlex. I just wanted to make you aware of this so there is no surprises when we release the Beta regarding this. Thanks!

Technorati Tags: aspnetmvc mvc, comments edit

This is one of them “coming of age” stories about how a lowly method becomes a full fledged Action in ASP.NET MVC. You might think the two things are the same thing, but that’s not the case. It is not just any method gets to take the mantle of being an Action method.


Like any good story, it all begins at the beginning with Routing. By default, one of the routes defined in the MVC project template has the following URL pattern:


When a request comes in and matches that route, we populate a dictionary of route values (accessible via the RequestContext) based on this route. For example, if a request comes in for:


We add the key “action” with the value “list” to the route values dictionary (We’ve also added “home” as the value for “controller”, but that’s for another story. This is the story of the action.) At the heart of it, an action is just a string. That’s how it starts out after all, as a sub string of the URL.

Later on, when the request is handed of to MVC, MVC interprets the value in the route values for “action” to be the action name. In this case, it knows that the request should be handled by the action “list”. Contrary to popular belief, this does not necessarily mean that a method named List will handle this request,as we’ll soon see.

Action Method Selection

Once we’ve identified the name of the action, we need to identify a method that can respond to that action. This is the job of the ControllerActionInvoker.

By default, the invoker simply uses reflection to find a public method on a class that derives from Controller which has the same name (case insensitive) as the current action.

Like many things within this framework, you can tweak this default behavior.


Introduced in ASP.NET MVC CodePlex Preview 5 which we just released, applying this attribute to a method allows you to specify the action that the method handles.

For example, suppose you want to have an action named View, this would conflict with the View method of Controller. An easy way to work around this issue without having to futz with routing or method hiding is to do the following:

public ActionResult ViewSomething(string id)
  return View();

The ActionNameAttribute redefines the name of this action to be “View”. Thus this method is invoked in response to requests for /home/view, but not for /home/viewsomething. In the latter case, as far as the action invoker is concerned, an action method named “ViewSomething” does not exist.

One consequence of this is that if you’re using our conventional approach to locate the view that corresponds to this action, the view should be named after the action, not after the method. In the above example (assuming this is a method of HomeController), we would look for the view ~/Views/Home/View.aspx by default.

This attribute is not required on an action method. Implicitly, the name of a public method serves as the action name for that method.


We’re not done yet matching the action to a method. Once we’ve identified all methods of the Controller class that match the current action name, we need to whittle the list down further by looking at all instances of the ActionSelectionAttribute applied to the methods in the list.

This attribute is an abstract base class for attributes which provide fine grained control over which requests an action method can respond to. The API for this method is quite simple and consists of a single method.

public abstract class ActionSelectionAttribute : Attribute
  public abstract bool IsValidForRequest(ControllerContext controllerContext
    , MethodInfo methodInfo);

At this point, the invoker looks for any methods in the list which contain attributes which derive from this attribute and calls the IsValidForRequest() method on each attribute. If any attribute returns false, the method that the attribute is applied to is removed from the list of potential action methods for the current request.

At the end, we should be left with one method in the list, which the invoker then invokes. If more than one method can handle the current request, the invoker throws an exception indicating the problem. If no method can handle the request, the invoker calls HandleUnknownAction() on the controller.

The ASP.NET MVC framework includes one implementation of this base attribute, the AcceptVerbsAttribute.


This is a concrete implementation of ActionSelectionAttribute which uses the current HTTP request’s http method (aka verb) to determine whether or not a method is the action that should handle the current request.

This allows for having two methods of the same name (different parameters of course) to both be actions, but respond to different HTTP verbs.

For example, we may want two versions of the Edit method, one which renders the edit form, and the other which handles the request when that form is posted.

public ActionResult Edit(string id)
  return View();

public ActionResult Edit(string id, FormCollection form)
  //Save the item and redirect…

When a POST request for /home/edit is received, the action invoker creates a list of all methods of the controller that match the “edit” action name. In this case, we would end up with a list of two methods. Afterwards, the invoker looks at all of the ActionSelectionAttribute instances applied to each method and calls the IsValidForRequest() method on each. If each attribute returns true, then the method is considered valid for the current action.

For example, in this case, when we ask the first method if it can handle a POST request, it would respond with false because it only handles GET requests. The second method responds with true because it can handle the POST request and it is the one selected to handle the action.


One consequence to keep in mind when using helpers which use our routing API to generate URLs is that the parameters for all of these helpers take in the action name,not the method name. So if I want to render the URL to the following action:

public ActionResult ListSomething()

Use “List” and not “ListSomething” as the action name.

<!-- WRONG! -->
<%= Url.Action("ListSomething") %>

<!-- RIGHT! -->
<%= Url.Action("List") %>

This is one reason you’ve seen the MVC team resistant to including helper methods, such as Url<T>(…), that use an expression to define the URL of an action. The action is not necessarily equivalent to a method on the class with the same name.


So in the end, an action is a logical concept that represents an event caused by the user (such as clicking a link or posting a form) which is eventually mapped to a method which handles that user event.

It’s convenient to think of an action as a method of the same name, but they are distinct concepts. A lowly method can become an action by the power of its own name (aka name dropping), but in this egalitarian framework, any method, no matter its name, can handle a particular action, by merely using the ActionNameAttribute.

Technorati Tags: aspnetmvc,routing, mvc, code comments edit

Download the MSI and Release notes here.

Last night we released ASP.NET CodePlex Preview 5 on CodePlex. Be on the lookout for one of those famous epic blog posts from ScottGu describing the release. In the meanwhile, the release notes contain short write-ups of what has changed.

We didn’t originally plan to have another preview. However, we implemented a few significant chunks of functionality and were dying to get feedback so that we could incorporate it into the product before Beta. It helps that with five or so of these interim releases, we’ve become pretty efficient producing these releases.

We plan to have our next release be our official Beta, which means we’ll have a lot more test passes to produce and run before we release the next one.

In the meanwhile, take the code for a test drive and let us know what you think. Some of the naming needs to be cleaned up, so you can expect some name changes and improvements to the API from here to Beta, along with a lot of bug fixes and a few more features. Naming classes is tough, so we appreciate good suggestions there. :)

One change that I think I forgot to mention in the release notes is that the Ajax helpers do not accept inline script any longer, they take method names. Those helpers are all in their own namespace now as extension methods which allow you to completely swap them out with ones of your own.

If you’re interested in more details about how our action method selection works, be sure to read my post entitled How a Method Becomes an Action. Be sure to keep an eye on Brad Wilson’s blog too, as he put in some work on this feature and will describe the view engine changes.

UPDATE: Brad just blogged about partial rendering and view engines in ASP.NET MVC.

Technorati Tags: aspnetmvc,

tdd, code comments edit

I admit, up until now I’ve largely ignored the BDD (Behavior Driven Development) Context/Specification style of writing unit tests. It’s been touted as a more approachable way to learn TDD (Test Driven Development) and as a more natural transition from user stories to the actual code design. I guess my hesitation to give it a second thought was that I felt I didn’t need a more approachable form of TDD.

Recently, my Subtext partner in crime, Steve Harman, urged me to take another fresh look at BDD Context/Specification style tests. I trust Steve’s opinion, so I took another look and in doing so, the benefits of this approach dawned on me. I realized that it wasn’t BDD itself I didn’t like, after all, I did enjoy writing specs using minispec and IronRuby. I realized that the part I didn’t really like was the .NET implementations of this style. Keep in mind that I do not claim to be an expert in TDD or BDD, I’m just a student and these are just my observations. I’m sure others will chime in and provide corrections that we can all learn from.

SpecUnit.NET example

For example, let’s take a look at one example pulled from the sample project of Scott Bellware’s SpecUnit.NET project, which provides extensions supporting the BDD-style use with .NET unit testing frameworks and has really pushed this space forward. I trimmed the name of the class slightly by removing a couple articles (“the” and “an”) so it would fit within the format of my blog post.

[Concern("Funds transfer")]
public class when_transfering_amount_greater_than_balance_of_the_from_account
  : behaves_like_context_with_from_account_and_to_account
  private Exception _exception;

  protected override void Because()
    _exception = ((MethodThatThrows) delegate
      _fromAccount.Transfer(2m, _toAccount);

  public void should_not_allow_the_transfer()

  public void should_raise_System_Exception()

The Because method contains the code with the behavior we’re interested in testing. The two methods annotated with Observation are the specifications. Notice that the names of the classes and methods are meant to be human readable. The output of running these tests remove underscores and reads like a specification document. It’s all very cool.

What I like about this approach is there’s a crisp focus on having each test class focused on a single behavior, in this case transferring a balance from one account to another. In the past, I might have written something like this as two test methods (which led to duplicating code or putting code in some generic Setup method that seems detached from what I’m trying to test) or as one method with two asserts. This approach helps you think about how to organize tests along the lines of your objects’ responsibilities.

What I don’t like about it, and I admit this is really just a nitpick, is that it looks like someone’s keyboard puked underscores all over the place. I feel like having to encapsulate each observation as a method adds a lot of syntactic overhead when I’m trying to read this class from top to bottom. Maybe that’s just something you get used to.

MSpec example

Switching gears, let’s look at a different example by Aaron Jensen. This is an experiment in which he tried a very different approach. Look at this code sample…

public class Transferring_between_from_account_and_to_account   
  static Account fromAccount;   
  static Account toAccount;   
  Context before_each =()=>   
    fromAccount = new Account {Balance = 1m};   
    toAccount = new Account {Balance = 1m};   
  When the_transfer_is_made =()=>   
    fromAccount.Transfer(1m, toAccount);   
  It should_debit_the_from_account_by_the_amount_transferred =()=>   
  It should_credit_the_to_account_by_the_amount_transferred =()=>   

There’s still the underscore porn, but it does read a little more like prose from top to bottom, if you can get yourself to ignore that funky operator right there. =()=> Whoa!

When I complained to Steve about all the underscores in these various approaches, he suggested that being a fan of the more Zen-like Ruby language, the underscores didn’t bother him. I didn’t buy that as part of the aesthetic of Ruby is its clean DRY minimalism. Yes, it uses underscores, but it doesn’t generally abuse them. Let’s take a look at a BDD example using RSpec and Ruby. This is an example of a spec in progress from Luke Redpath… (forgive the poor syntax highlighting. I need a ruby css stylesheet. :)

context "A user (in general)" do 
  setup do 
    @user = 

  specify "should be invalid without a username" do 
    @user.errors.on(:username).should_equal "is required" 
    @user.username = 'someusername' 

  specify "should be invalid without an email" do 
    @user.errors.on(:email).should_equal "is required" = '' 

One thing to notice is that we’re not using separate methods and classes here. Ruby doesn’t force you to put code in classes. You can just execute a script top-to-bottom. In this case, the code sets up a context block and within that block there is a setup block and a couple of specify blocks. There’s no need to factor a specification into multiple classes and methods.

Also notice that the context and specifications are described using strings! Now we’re getting somewhere. If it’s meant to be human readable, why don’t we use strings instead of the underscore porn? On Twitter, many accused the ceremony and vagaries of C# of preventing this approach. While I agree that Ruby has less ceremony than C#, I also think C# doesn’t get its fair shake sometimes. We can certainly take a C# approach down to its bare metal with the least syntactic noise as possible, right?


So in true Program Manager at Microsoft fashion, I spec’d out a rough idea of the syntax I would like to use with BDD. I then showed it to Brad Wilson asking him how can I make this work in In true Developer fashion, he ran with it and made it actually work. This blog post is the part where I try to take all the credit. That’s what PMs do at Microsoft, write specs, take credit for the hard work the developers do in bringing the specs to life. ;) (I kid, I kid)

Here’s an example using this syntax…

public void PushNullSpecifications()
  Stack<string> stack = null;

  "Given a new stack".Context(() => stack = new Stack<string>());

  "with null pushed into it".Do(() => stack.Push(null));

  "the stack is not empty".Assert(() => Assert.False(stack.IsEmpty));
  "the popped value is null".Assert(() => Assert.Null(stack.Pop()));
  "Top returns null".Assert(() => Assert.Null(stack.Top));

A few things to notice. First, the entire spec is in a single method, which reduces some of the syntactic noise of splitting the spec into multiple methods. Secondly, we’re using strings here to describe the specification and context, rather than method names with underscores for the human readable part.

Lastly, and most importantly, while it may look like we’re committing the sin of multiple asserts in a single test, this is not the case. Via the power of the xUnit.NET extensibility model, Brad was able to generate a test per assertion. That’s why the Assert method (should it be Observe or Fact?) takes in a lambda. We can return these closures to and it will wrap each one in a separate test. Here’s another look at the same method with some comments to highlight how similar this is to the previous examples. (UPDATE: I also changed the asserts to use the Should style extension methods to demonstrate what it could look like).

public void PushNullSpecifications()
  Stack<string> stack = null;
  //equivalent to before-each
  "Given a new stack".Context(() => stack = new Stack<string>());

  //equivalent to Because()
  "with null pushed into it".Do(() => stack.Push(null));

  //Equivalent to [Observation]
  "the stack is not empty".Assert(() => stack.IsEmpty.ShouldBeFalse());
  //Equivalent to [Observation]
  "the popped value is null".Assert(() => stack.Pop().ShouldBeNull());
  //Equivalent to [Observation]
  "Top returns null".Assert(() => stack.Top.ShouldBeNull());

Keep in mind, at this point, this is a merely proof-of-concept sample that will be included with the samples project in the next version of xUnit.NET and by the time you read this sentence, it may have changed already. You can download this particular changeset here.

The following is a screenshot of the HTML report generated by xUnit.NET when using this syntax that Brad sent me today.subspec-report

Despite it being a sample, I tried to give it a catchy name in case this is intriguing to others and worth iterating on to make it better (not to mention that I love putting the prefix “Sub” in front of everything.)

Possible next steps would be to add all the Woulda, Coulda, Shoulda extension methods so popular with this style of testing. For example, that would allow you to replace Assert.False(stack.IsEmpty) with stack.IsEmpty.ShouldBeFalse(). For those of you practicing BDD, I’d be interested in hearing your thoughts, objections, etc… concerning this approach.

For completeness sake, here’s another syntax I proposed to Brad. He mentioned it was similar to something else he’s seen which he might port over to

public void When_Transferring_To_An_Account()
  Election e = null;
  Account a = null;
  Account b = null;
  Where("both accounts have positive balances", () => {
    a = new Account { Balance = 1 };
    b = new Account { Balance = 2 };
  When("transfer is made", () =>
    a.Transfer(1, b)
  It("debits account by amount transferred", () => a.Balance.ShouldBe(0));
  It("credits account by amount transferred", () => b.Balance.ShouldBe(3));

For those of you completely new to BDD, check out Scott Bellware’s Code Magazine article on the subject.

Technorati Tags: tdd,bdd,

personal comments edit

As Scott wrote last week, using a punny title I have to admire, he and I (among many others) were both the subject of a DoS (Denial of Service) attack. Looking through my logs, it looks to actually be a DDoS (Distributed Denial of Service) attack coming from multiple IP addresses.

The attack appears to actually be an attempt at a SQL Injection attack, but for his blog, which stores its data in XML files, that is entirely pointless. For my blog, which doesn’t do any inline SQL, it’s also mostly pointless. So far, the SQL injection part of the attack has failed, but it has succeeded in pegging my CPU. Maybe that’s the actual intended goal. Only the attacker knows.

LogParser Queries

The first clue (besides my site being down) is that my log file for today is huge at 9:00 AM.


The next step is to run some queries against my logs using the fantastic LogParser tool. This post, entitled Forensic Log Parsing with Microsoft’s LogParser is a great resource for constructing queries. The focus tends to be more on investigating an actual intrusion. The queries I need are to discover what kind of DoS attack I’m experiencing. Here’s the query I’m using so far…

  logparser "SELECT c-ip, COUNT(*), STRLEN(cs-uri-query) as LENGTH, cs-uri-query 
  FROM C:\WINDOWS\system32\LogFiles\W3SVC1\ex080822.log 
  GROUP BY Length, cs-uri-query, c-ip 
  HAVING Length > 500 
  ORDER BY LENGTH DESC" -rtp:-1 > long-query.txt

Note that I’m running this for a single log file for the day. I could use a wildcard and run this for all my log files. The very last snippet, > long-query.txt, pipes the output to a text file. Here’s a snippet of one of the query strings I’m seeing:


The length of these query strings are all very long. Interestingly enough, there’s no smooth transition in length. For example, there are no query strings of length 500 – 1000.

URL Scan

I then went and installed URLScan 3.0 Beta, which Scott wrote about, and went into the configuration file (located at C:\WINDOWS\system32\inetsrv\urlscan\UrlScan.ini by default and changed the following setting near the bottom:


From its default of 2048 to another smaller value.

The other setting I changed is to allow dots in the path because I have many URLs that contain dots.


Technorati Tags: UrlScan,IIS,DoS,DDoS,Security

code, mvc, comments edit

A commenter to my last post asks the following question,

What is the difference between a beta, a CTP, a fully-supported out of band release, an RTM feature, and a service pack?

The answer you get will differ based on who you ask, but I’ll give you my two cents on what these terms mean.


Let’s start with Beta. A great starting point is this post by Jeff Atwood entitled Alpha, Beta, and Sometimes Gamma.

The software is complete enough for external testing – that is, by groups outside the organization or community that developed the software. Beta software is usually feature complete, but may have known limitations or bugs. Betas are either closed (private) and limited to a specific set of users, or they can be open to the general public.

With the ASP.NET MVC project, all features we plan to implement for RTM should be complete for our Beta. However, the Beta period can influence this and if it seems extremely important, we may take on small DCRs (Design Change Requests).


CTP stands for Community Technology Preview. It’s generally an incomplete preview of a new technology in progress. These usually come out before beta and are a way to gather feedback from the community during the development of a product. This is similar to an Alpha release per Jeff’s hierarchy, except that at Microsoft, we generally do put CTPs in a public location.

With the ASP.NET MVC project, we no longer use the term CTP and simply use the term “Preview”. I think this is due to running out of our TLA (Three Letter Acronym) budget for the year. Our previews do still undergo a QA test pass and are released to the ASP.NET website.

Daily Builds / Interim Releases

The commenter didn’t ask about this, but I thought I would mention it. In many open source projects, you can get a daily build of the software directly from their source code repository. For example, with Subtext, if you want to grab the most recent build, you can go to our builds archive. A daily build is really for those who like to play with fire, as they usually are not tested, and could represent work in progress that is not even working at all.

The closest thing the ASP.NET MVC team has to this is with our periodic “Interim releas”, a term we just made up, that is pushed out to CodePlex and not placed on the ASP.NET website, because of the more mainstream nature of that site.

As much as these CodePlex releases are for the cutting edge audience, being Microsoft, we can’t simply put daily builds out there and say you’re on your own. At least not yet. So these CodePlex builds are sanity checked by our QA team and by me, but they do not go under a full test pass like our Preview releases do. This is an area of experimentation for the ASP.NET team and so far, is proving successful.

Fully Supported Out-of-Band release

Internally, we usually call these OOB releases (pronounced “oob” like it’s spelled).

A Fully Supported Out-of-Band release is a release that is not part of the Framework (i.e. it’s not included in an installation of the .NET Framework), but is fully supported as if it were. For example, you can call up PSS (Microsoft’s Tech Support) for support on a fully supported OOB release.

One example of this was “Atlas” which later became Microsoft Ajax and was rolled into ASP.NET 3.5. ASP.NET MVC 1.0 will be an example of an OOB release.

RTM and RTW release

RTM stands for “Released to Manufacturing” and is a throwback to the days when software was mostly released as CDs. When a project went “Gold”, it was released to manufacturing who then burned a bunch of CDs and packaged them up to be put on store shelves. True, this still goes on today believe it or not, but this mode of delivery is on the decline for certain types of software.

RTW is a related term that stands for “Released to Web” which is more descriptive of how software is actually shipped these days. For example, while we like to use the term RTM internally out of habit, ASP.NET MVC will actually be RTW.

Service Pack

A Service Pack (or SP) is simply an RTM (or RTW) release of fixes and/or improvements to some software. It used to be that SPs rarely included new features, but it seems to be the norm now that they do. Service Packs tend to include all the hotfixes and patches released since the product originally was released, which is convenient for the end user in not having to install every fix individually.

Technorati Tags: beta,ctp,alpha,rtw,rtm mvc, comments edit

I wanted to clear up a bit of confusion I’ve seen around the web about ASP.NET MVC and the .NET Framework 3.5 Service Pack 1. ASP.NET MVC was not released as part of SP1. I repeat, ASP.NET 3.5 SP1 does not include ASP.NET MVC.

What was released with SP1 was the ASP.NET Routing feature, which is in use by both ASP.NET MVC and Dynamic Data. The Routing feature is my first Framework RTM feature to ship at Microsoft! We also shipped a bunch of other features such as Dynamic Data, and this short list of breaking changes.

I hope that clears things up and I apologize for the confusion.

And for my next feat, I’m going to try and read your mind, oooooh! Right now, you’re thinking something along the lines of,

Ok, so ASP.NET MVC didn’t ship as part of SP1. When is it going to ship?!

Good question! Scott Hanselman once quipped that it would ship in a month that ends in “-ber”. He also recently quipped,

Anyway, Phil has always said that MVC is on its own schedule and will ship when its done. Possibly when Duke Nukem Forever ships.

That Scott, he’s so full of quips. ;)

In any case, he’s right in that MVC is pretty much on its own schedule since the first RTM version will be a fully supported out-of-band release, much like Atlas was back in the day.

The MVC team really doesn’t want to rush the first release. We’re taking the time to do the best we can in laying the groundwork for future releases. My hope is that we’ll have very few, if any, moments where we we want to make a breaking change because we didn’t provide the right amount of extensibility.

At the same time, we also really want to get ASP.NET MVC in your hands in an RTM form soon so you can start using it for your clients who are uncomfortable working with a beta technology. Trust me, we are not in the business of the “perpetual-beta” and are working towards an RTM. As Scott pointed out, our hope is to get it out before the end of the year. But as most of you know about how software scheduling works, anything can happen between now and tomorrow.


As we move towards the tail end of the development cycle, we’ve been pushing hard to get our bug/approved change request count down, which I recently twittered about. I asked Carl, our tester, to print out an Excel graph of our bug count over time. It feels really good to walk by his office every day and see the line trending down towards zero (though occasionally, it ticks up a bit). I think it’s a huge motivator to try and fix and close out work items.

At the same time, this graph is for our benefit only and not something we’re being evaluated on by any managers, which is extremely important. One of the dangers of any metric is that developers are smart and they’ll do what they can to optimize the metric. For example, the danger with this metric is that we might be tempted to not log feature requests and bugs. Joel Spolsky wrote about this phenomena when measuring the performance of knowledge workers a while back,

But in the absence of 100% supervision, workers have an incentive to “work to the measurement,” concerning themselves solely with the measurement and not with the actual value or quality of their work.

Since we’re the only ones who care about this graph (nobody is looking over our shoulder) and QA is very motivated to find bugs, I think it’s a safe to use as a fun source of motivation. For the most part, watching the graph move towards zero feels good. Those are the metrics I like, the ones that inspire positive feelings among the team and a sense of forward motion and momentum. :)

Tags: aspnetmvc , aspnet , schedule