asp.net, asp.net mvc comments edit

The ASP.NET and Silverlight team are hiring! Brad Abrams (who happens to be my “grand-boss” as in my boss’s boss) posted a developers wanted ad on his blog:

  • Are you JavaScript guru who has a passion to make Ajax easier for the masses?
  • Are you the resident expert in ASP.NET and consistently think about how data driven applications could be easier to build?
  • Are you a TDD or patterns wonk that sees how ASP.NET MVC is a game-changer?
  • Are you excited about the potential of Silverlight for business applications, and particularly the potential for the ASP.NET+Silverlight combination where we have the great .NET programming model on the server and client?

Some of you out there have provided great insight into how ASP.NET MVC could be better (and then some of you just point out its warts).  Either way, here’s a chance to have an even bigger influence on its design and code. I promise I’m easy to work with.

These are senior developer positions…

My team has several openings for senior, experienced developers with a passion for platform\framework technology. If you have 5+ years of software development industry experience, know how to work effectively in teams, have a great software design abilities and are an excellent developer than we just might have the spot for you!

Oh, and if you do get hired and join my feature team, I like my coffee with milk and sugar. Thank you very much. ;)

Technorati Tags: ASP.NET,ASP.NET MVC,Microsoft,Jobs

code comments edit

camping The Seattle Code Camp (which despite the misleading photo, isn’t a camping trip) is now over and I have nothing but good things to say about it. I didn’t get a chance to see a lot of talks but did enjoy the xUnit.net talk by Jim Newkirk and Brad Wilson. I’m a fan of their approach to providing extensibility and this session provided all the impetus I needed to really give xUnit.net a try rather than simply talking about trying it. :)

As for my own talk, I had the great pleasure of showing up late to my talk. To this moment, I still don’t know why my alarm didn’t go off. All indications are that it was set properly.

My wife woke me up at 9:00 AM asking, “Don’t you have a talk to give today?” I sure did, at 9:15 AM. I drove like a madman from Mercer Island (sorry to all the people I cut off) to Redmond and ended up being around 10 minutes late I think.

Fortunately the attendees were patiently waiting and despite my frazzled approach, I think the presentation went fairly well. Perhaps Chris Tavares can tell me in private how it really went. ;) Thanks to everyone who attended and refrained from heckling me. I appreciate the restraint and thoughtfulness.

By the way, Chris is part of the P&P group, but he’s also a member of the ASP.NET MVC feature team. I think his role is a P&P liason or something like that. Mainly he’s there to give great advice and help us out. So definitely give his blog a look for some great software wisdom.

As this was my first Code Camp, I am definitely looking forward to the next one.

Technorati Tags: Code Camp,ASP.NET MVC

personal comments edit

Well today I turn old. 33 years old to be exact. A day after Hanselman turns really old. It seems I’m always following in that guy’s footsteps doesn’t it?

Oh look, Hanselman gets a blue badge so Phil has to go and get a blue badge. Hanselman has a birthday and Phil has to go and have a birthday on the next day. What a pathetic follower!

What’s interesting is that Rob Conery’s birthday was just a few days ago and we’re all recent hires and involved in MVC in some way. Ok, maybe that isn’t all that interesting after all as it is statistically insignificant, but I thought I’d mention it anyways.

Clustering is a natural occurrence in random sequences. In fact, when looking at a sequence in which there is no clustering, you’d pretty much know it wasn’t random. That’s often what happens when a human tries to make a sequence look random. The person will tend to spread things evenly out. But randomness typically forms clusters. Not only that, but people have a natural tendency to find patterns in sequences and phenomena that don’t exist. But I digress.

Code Camp Seattle

If you’re in the Seattle area this weekend, I’ll be speaking at the Seattle Code Camp. There are several speakers covering various aspects of ASP.NET MVC so I thought I would try not to overlap and maybe cover a bit of an introduction, a few techniques, and some Q & A.

In other words, I’m woefully unprepared because I’ve been so slammed trying to get a plan finalized for MVC that we can talk about. But I’m enlisting Rob’s help to put together some hopefully worthwhile demos. All I really need to do is get a designer involved to make something shiny. ;)

In any case, it’s 2 AM, I need to retire for the evening. I leave you with this photo of my son after he got ahold of a pen while my wife wasn’t looking. It was a brief moment, but that’s all he needed to change his look.

Cody Pen
Moustache

code, tdd comments edit

In a recent post, Frans Bouma laments the lack of computer science or reference to research papers by agile pundits in various mailing lists (I bet this really applies to nearly all mailing lists, not just the ones he mentions).

What surprised me to no end was the total lack of any reference/debate about computer science research, papers etc. … in the form of CS research. Almost all the debates focused on tools and their direct techniques, not the computer science behind them. In general asking ’Why’ wasn’t answered with: “research has shown that…” but with replies which were pointing at techniques, tools and patterns, not the reasoning behind these tools, techniques and patterns.

science-in-actionAs a fan of the scientific method, I understand the difference between a hypothesis and a theory/law. Experience and anecdotal evidence do not a theory make, as anyone who’s participated in a memory experiment will learn that memory itself is easily manipulated. At the same time though, if a hypothesis works for you every time you’ve tried it, you start to have confidence that the hypothesis holds weight.

So while the lack of research was a slight itch sitting there in the back of my mind, I’ve never been overly concerned because I’ve always felt that the efficacy of TDD would hold weight when put to the test (get it?). It is simply a young hypothesis and it was only a matter of time before experimentation would add evidence to bolster the many claims I’ve made on my blog.

I’ve been having a lot of interesting discussions around TDD internally here lately and wanted to brush up on the key points when I happened upon this paper published in the Proceedings of the IEEE Transactions on Software Engineering entitled On the Effectiveness of Test-first Approach to Programming.

The researchers put together an experiment in which an experiment group and a control group implemented a set of features in an incremental fashion. The experiment group wrote tests first, the control group applied a more conventional approach of writing the tests after the fact. As a result, they found…

We found that test-first students on average wrote more tests and, in turn, students who wrote more tests tended to be more productive. We also observed that the minimum quality increased linearly with the number of programmer tests, independent of the development strategy employed.

The interesting result here is that quality is more a factor of the number of tests you write, and not whether you write them first. TDD just happens to be a technique in which the natural inclination (path of least resistance) is to write more tests than less in the same time span. The lesson here is even if you don’t buy TDD, you should still be writing automated unit tests for your code.

Obviously such a controlled experiment on undergraduate students leaves one wondering if the conclusions drawn can really be applied to the workplace. The researches do address this question of validity…

The external validity of the results could be limited since the subjects were students. Runeson [21] compared freshmen, graduate, and professional developers and concluded that similar improvement trends persisted among the three groups. Replicated experiments by Porter \ and Votta [22] and Höst et al. [23] suggest that students may provide an adequate model of the professional population.

Other evidence they refer to even suggests that in the case of advance techniques, the benefit that professional developers gain outweighs that of students, which could bolster the evidence they present.

My favorite part of the paper is the section in which they offer their explanations for why they believe that Test-First programming might offer productivity benefits. I won’t dock them for using the word synergistic.

We believe that the observed productivity advantage of Test-First subjects is due to a number of synergistic effects:

  • Better task understanding. Writing a test before implementing the underlying functionality requires \ the programmer to express the functionality unambiguously.
  • Better task focus. Test-First advances one test case at a time. A single test case has a limited scope. Thus, the programmer is engaged in a decomposition process in which larger pieces of functionality are broken down to smaller, more manageable chunks. While developing the functionality for a single test, the cognitive load of the programmer is lower.
  • Faster learning. Less productive and coarser decomposition strategies are quickly abandoned in favor of more productive, finer ones.
  • Lower rework effort. Since the scope of a single test is limited, when the test fails, rework is easier. When rework immediately follows a short burst of testing and implementation activity, the problem context is still fresh in the programmer’s mind. With a high number of focused tests, when a test fails, the root cause is more easily pinpointed. In addition, more frequent regression testing shortens the feedback cycle. When new functionality interferes with old functionality, this situation is revealed faster. Small problems are detected before they become serious and costly.

Test-First also tends to increase the variation in productivity. This effect is attributed to the relative difficulty of the technique, which is supported by the subjects’ responses to the post-questionnaire and by the observation that higher skill subjects were able to achieve more significant productivity benefits.

So while I don’t expect that those who are resistant or disparaging of TDD will suddenly change their minds on TDD, I am encouraged by this result as it jives with my own experience. The authors do cite several other studies (future reading material, woohoo!) that for the most part support the benefits of TDD.

So while I’m personally convinced of the benefits of TDD and feel the evidence thus far supports that, I do agree that the evidence is not yet overwhelming. More research is required.

I prefer to take a provisional approach to theories, ready to change my mind if the evidence supports it. Though in this case, I find TDD a rather pleasant fun enjoyable method for writing code. There would have to be a massive amount solid evidence that TDD is a colossal waste of time for me to drop it.

Technorati Tags: TDD,Unit Tests,Research

comments edit

After joining Microsoft and drinking from the firehose a bit, I’m happy to report that I am still alive and well and now residing in the Seattle area along with my family. In meeting with various groups, I’ve been very excited by how much various teams here are embracing Test Driven Development (and its close cousin, TAD aka Test After Development). We’ve had great discussions in which we really looked at a design from a TDD perspective and discussed ways to make it more testable. Teams are also starting to really apply TDD in their development process as a team effort, and not just sporadic individuals.

BugsTDD doesn’t work well in a vacuum. I mean, it can work to adopt TDD as an individual developer, but the effectiveness of TDD is lessened if you don’t consider the organizational changes that should occur in tandem when adopting TDD.

One obvious example is the fact that TDD works much better when everyone on your team applies it. If only one developer applies TDD, the developer loses the regression tests benefit of having a unit test suite when making changes that might affect code written by a coworker who doesn’t have code coverage via unit tests.

Another example that was less obvious to me until now was how the role of a dedicated QA (Quality Assurance) team changes subtly when part of a team that does TDD. This wasn’t obvious to me because I’ve rarely been on a team with such talented, technical, and dedicated QA team members.

QA teams at Microsoft invest heavily in test automation from the UI level down to the code level. Typically, the QA team goes through an exploratory testing phase in which they try to break the app and suss out bugs. This is pretty common across the board.

The exploratory testing provides data for the QA team to use in determining what automation tests are necessary and provide the most bang for the buck. Engineering is all about balancing constraints so we can’t write every possible automated test. We want to prioritize them. So if exploratory testing reveals a bug, that will be a high priority area for test automation to help prevent regressions.

However, this appears to have some overlap with TDD. Normally, when someone reports a bug to me, the test driven developer, I will write a unit test (or tests) that should pass but fails because of that bug. I then fix the bug and ensure my test (or tests) now pass because the bug is fixed. This prevents regressions.

In order to reduce duplication of efforts, we’re looking at ways of reducing this overlap and adjusting the QA role slightly in light of TDD to maximize the effectiveness of QA working in tandem with TDD.

In talking with our QA team, here’s what we came up with that seems to be a good guideline for QA in a TDD environment:

  • QA is responsible for exploratory testing along with non-unit tests (system testing, UI testing, integration testing, etc…). TDD often focuses on the task at hand so it may be easy for a developer to miss obscure test cases.
  • Upon finding bugs in exploratory testing, assuming the test case doesn’t require external systems (aka it isn’t a system or integration test), the developer would be responsible for test automation via writing unit tests that expose the bug. Once the test is in place, the developer fixes the bug.
  • In the case where the test requires integrating with external resources and is thus outside the domain of a unit test, the QA team is responsible for test automation.
  • QA takes the unit tests and run them on all platforms.
  • QA ensures API integrity by testing for API changes.
  • QA might also review unit tests which could provide ideas for where to focus exploratory testing.
  • Much of this is flexible and can be negotiated between Dev and QA as give and take based on project needs.

Again, it is a mistake to assume that TDD should be done in a vacuum or that it negates the need for QA. TDD is only one small part of the testing story and if you don’t have testers, shame on you ;) . One anecdote a QA tester shared with me was a case where the developer had nice test coverage of exception cases. In these cases, the code threw a nice informative exception. Unfortunately a component higher up the stack swallowed the exception, resulting in a very unintuitive error message for the end user. This might rightly be considered an integration test, but the point is that relying soley on the unit tests caused an error to go unnoticed.

TDD creates a very integrated and cooperative relationship between developers and QA staff. It puts the two on the same team, rather than simply focusing on the adversarial relationship.

Technorati Tags: TDD,Microsoft

comments edit

File this in my learn something new every day bucket. I received an email from Steve Maine after he read a blog post in which I discuss the anonymous object as dictionary trick that Eilon came up with.

He mentioned that there is an object initializer syntax for collections and dictionaries.

var foo = new Dictionary<string, string>()
{
  { "key1", "value1" },
  { "key2", "value2" }
};

That’s pretty nice!

Here is a post by Mads Torgersen about collections and collection initializers.

Naturally someone will mention that the Ruby syntax is even cleaner (I know, because I was about to say that).

However, suppose C# introduced such syntax:

var foo = {"key1" => "value1", 2 => 3};

What should be the default type for the key and values? Should this always produce Dictionary<object, object>? Or should it attempt type inference for the best match? Or should there be a funky new syntax for specifying types?

var foo = <string, object> {"key1" => "value1", "2" => 3};

My vote would be for type inference. If the inferred type is not the one you want, then you have to resort to the full declaration.

Then again, the initializer syntax that does exist is much better than the old way of doing it, so I’m happy with it for now. In working with a statically typed language, I don’t expect that all idioms for dynamic languages will translate over in as terse a form.

Check out this use of lambda expressions by Alex Henderson to create a hash that is very similar in style to what ruby hashes look like. Thanks Sergio for pointing that out in the comments.

Technorati Tags: C#,Object Initializers,Collection Initializers

personal comments edit

132554078_55943228ef[2]

No, the title of this post isn’t suggesting that L.A. is about to be demolished to make way for a hyperspatial express route. It’s pretty much already one big freeway already, isn’t it? ;)

Seriously though, I am going to miss this wonderful city after spending the last fourteen years here. A lot of people look at L.A. as a place they could never live. I thought that myself coming from Alaska, but boy was I wrong.152767725_7ca21f59c9[1]

I think the weather alone is enough to move to L.A. Perhaps the only place with better weather might be San Diego. But along with great weather during the day, L.A. has a great nightlife.

Being an outdoorsy type, I’ve always been fortunate that a good camping trip is just a short drive away.

16831248_a228be178e[1]

Not to mention great skiing and snowboarding.

16831344_77a321d104[1]

I even took part in my first protest march in Los Angeles, something that pretty much never happened in Alaska.

138586490_61d126c584[1]

One of the things I’ll miss the most is the great soccer game I’ve been a part of for 10 years there. This particular regular pick-up game has been going on for around 15 to 20 years in one form or another.

347545471_ab87b90733[1]

Today the movers came and moved all of our stuff out and we left the keys behind in our now empty house. Tomorrow morning, we will be on a plane for Seattle.

The one thing that has made this move a lot easier for us has been that Microsoft took care of just about everything. Let me tell you, if you’re thinking about joining Microsoft, we might not have free food like some other companies, but we do have a great healthcare plan and the relocation benefits (at least for me) are astounding. They have made this transition a lot less a nightmare than it could’ve been. Though it has still been tough with all three of us catching colds around the same time.

Stay classy L.A., I will miss you. Seattle, watch your back. We’ll be there tomorrow.

Technorati Tags: Moving,Seattle,L.A.

code comments edit

Six months ago and six days after the birth of my son, Subkismet was also born which I introduced as the cure for comment spam. The point of the project was to be a useful class library containing multiple spam fighting classes that could be easily integrated into a blog platform or any website that allows users to comment.

One of my goals with the project was to make it safe to enable trackbacks/pingbacks again.

I’ve been very happy that others have joined in the Subkismet efforts. Mads Kristensen, well known for BlogEngine.NET, contributed some code.

Keyvan Nayyeri has also been hard at work putting the finishing touches on an implementation of a client for the Google Safe Browsing API service.

Keyvan just announced the release of Subkismet 1.0. Here is a list of what is included in this release. I’ve bolded the items that are new since the first release of Subkismet.

For the current version (1.0) we’ve included following tools in Subkismet core library:

  • Akismet service client: Akismet is an online web service that helps to block spam. This service client implementation for .NET is done by Phil and lets you send your comments to the service to check them against a huge database of spammers.
  • Invisible CAPTCHA control: A clever CAPTHCA control that hides from real human but appears to spammers. This control is done by Phil and you can read more about it here.
  • CAPTCHA control: An excellent implementation of traditional image CAPTCHA control for ASP.NET applications.
  • Honeypot CAPTCHA: Another clever CAPTCHA control that hides form fields from spam bots to stop them. This control is done by Phil and you can read more about it here.
  • Trackback HTTP Module: An ASP.NET Http Module that blocks trackback spam. This module is done by Mads Kristensen and he has explained his method in a blog post and this Word document.
  • Google Safe Browsing API service client: This is done by me and you saw its Beta 2 version last week. Google Safe Browsing helps you check URLs to see if they’re phishing or malware links.

Since it is always fun for us developers to write code with the latest technologies, we’re planning to have the next release target .NET 3.5.

Part of the reason for that is that over the holidays, I wrote a little something something just for fun as a way of getting up to speed with C# 3.0. It was a lot of fun and I think my secret project will make a nice addition to Subkismet. I’ll write about it when it is ready for action.

Unfortunately, this move has made it difficult to fully complete the implementation and test it out on real data.

Subkismet is hosted on CodePlex. Many thanks go out to Mads and others for their contributions and to Keyvan for all the implementation work as well as release work he did. And for the record, Keyvan mentioned that I ordered him to prepare the release. While I do have dictatorial tendencies, I think this is too harsh a description. I’d like to say I requested that he prepare the release. ;)

Technorati Tags: Subkismet,Spam

personal comments edit

You’ve been forewarned, this is yet another end-of-year slightly self-inflating retrospective blog post (complete with the cheesy meta-blogging introduction).

But this year for me was quite significant and full of big changes. On a personal level, this was the year the agent of my little world domination plan was hatched.

Newborn Cody With
Glasses

He was tiny then, but six months later, he’s gotten quite big. He’s remained in the 95^th^ percentile in height for a baby his age.

Cody in a shark
costume

As much fun as it has been with Cody, he’s never taken his devious eye off the prize in keeping with the master plan.

cody-plotting

He is not going to be a kid one wants to mess with. I kid you not, he laughs out loud with glee when I whack him with a pillow or pound on his belly with my fists. That’s his idea of fun. As I said originally, he’s a li’l thug.

In terms of my professional life, it’s been quite a whirlwind year. All in the same year, I:

Throughout this whole ordeal, my wonderful wife has been most gracious and supportive. Consider the fact that when she was pregnant with Cody, I was working as a co-owner at a startup, often not taking a paycheck so we could pay our employees. That has to be stressful.

Then after one job change, I tell her about this great opportunity and ask her if it is ok to move to Redmond. Her response was immediate. Let’s go!What a woman!

Unfortunately once we made that decision, in a wonderful display of synchronicity, the Los Angeles housing market stated a downward spiral. We had zero offers for the first two months of trying to sell our house. It was so bad, in fact, that we decided we would try and rent the house. On the day we had an open house for renters, an offer came just in the nick of time!

So while we close out another year, we’re also closing out the Los Angeles era for my family. We really love this town. For one thing, we have some great friends who live here. We’re trying to recruit them up to Seattle, but they keep mumbling something about the rain and cold as if it were a bad thing.

Something else we’ll miss is the great diverse food here. Many regard the Korean food in L.A. as the best in the world. And the Japanese market and restaurants on Sawtelle have been a staple for us.

I’ll particularly miss my pickup soccer crew as well as the league of ex-pros. Lots to love about L.A., but at the same time, we’re quite excited about our new adventures and opportunities up in the Seattle area. For example, the opportunity to breathe clean air!

To all who have read this far, I hope 2007 was a good year for you and that 2008 proves to be even better. Happy New Year!

code comments edit

Faceoff Recently, Maxfield Pool from CodeSqueeze sent me an email about a new monthly feature he calls Developer Faceoff in which he pits two developers side-by-side for a showdown.

It’s an obvious attempt to gain readers via an appeal to vanity of the featured bloggers who have no choice to link to it. Brilliant!  :)

Seriously, I think it’s a fun and creative idea, but I have no credibility in saying so because I’m obviously biased being featured alongside my longtime nemesis and friend, Scott Hanselman. So check it out for yourself.

Some of my answers were truncated due to the format so I thought it’d be fun to elaborate on a couple of questions.

5. Are software developers - engineers or artists?

Don’t take this as a copout, but a little of both. I see it more as craftsmanship. Engineering relies on a lot of science. Much of it is demonstrably empirical and constrained by the laws of physics. Software is less constrained by physics as it is by the limits of the mind.

Software in many respects is as much a social activity as it is an engineering discipline. Working well as a team is essential, as is understanding your users and how they get their work done so your software helps, rather than hinders.

Much of software is based on faith and anecdotal evidence. For example, do we have scientific evidence that TDD improves the design of code? Do we have empirical evidence that it doesn’t? Research is scant, in part because it’s extremely challenging to set up valid experiments. Much of software research focuses on retrospective research, the sort that sociologists do.

So again, back to the question. Crafting a sorting algorithm is engineering. Building a line of business app that delights all the users is an art.

8. What is the biggest mistake you made along the way?

My first year as software developer, I deployed a reset password feature to a large music community site. A week or so after we deployed, a child of a VP of the client (or maybe it was an investor, I can’t remember) complained she couldn’t get into her account and hadn’t received her new password.

I was “sure” I had tested it, but it turned out I hadn’t done a very good job of it. There was a bug in my code and a bunch of users were waiting around for a regenerated password that would never arrive.

Needless to say, my boss wasn’t very happy it and for a good while I tread lightly worried I’d lose my job if I made another mistake. In retrospect, it was a good thing to get such a big production mistake out of the way early because I was extremely careful afterwards, always triple checking my work.

Tags: Software Development

code, asp.net mvc comments edit

A common pattern when submitting a form in ASP.NET MVC is to post the form data to an action which performs some operation and then redirects to another action afterwards. The only problem is, the form data is not repopulated automatically after a redirect. Let’s look at remedying that, shall we?

When submitting form data, the ASP.NET MVC Toolkit includes a helper extension method that makes it easy to go the other direction, populating an object from the request. Check out the following simplified controller action adapted from an example ScottGu’s post on handling form data.

[ControllerAction]
public void Create()
{
  Article article = new Article();
  article.UpdateFrom(Request.Form);
  
  repository.Persist(article);
 
  RedirectToAction("List");
}

UpdateFrom() is an extension method on the type object that will attempt to populate each property of the object with a corresponding value from the posted form.

The example above doesn’t address what should happen if the data passed to product is incomplete or incorrect.

In that situation, I may want to redirect back to the action that renders the form for creating a new product. But now I’m responsible for populating the form fields because the posted values are lost after a redirect.

One option is to use the TempData dictionary, which is intended for these scenarios in which you need to persist data for the next request, but not afterwards.

[ControllerAction]
public void Create()
{
  Article article = new Article();
  article.UpdateFrom(Request.Form);
  
  //Pretend this was extensive validation
  if(article.IsValid)
  {
    repository.Persist(article);
    RedirectToAction("List");
  }
  else
  {
    TempData["message"] = "Please fill in all fields!";
    TempData["title"] = article.Title;
    TempData["body"] = article.Body;
    //... and so on and so on...

    //Takes us to a form for creating a product.
     RedirectToAction("New");
  }
}

That’ll work nicely for object with a small number of properties, but when you have a lot of properties to store in TempData, it gets a bit cumbersome. We have an extension method for populating an object from a form, why not do something similar for populating TempData from an object?

I put together a series of helper extension methods that help simplify the above case. Using these extension methods, you can reduce the above code to…

[ControllerAction]
public void Create()
{
  Article article = new Article();
  article.UpdateFrom(Request.Form);
  
  //Pretend this was extensive validation
  if(article.IsValid)
  {
    repository.Persist(article);
    RedirectToAction("List");
  }
  else
  {
    TempData["Message"] = "Please supply all fields.";
    TempData.PopulateFrom(article);

    //Takes us to a form for creating a product.
     RedirectToAction("New");
  }
}

PopulateFrom is an extension method on TempDataDictionary that populates the dictionary collection using whatever you pass into it. I wrote some overloads so you can populate it directly from an object, the form collection, or from a dictionary. I will show the code for the extension methods at the end.

This gets us part of the way, but we still need to populate the form field values in the view. Here is the relevant code snippet from the New view.

<% using(Html.Form("Article", "Create")) { %>
    
<span class="error">
    <%= ViewContext.TempData.SafeGet("Message") %>
</span>

<label for="title">Title: </label> 
<%= Html.TextBox("title"
  , Html.Encode(ViewContext.TempData.SafeGet("title"))) %>

<label for="body">Body: </label>
<%= Html.TextArea("body"
  , Html.Encode(ViewContext.TempData.SafeGet("body"))) %>


<%= Html.SubmitButton() %>
<% } %>

When retrieving a value from the TempData dictionary, if the key you specify doesn’t exist, it throws an exception. So I added a SafeGet extension method to make it cleaner to extract values from TempData.

Note: We plan on making TempData a direct property of ViewPage in the future, so you don’t have to go through ViewContext.

Here is the code for my temp data extensions…

public static class TempDataExtensions
{
  public static void PopulateFrom(this TempDataDictionary tempData, object o)
  {
    foreach (PropertyValue property in o.GetProperties())
    {
      tempData[property.Name] = property.Value;
    }
  }

  public static void PopulateFrom(this TempDataDictionary tempData
    , NameValueCollection nameValueCollection)
  {
    foreach (string key in nameValueCollection.Keys)
      tempData[key] = nameValueCollection[key];
  }

  public static void PopulateFrom(this TempDataDictionary tempData
    , IDictionary<string, object> dictionary)
  {
    foreach (string key in dictionary.Keys)
      tempData[key] = dictionary[key];
  }

  public static string SafeGet(this TempDataDictionary tempData, string key)
  { 
    object value;
    if (!tempData.TryGetValue(key, out value))
      return string.Empty;
    return value.ToString();
  }
}

These methods rely on some object extension methods I wrote based on the work that Eilon Lipton did with using C# 3.0 Anonymous Types as Dictionaries.

public static class ObjectHelpers
{
  public static IDictionary<string, object> ToDictionary(this object o)
  {
    Dictionary<string, object> properties = new Dictionary<string, object>();

    foreach (PropertyValue property in o.GetProperties())
    {
      properties.Add(property.Name, property.Value);
    }
    return properties;
  }


  internal static IEnumerable<PropertyValue> GetProperties(this object o)
  {
    if (o != null)
    {
      PropertyDescriptorCollection props = TypeDescriptor.GetProperties(o);
      foreach (PropertyDescriptor prop in props)
      {
        object val = prop.GetValue(o);
        if (val != null)
        {
          yield return new PropertyValue { Name = prop.Name, Value = val };
        }
      }
    }
  }
}

internal sealed class PropertyValue
{
  public string Name { get; set; }
  public object Value { get; set; }
}

The ToDictionary method makes it easy to convert an anonymous typed object to a dictionary.

Using these extension methods should help reduce some of the chore of handling form submissions with the CTP version ASP.NET MVC. In future versions of the framework, I hope we can make some of these common scenarios more streamlined.

And before I forget, I have a simple solution for download that includes full source code for the extension methods I wrote as well as a trivially simple application that demonstrates using this code.

Tags: ASP.NET MVC , TempData , Form Handling

asp.net, code, asp.net mvc comments edit

The ASP.NET Routing engine used by ASP.NET MVC plays a very important role. Routes map incoming requests for URLs to a Controller and Action. They also are used to construct an URL to a Controller/Action. In this way, they provide a two-way mapping between URLs and controller actions.

When building routes, it may be useful to write unit tests for the routes to ensure that you’ve set up the proper mappings you intend.

ScottGu touched a bit on unit testing routes in part 2 of his series on MVC in which he covers URL Routing. In this post, we’ll go into a little more depth with testing routes.

To keep it interesting, let me show you what the final unit test looks like for testing a route. That way, if you don’t care about the details, you can skip all this discussion and just download the code.

[TestMethod]
public void RouteHasDefaultActionWhenUrlWithoutAction()
{
  RouteCollection routes = new RouteCollection();
  GlobalApplication.RegisterRoutes(routes);

  TestHelper.AssertRoute(routes, "~/product"
    , new { controller = "product", action = "Index" });
}

The first part of the test simply populates a collection with routes from your Global application class defined in Global.asax.cs. The second part is a call to another helper method that attempts to map a route to the specified virtual URL and compares the route data to a dictionary of name/value pairs. The dictionary is passed in as an anonymous type using a technique that my coworker Eilon Lipton wrote about on his blog.

Let’s take a quick look at the RegisterRoutes method so you can see which routes I am testing.

public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute("blog-route", "blog/{year}/{month}/{day}",
        new { controller = "Blog", action = "Index", id = "" },
        new { year = @"\d{4}", month = @"\d{2}", day = @"\d{2}" }
    );

    routes.MapRoute(
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" }
    );
}

Looks like your standard set of routes, no? I threw one in there that looks like one you might use with a blog engine.

Next, I’ll show you how I would write a test the long way using MoQ.

[TestMethod]
public void CanMapNormalControllerActionRoute() {
    RouteCollection routes = new RouteCollection();
    GlobalApplication.RegisterRoutes(routes);

    var httpContextMock = new Mock<HttpContextBase>();
    httpContextMock.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath)
        .Returns("~/product/list");

    RouteData routeData = routes.GetRouteData(httpContextMock.Object);
    Assert.IsNotNull(routeData, "Should have found the route");
    Assert.AreEqual("product", routeData.Values["Controller"]
        , "Expected a different controller");
    Assert.AreEqual("list", routeData.Values["action"]
        , "Expected a different action");
}

Ok, that isn’t all that bad. It may seem like a lot of code, but it’s pretty straightforward, assuming you understand the general pattern for using a mock framework.

However, we can shorten a lot of this code by using an extension method I wrote in a previous post. I actually wrote an overload that makes it easier to mock a request for a specific URL.

That gets us further, but we can do so much more. Here is the code I wrote for my AssertRoute method.

public static void AssertRoute(RouteCollection routes, string url, 
    object expectations) 
{
    var httpContextMock = new Mock<HttpContextBase>();
    httpContextMock.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath)
        .Returns(url);

    RouteData routeData = routes.GetRouteData(httpContextMock.Object);
    Assert.IsNotNull(routeData, "Should have found the route");

    foreach (PropertyValue property in GetProperties(expectations)) {
        Assert.IsTrue(string.Equals(property.Value.ToString(), 
            routeData.Values[property.Name].ToString(), 
            StringComparison.OrdinalIgnoreCase)
            , string.Format("Expected '{0}', not '{1}' for '{2}'.", 
            property.Value, routeData.Values[property.Name], property.Name));
    }
}

This code makes use of the GetProperties method I lifted from Eilon’s blog post, Using C# 3.0 Anonymous types as Dictionaries.

The expectations passed to this method are the name/value pairs you expect to see in the RouteData.Values dictionary.

I hope you find this useful. The code (along with other unit test examples) are in solution ready for download.

UPDATE: I updated the blog post and solution (7/27 1:38 PM PST) to account for all the changes to routing made since I wrote this post originally.

UPDATE AGAIN: Updated the post to use MoQ 3.0 and cleaned up the code a slight bit.

UPDATE: 03/11/2012 - Fixed the broken download link. Rewrote the tests to use xUnit.NET.

Tags: ASP.NET MVC , TDD , Routing

code, asp.net mvc comments edit

Yesterday, Wally McClure interviewed me for the ASP.NET Podcast Show. We chatted for around half an hour on my background, Microsoft, and ASP.NET MVC.

It was a fun chat, but I have to warn you, I was very sleep deprived (a constant condition lately), so at points I tend to ramble a bit, second-guess myself (I was right the first time, model-view-thing-editor!), and even contradict myself.

I’m not normally that harebrained. I promise. Ok, maybe just a little. With all those caveats in place, give it a listen.

This is why writing a blog is so much easier than being interviewed. All the times I correct myself are not visible in a blog entry.

Tags: ASP.NET MVC , Podcast

asp.net, code, asp.net mvc comments edit

I have a set of little demos apps I’ve been working on that I want to release to the public. I need to clean them up a bit (you’d be surprised how much I swear in comments) and make sure they work with the CTP. Hopefully I will publish them on my blog over the next few weeks.

In the meanwhile, there’s some great stuff being posted by the community I want to call out. All these great posts are making my life easier.

  • Routing Revisited
    • Sean Lynch talks about some interesting route scenarios. Currently the Route object doesn’t support all the scenarios he is attempting. This is good feedback and we’re already looking into it. He mentioned wanting Subtext-style URLs. You better believe I’m going to bring this up. ;) He also brings up a good point clarifying which Page templates in the Add New Item dialog to select when working with master pages. I’m sorry that dialog is crazy busy.
  • Using script.aculo.us with ASP.NET MVC
    • Chad Myers does some fancy schmancy AJAX stuff with ASP.NET MVC and the ever so flashy Script.aculo.us framework. What! No JQuery?! ;) Hasn’t anyone told Chad that Ajax is just a fad? All the interactivity you’ll ever need is in the <blink /> tag.
  • ASP.NET MVC Framework - Create your own IRouteHandler
    • Fredik Normén didn’t like the fact that IControllerFactory.GetController takes in the type of the controller (something we’re definitely looking at) because it made it more difficult to use Spring.NET. So he went an implemented his own IControllerFactory and his own IRouteHandler. This is a great demonstration of how to swap out a couple of nodes in the “snake diagram” with your own implementation. While it’s a validation of our extensibility story that he was able to accomplish this scenario, the fact that he needed to do all this also highlights areas for improvements.
  • MvcContrib Open Source Project Call for Participation
    • Jeffrey Palermo writes about a brand spanking new OSS project to build useful tools and libraries for MVC. Gotta give them credit for starting an OSS project on a CTP technology the day before it launched.

It is really great to see people building demos and applications on top of ASP.NET MVC. Learing about the rough areas that you run into doing real-world tasks is immensely valuable feedback.

Forums!

We have an official ASP.NET MVC forum now for discussing…surprise surprise…ASP.NET MVC. If you have questions about ASP.NET MVC, I encourage you ask them there for the benefit of others. Feel free to comment on my blog if you don’t get a satisfactory answer in a reasonable amount of time.

Even better, jump in and help answer questions!

Tags: ASP.NET MVC

altdotnet design-patterns comments edit

Love them or hate them, the ALT.NET mailing list is a source of interesting debate, commentary and insight. I can’t help myself but to participate. Debate is good. Stifling debate is bad. Period. End of debate. (see!? That was bad!)

The community itself is a young community, and as such, they are going through a period of identity forming. What are their shared values? What does it mean to be an ALT.NET-er? It’s not exactly clear yet, but it is starting to form.

One thing I would caution this community is to be careful in how they define their shared principles. For example, in one thread one individual mentioned debating me and then in the same message proposed the idea of Composition over Inheritance as a shared principle.

In response, someone posted this:

You can throw the book at those people–literally. Favoring composition over inheritance is straight out of the Gang of Four book. Don’t like design patterns? Fine. No problem. I have a couple of Don Box COM+ books that say the exact same thing.

Here was my response, which I also wanted to put in a blog post since it represents pretty well what I think.

I think ALT.NET should focus more on the principles of thinking for yourselfand a desire to improve.

Favoring composition over inheritance is straight out of the Gang of Four book.

So is the Singleton pattern. So is the Template Method pattern.

Sorry, Appeal to Authority doesn’t work for me. Look, I’m not against composition over inheritance in many cases. Perhaps most cases. What I am against is saying that it applies in all cases and that if you don’t do it, you’re not ALT.NET.

I’m against the blind application of these pithy catch phrases. Blindly applying a “best practice” is just as irresponsible as never applying a “best practice”. There is no perfect design. There is no one true way. There is no one size fits all.

Why favor composition over inheritance? What trade-offs are you making when you do so? Developers should think through these things when they make these choices. And when a developer does think through the issue, but makes a choice that differs from what you think, you should applaud that. At least the developer thought through the decision.

I don’t care that a developer doesn’t favor composition over inheritance in a specific case. I only care that the developer thought it through, had a reason for the decision, wants to improve.

The goal is not to bend developers to the will of some specific patterns, but to get them to think about their work and what they are doing. For example, one advantage with inheritance is that it is easier to use than composition. However, that ease of use comes at the cost that it is harder to reuse because the subclass is tied to the parent class.

One advantage of composition is that it is more flexible because behavior can be swapped at runtime. One disadvantage of composition is that the behavior of the system may be harder to understand just by looking at the source. These are all factors one should think about when applying composition over inheritance.

So while I agree that you should favor composition over inheritance, inheritance is still necessary. After all, “the set of components is never quite rich enough in practice.”

That quote is from Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in Design Patterns. But don’t believe it just because they said it. After all, I would hate to be guilty of an Appeal to Authority. ;)

asp.net, code, asp.net mvc comments edit

Eilon Lipton, the lead developer on the ASP.NET MVC project shares some of his thoughts on the design philosophy guiding the shaping of the framework.

There have been many post describing what the framework is and how to perform tasks, which are really useful. I think a more reflective post like this is a breath of fresh air and a nice insight into how the team is making decisions.

Rodin-Denker-KyotoEilon also covers some of the lessons we’ve already learned in building the CTP, and some of the changes we have planned for the next CTP.

At the end he lists some interesting facts. Here are my two favorites:

  • For the released CTP, the unit test code coverage numbers were about 93%, far more than any other major feature area. This does not include the code coverage by our QA guys, which I’m sure would bring the number up to at least 99%.
  • We had about 250 unit tests for MVC, and the ratio of unit test code to product code is about 1.9 to 1 (in terms of the size of the code files, not lines of code; I’m too lazy to do the latter!).

It has been a real joy to work with this team. For example, I’ve never worked with such experienced and smart QA people before. I always read that the QA team should be involved in design meetings, but Microsoft is the first place I worked where we actually did that in a real manner.

Obviously the developers are top notch as you can see from Eilon’s blog in general. Hopefully the PM of this team can keep up. ;)

Tags: ASP.NET MVC

asp.net, code, asp.net mvc comments edit

UPDATE: ASP.NET MVC now works with Visual Web Developer Express SP1

Some developers who downloaded the ASP.NET Extensions CTP specifically for ASP.NET MVC and then opened up Visual Web Developer like it was Christmas morning instead got a lump of coal.

We currently only include Web Application Projects for ASP.NET MVC, which Visual Web Developer does not support. I was planning to write up a post on this, but Scott Koon beat me to it.

And thank goodness! I’m busy enough as it is already. It’s all part of my master plan to have members of the community doing my job for me so we can finally take that trip to Tahiti and sip margaritas while I tell my bosses I’m “telecommuting”. ;) Seriously though, I appreciate it.

If you’re using Visual Web Developer Express, read Scott’s blog post on how to get MVC working for you.

I personally would like to get ASP.NET MVC in more hands than less hands, so I hope we have a better story for this with a future release.

Tags: ASP.NET MVC , Visual Web Developer Express , VWD

asp.net, code, asp.net mvc, tdd comments edit

UPDATE: Completely ignore the contents of this post. All of this is out-dated. Test specific subclasses are no longer necessary with ASP.NET MVC since our April CodePlex refresh

Just a brief note on writing unit tests for controller actions. When your action has a call to RedirectToAction or RenderView (yeah, pretty much every action) be aware that these methods have dependencies on various context objects.

If you attempt to mock these objects, you sometimes also have to mock their dependencies and their dependencies’ dependencies and so on, depending on what you are trying to test. This is why I wrote my post on Test Specific Subclasses. It provides an easier way to test some of these cases.

Some of these challenges are the nature of mocking and some of them are due to protected methods that we realize we should probably make public.

In this post, I want to demonstrate a couple of unit test techniques for testing controller actions for the CTP release of the ASP.NET MVC Framework. Remember, this is a CTP so all of this may change in the future. I will be compiling testing patterns into a longer document on unit testing patterns for ASP.NET MVC

Controller with RedirectToAction

Here is the really simple controller we’ll test

public class HomeController : Controller
{
  [ControllerAction]
  public void Index()
  {
    RenderView("Index");
  }

  [ControllerAction]
  public void About()
  {
    RedirectToAction("Index");
  }
}

We will test the About action.

Test Specific Subclass Approach

For the most part, when a test calls RedirectToAction, you just want to no-op that method call. But if you want to verify that the action that is being redirected to is the correct one, here’s one way to test it using a test-specific subclass.

[Test]
public void VerifyAboutRedirectsToCorrectActionUsingTestSpecificSubclass()
{
  HomeControllerTester controller = new HomeControllerTester();
  controller.About();
  Assert.AreEqual("Index", controller.RedirectedAction
    , "Should have redirected to 'Index'.");
}

internal class HomeControllerTester : HomeController
{
  public string RedirectedAction { get; private set; }

  protected override void RedirectToAction(object values)
  {
    this.RedirectedAction = (string)values.GetType()
      .GetProperty("Action").GetValue(values, null);
  }
}

In this test I inherited from the controller I am testing, following the Test Specific Subclass pattern (Note: This pattern leaves a bad taste in some TDDers mouths. I am aware of that. I still like it. But I already know some of you don’t).

One thing that is really ugly is I had to resort to reflection to get the Action we are redirecting to. This testing scenario will be fixed in the next release. Just showing you how it is done now.

Mock Framework Approach

In this test, I will use RhinoMocks to test the same thing as above.

[Test]
public void VerifyAboutRedirectsToCorrectActionUsingMockViewFactory()
{
  RouteTable.Routes.Add(new Route
  {
    Url = "[controller]/[action]",
    RouteHandler = typeof(MvcRouteHandler)
  });

  HomeController controller = new HomeController();
    
  MockRepository mocks = new MockRepository();
  IHttpContext httpContextMock = mocks.DynamicMock<IHttpContext>();
  IHttpRequest requestMock = mocks.DynamicMock<IHttpRequest>();
  IHttpResponse responseMock = mocks.DynamicMock<IHttpResponse>();
  SetupResult.For(httpContextMock.Request).Return(requestMock);
  SetupResult.For(httpContextMock.Response).Return(responseMock);
  SetupResult.For(requestMock.ApplicationPath).Return("/");
  responseMock.Redirect("/Home/Index");

  RouteData routeData = new RouteData();
  routeData.Values.Add("Action", "About");
  routeData.Values.Add("Controller", "Home");
  ControllerContext contextMock = new 
    ControllerContext(httpContextMock, routeData, controller);
  mocks.ReplayAll();

  controller.ControllerContext = contextMock;
  controller.About();

  mocks.VerifyAll();
}

The mock test actually tests the final URL that we would be redirecting to. You can verify this test is actually testing what I say it will by changing the line with “/Home/Index” to something like “/Home/Index2” and see that the test does fail.

Controller With RenderView

Using the same controller class above, let’s write a test to make sure the correct view is rendered.

Using Test Specific Subclass

[Test]
public void VerifyIndexSelectsCorrectViewUsingTestSpecificSubclass()
{
  HomeControllerTester controller = new HomeControllerTester();
  controller.Index();
  Assert.AreEqual("Index", controller.SelectedViewName
    , "Should have selected 'Index'.");
}

internal class HomeControllerTester : HomeController
{
  public string SelectedViewName { get; private set; }
    
  protected override void RenderView(string viewName
    , string masterName, object viewData)
  {
    this.SelectedViewName = viewName;   
  }
}

Using a Mock Framework

UPDATE: Sorry, but the following test doesn’t work in the CTP. I had compiled it against an interim build and not the CTP version. Apologies. For this scenario, you pretty much have to use the subclass approach. We will make this better in the next CTP.

[Test]
public void VerifyIndexSelectsCorrectViewUsingMockViewFactory()
{
  MockRepository mocks = new MockRepository();
  IViewFactory mockViewFactory = mocks.DynamicMock<IViewFactory>();
  IView mockView = mocks.DynamicMock<IView>();
  IHttpContext httpContextMock = mocks.DynamicMock<IHttpContext>();

  HomeController controller = new HomeController();
  RouteData routeData = new RouteData();

  ControllerContext contextMock = new ControllerContext(httpContextMock
    , routeData, controller);

  Expect.Call(mockViewFactory.CreateView(contextMock, "Index"
    , string.Empty, controller.ViewData)).Return(mockView);
  Expect.Call(delegate { mockView.RenderView(null); }).IgnoreArguments();
    
  mocks.ReplayAll();

  controller.ControllerContext = contextMock;
  controller.ViewFactory = mockViewFactory;
  controller.Index();

  mocks.VerifyAll();
}

Please note that while the Rhino Mocks examples look like a lot of code, on a real project I would build up a custom set of Extension methods to effectively create a DSL (Domain Specific Language) for testing my controllers.

I’ve already started on this a bit. Hopefully together, we can build up a really nice library to make testing controllers much more fluid.

In the meanwhile, we will also evaluate the sticking points when it comes to writing tests and do our part to reduce the friction for TDD scenarios.

 

Tags: aspnetmvc , TDD

asp.net, code, asp.net mvc comments edit

UPDATE: Much of this post is out-of-date with the latest versions of MVC. We long sinced removed the ControllerAction attribute.

Note: If you hate reading and just want the code, it is at the bottom.

Eons ago, I was a youngster living in Spain watching my Saturday morning cartoons when my dad walked in bearing freshly made taquitos and a small cup of green stuff. The taquitos looked delicious, but I was appalled at the green stuff.

Was this some kind of joke? My dad wanted me to simply just taste it but I refused because I absolutely knew it would suck just by looking at it. The green stuff, of course, was guacamole, which I love by the truckload now.

Guacamole

With all the code samples and blog posts published about the ASP.NET MVC Framework, there’s been some debate about the big picture stuff.

  • Should I be looking to migrate to this? (Depends)
  • Will this replace Web Forms? (NO!)
  • Is this feature even necessary? (I sure think so!)

Interestingly enough, the most passionate debate I’ve seen is not around these big picture questions, but is centered around very specific detailed design decisions. After all, we are software developers, and if there’s one thing software developers love to do, it’s debate the design and architecture of code.

I’m no exception to this rule and admit I rather enjoy it, sometimes to the point of absurdity and pointlessness. At the end of the day, however, the framework developer has to make a decision and move forward so he or she can go home. These choices will never make everyone happy because there is no such thing as a perfect design that satisfies everyone.

That doesn’t mean we give up trying though!

Hopefully the quality of feedback the framework designer receives pushes that designer to reevaluate assumptions and either reinforces the decision, or provides insight for an even better decision.

One design decision in particular that seems to have drawn somewhat disproportionate amount of attention is the decision to require a [ControllerAction] attribute on public methods within a controller class that are meant to be a web visible action. There’s been much discussion in various mailing lists and in some blog posts before the CTP has been released.

This post is not going to rehash these concerns nor address these concerns. If I think it would help, perhaps I will have a follow-up post in which I explain some of the reasoning behind this decision. This would give those who feel all that strongly about this a chance to make a well-reasoned point by point refutation should they wish.

I worry about focusing too much on this one issue. I don’t want it to become such a hang up that it disproportionately dominates discussion and feedback at the expense of gathering valuable feedback on other areas of the framework. There is much more to the framework than this one issue.

At the same time, I do understand this issue is about more than a single attribute. It’s about applying a design philosophy centered around convention over configurationand where it works well and where it doesn’t.

Like guacamole, I hope that critics of this particular issue don’t judge it by sight alone and give it a real honest try. See if it makes as big a difference as you think. Maybe it does. Maybe it doesn’t. At least you’ve tasted it. Feedback based on trying it out for a while is more valuable and potent than feedback based on just on seeing sample code.

Please understand that I’m not dismissing feedback based on what you have seen. It certainly is valuable and much of it has been incorporated and discussed in our design meetings. Some of it has led to changes. All I am saying is that as valuable as that feedback is, feedback based on usage is even more valuable.

The Convention Controller

However, if you still hate it, I have a little workaround for you :). I’ve written a custom controller base class that allows for a more “convention over configuration” approach to building your controllers named ConventionController.

By inheriting from this controller instead of the vanilla Controller class, you no longer need to add the [ControllerAction] attribute to every public method. You also don’t need to call RenderView if you name your view the same name as the action. Of course this means you cannot use strongly typed views and must use the ViewData property bag to pass data to the view.

So instead of writing your controller like this:

public class HomeController : Controller
{
  [ControllerAction]
  public void Index()
  {
    //Your action logic
    RenderView("Index");
  }
}

Using my class you could write it like this

public class HomeController : ConventionController
{
  public void Index()
  {
    //Your action logic
  }
}

The key point in posting this code is to demonstrate how easy it is to override the behavior we bake in with something more to your liking. When you look at the code, you will see it wasn’t rocket science to do what I did. Extending the framework is quite easy.

We may not provide the exact out of box experience that you want, but we do try and give you the tools to control your own destiny with this framework and provide you with the power of choice.

I will look into adding this to the MVC Contrib project started by some community members. In the meanwhile, if you like this approach or style of building controllers, you can either add the ConventionController.cs class to your own project or compile it into a separate assembly and drop it into your own projects.

To get to this class, download the example code.

Tags: ASP.NET MVC , Convention over Configuration , ControllerAction

asp.net, code, asp.net mvc, tdd comments edit

One of the guiding principles in the design of the new ASP.NET MVC Framework is enabling TDD (Test Driven Development) when building a web application. If you want to follow along, this post makes use of ASP.NET MVC CodePlex Preview 4 which you’ll need to install from CodePlex. I’ll try and keep this post up to date with the latest releases, but it may take me time to get around to it.

This post will provide a somewhat detailed walk-through of building a web application in a Test Driven manner while also demonstrating one way to integrate a Dependency Injection (DI) Framework into an ASP.NET MVC app. At the very end, you can download the code.

I chose StructureMap 2.0 for the DI framework simply because I’m familiar with it and it requires very little code and configuration. If you’re interested in an example using Spring.NET, check out Fredrik Normen’s post. I’ll try and post code examples in the future using Castle Windsor and ObjectBuilder.

Start Me Up! with apologies to The Rolling Stones

Once the CTP is released and you have it installed, open Visual Studio 2008 and select the File | New Projectmenu item. In the dialog, select the ASP.NET MVC Web Applicationproject template.

New
Project

At this point, you should see the following unit test project selection dialog.

Select Unit Test
Project

In a default installation, only the Visual Studio Unit Test project option is available. But MbUnit, xUnit.NET and others have installers available to get their test frameworks in this dialog.

As you might guess, I’ll start off building the canonical blog demo. I am going to start without using a database. We can always add that in later.

The first thing I want to do is add a few classes to the main project. I won’t add any implementation yet, I just want something to compile against. I’m going to add the following:

  • BlogController.cs to the Controllers directory
  • IPostRepository.cs to the Models directory
  • Post.cs to the Models directory
  • BlogControllerTests to the MvcApplicationTest project.

After I’m done, my project tree should look like this.

 Project
Tree

At this point, I want to implement just enough code so we can write a test. First, I define my repository interface.

using System;
using System.Collections.Generic;

namespace MvcApplication.Models
{
  public interface IPostRepository
  {
    void Create(Post post);

    IList<Post> ListRecentPosts(int retrievalCount);
  }
}

Not much of a blog post repository, but it’ll do for this demo. When you’re ready to write the next great blog engine, you can revisit this and add more methods.

Also, I’m going to leave the Post class empty for the time being. We can implement that later. Let’s implement the blog controller next.

using System;
using System.Web.Mvc;

namespace MvcApplication.Controllers 
{
  public class BlogController : Controller 
  {
    public ActionResult Recent() 
    {
      throw new NotImplementedException("Wait! Gotta write a test first!");
    }
  }
}

Ok, we better stop here. We’ve gone far enough without writing a unit test. After all, I’m supposed to be demonstrating TDD. Let’s write a test.

Let’s Get Test Started, In Here. with apologies to the Black Eyed Peas

Starting with the simplest test possible, I’ll make sure that the Recent action does not specify a view name because I want the default behavior to apply (this snippet assumes you’ve imported all the necessary namespaces).

[TestClass]
public class BlogControllerTests 
{
  [TestMethod]
  public void RecentActionUsesConventionToChooseView() 
    {
    //Arrange
    var controller = new BlogController();

    //Act
    var result = controller.Recent() as ViewResult;

    //Assert
    Assert.IsTrue(String.IsNullOrEmpty(result.ViewName));
  }
}

When I run this test, the test fails.

failed-test

This is what we expect, after all, we haven’t yet implemented the Recent method. This is the RED part of the RED, GREEN, REFACTOR rhythm of TDD.

Let’s go and implement that method.

public ActionResult Recent() 
{
  //Note we haven’t yet created a view
  return View();
}

Notice that at this point, we’re focusing on the behavior of our app first rather than focusing on the UI first. This is a stylistic difference between ASP.NET MVC and ASP.NET WebForms. Neither one is necessarily better than the other. Just a difference in approach and style.

Now when I run the unit test, it passes.

passing-test 

Ok, so that’s the GREEN part of the TDD lifecycle and a very very simple demo of TDD. Let’s move to the REFACTOR stage and start applying Dependency Injection.

It’s Refactor Time! with apologies to the reader for stretching this theme too far

In order to obtain the recent blog posts, I want to provide my blog controller with a “service” instance it can request those posts from. 

At this point, I’m not sure how I’m going to store my blog posts. Will I use SQL? XML? Stone Tablet?

Dunno. Don’t care… yet.

We can delay that decision till the last responsible moment. For now, I’ll create a repository abstraction to represent how I will store and retrieve blog posts in the form of an IPostRepository interface. We’ll update the blog controller to accept an instance of this interface in its constructor.

This is the dependency part of Dependency Injection. My controller now has a dependency on IPostRepository. The injection part refers to the mechanism you use to pass that dependency to the dependent class as opposed to having the class create that instance directly and thus binding the class to a specific implementation of that interface.

Here’s the change to my BlogController class.

public class BlogController : Controller 
{
  IPostRepository repository;

  public BlogController(IPostRepository repository) 
  {
    this.repository = repository;
  }

  public ActionResult Recent() 
  {
    //Note we haven’t yet created a view
    return View();
  }
}

Great. Notice I haven’t changed Recent yet. I need to write another test first. This will make sure that we pass the proper data to the view.

Note: If you’re following along, you’ll notice that the first test we wrote won’t compile. Comment it out for now. We can fix it later.

I’m going to use a mock framework, so before I write this test, I need to reference Moq.dll in my test project, downloaded from the MoQ downloads page.

Note: I’ve included this assembly in the example project at the end of this post.

Here’s the new test.

[TestMethod]
public void BlogControllerPassesCorrectViewData() 
{
  //Arrange
  var posts = new List<Post>();
  posts.Add(new Post());
  posts.Add(new Post());

  var repository = new Mock<IPostRepository>();
  repository.Expect(r => r.ListRecentPosts(It.IsAny<int>())).Returns(posts);

  //Act
  BlogController controller = new BlogController(repository.Object);
  var result = controller.Recent() as ViewResult;

  //Assert
  var model = result.ViewData.Model as IList<Post>;
  Assert.AreEqual(2, model.Count);
}

What this test is doing is dynamically stubbing out an implementation of the IPostRepository interface. We then tell it that no matter what argument is passed to ListRecentPosts, return two posts. We can then pass that stub to our controller.

Note: We haven’t yet needed to implement this interface. We don’t need to yet. We’re interested in isolating our test to only test the logic in the action method, so we fake out the interface for the time being.

At this point, the test fails as we expect. We need to refactor Recent to do the right thing now.

public ActionResult Recent() 
{
  IList<Post> posts = repository.ListRecentPosts(10); //Doh! Magic Number!
  return View(posts);
}

Now when I run my test, it passes!

Inject That Dependency

But we’re not done yet. When I load up a browser and try to navigate to this controller action (on my machine, http://localhost:64701/blog/recent/), I get the following error page.

No parameterless constructor defined for this object. - Mozilla
Firefox

Well of course it errors out! By default, ASP.NET MVC requires that controllers have a public parameter-less constructor so that it can create an instance of the controller. But our constructor requires an instance of IPostRepository. We need someone, anyone, to pass such an instance to our controller.

StructureMap (or DI framework of your choice) to the rescue!

Note: Make sure todownloadand reference the StructureMap.dll assembly if you’re following along. I’ve included the assembly in the source code at the end of this post.

The first step I’m going to do is create a StructureMap.config file and add it to the root of my application. Here are the contents of the file.

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap>
  <Assembly Name="MvcApplication" />
  <Assembly Name="System.Web.Mvc
              , Version=1.0.0.0
              , Culture=neutral
              , PublicKeyToken=31bf3856ad364e35" />

  <PluginFamily Type="System.Web.Mvc.IController" 
                Assembly="System.Web.Mvc
                  , Version=1.0.0.0
                  , Culture=neutral
                  , PublicKeyToken=31bf3856ad364e35">
    <Plugin Type="MvcApplication.Controllers.BlogController" 
            ConcreteKey="blog" 
            Assembly="MvcApplication" />
  </PluginFamily>

  <PluginFamily Type="MvcApplication.Models.IPostRepository" 
                Assembly="MvcApplication" 
                DefaultKey="InMemory">
    <Plugin Assembly="MvcApplication" 
            Type="MvcApplication.Models.InMemoryPostRepository" 
            ConcreteKey="InMemory" />
  </PluginFamily>

</StructureMap>

I don’t want to get bogged down in describing this file in too much detail. If you want a deeper understanding, check out the StructureMap documentation.

The bare minimum you need to know is that each PluginFamily node describes an interface type and a key for that type. A Plugin node describes a concrete type that will be used when an instance of the family type needs to be created by the framework.

For example, in the second PluginFamily node, the interface type is  IPostRepository which we defined. The concrete type is InMemoryPostRepository. So anytime we use StructureMap to construct an instance of a type that has a dependency on IPostRepository, StructureMap will pass in an instance of InMemoryPostRepository.

Well if that’s true, we better then create that class. Normally, I would use a SqlPostRepository. But for purposes of this demo, we’ll store blog posts in memory using a static collection. We can always implement the SQL version later.

Note: This is where I would normally write tests for InMemoryPostRepository but this post is already long enough, right? Don’t worry, I included unit tests in the downloadable code sample.

public class InMemoryPostRepository : IPostRepository
{
  //simulates database storage
  private static IList<Post> posts = new List<Post>();

  public void Create(Post post)
  {
    posts.Add(post);
  }

  public System.Collections.Generic.IList<Post> 
    ListRecentPosts(int retrievalCount)
  {
    if (retrievalCount < 0)
      throw new ArgumentOutOfRangeException("retrievalCount"
          , "Let’s be positive, ok?");

    IList<Post> recent = new List<Post>();
    int recentIndex = posts.Count - 1;
    for (int i = 0; i < retrievalCount; i++)
    {
      if (recentIndex < 0)
        break;
      recent.Add(posts[recentIndex--]);
    }
    return recent;
  }

  public static void Clear()
  {
    posts.Clear();
  }
}

Quick, We Need A Factory {.clear}

We’re almost done. We now need to hook up StructureMap to ASP.NET MVC by writing implementing IControllerFactory. The controller factory is responsible for creating controller instances. We can replace the built in logic with our own factory.

public class StructureMapControllerFactory : DefaultControllerFactory
{
  protected override 
    IController CreateController(RequestContext requestContext, string controllerName) 
  {
    try
    {
      string key = controllerName.ToLowerInvariant();
      return ObjectFactory.GetNamedInstance<IController>(key);
    }
    catch (StructureMapException)
    {
      //Use the default logic.
      return base.CreateController(requestContext, controllerName);
    }
  }
}

Finally, we wire it all up together by adding the following method call within the Application_Start method in Global.asax.cs.

protected void Application_Start() {
  ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());

  RegisterRoutes(RouteTable.Routes);
}

And we’re done! Now that we have hooked up the dependency injection framework into our application, we can revisit our site in the browser (after compiling) and we get…

View Not Found
Message

Excellent! Despite the Yellow Screen of Death here, this is a good sign. We know our dependency is getting injected because this is a different error message than we were getting before. This one in particular is informing us that we haven’t created a view for this action. So we need to create a view.

Sorry! Out of scope. Not in the spec.

I leave it as an exercise for the reader to create a view for the page, or you can look at the silly simple one included in the source download.

Although this example was a ridiculously simple application, the principle applies in building a larger app. Just take the techniques here and rinse, recycle, repeat your way to TDD nirvana.

To see the result of all this, download the source code.