Testing Request.Form with ASP.NET MVC

July 8th 2008, 10:22 am in ASP.NET MVC, Monorail.

I wanted to quickly spike an idea that I had last night, and while normally I’d use Monorail, I thought it was high time I took an interest in ASP.NET MVC. It took about ten minutes for me to stumble to a halt.

In Monorail, you can do something like this:

public void Save([DataBind("item")]Model model){}

The instance of model will be automatically populated with incoming variables from Request.Form or Request.QueryString. To do similar in ASP.NET MVC, it seems you have to do this:

public void Save()
{
    Model model = new Model();
    BindingHelperExtensions.Binding.UpdateFrom(model, Request.Form, "item");
}

A bit more verbose, but I can live with that. The trouble came when I was thinking about unit testing this (yes, I should have thought about that first if I really wanted to do TDD, bla bla).

In Monorail, a test for the above could look like:

public void SaveTest()
{
    MyController controller = new MyController();
    controller.Save(new Model());
}

Obviously the above doesn’t actually do anything, but you get the point. But how would I replicate that with ASP.NET MVC? I can’t just pass through a ready-made instance to the Save action. I needed some way to pass through some values to Request.Form so that UpdateFrom would have something to chew on.

Trouble is… there doesn’t seem to be a simple way of doing that. I’ve reviewed a number of blog articles, and even looking at the code for Rob Conery’s Storefront which is now linked from the ASP.NET website itself, shows that his solution is to create a fake HttpContextBase class which uses a mock HttpRequestBase.

This being Preview 3, I’d like to think that this process would be streamlined in the near future, but for now, I’ll pass.

Responses to “Testing Request.Form with ASP.NET MVC”

  1. While I have not spent much time looking at ASP.NET MVC, I am pretty sure it has convention based parameter population. So you should be able to do this:

    public void Save(Model item)

    where the name of the argument matches a key in the form.Request collection.

    I think ScottGu wrote about this when one of the early previews dropped, but I could not find the post.

    Robin Clowers
  2. I just tried it Robin, and it doesn’t seem to work. I’d be happy to be proved wrong though, because it would be the simplest solution.

    Colin Ramsay
  3. I think there is a way to use the Castle DataBind attribute in ASP.NET MVC. If I’m not mistaken it’s in MVCContrib. I haven’t tried it out yet, because I use my own binder that also binds the associations with other entities. Otherwise my controller is cluttered with code to get the associations filled

    Bart

Post a Reply