Why can’t I use Request["id"] inside an action to get the value of the query string parameter named "id"?

I was asked this questions millions of times in the talks I did about ASP.NET MVC during the last months. I also got it asked a few times from colleagues so, when yesterday a friend asked the same question on a comment on one of my latest posts, I decided that the time had come to try and clarify this with a post.

The quick answer is: “Because you don’t want to have a dependency on the environment, especially since this can be easily avoided”.

But let me explain better. Imagine you want to display a “page” given its id, and you have to process the following url: http://example.com/Home/Page?id=123.

If you use the Request object, your action method will be (NOTE: this is not the recommended way to get the value of a query string parameter):

public ActionResult Page()
{
    int id = Convert.ToInt32(Request["id"]);
    //do something with the id
    return View();
}

Or you can do it the ASP.NET MVC idiomatic way:

public ActionResult Page(int id)
{
    //do something with the id
    return View();
}

What the ASP.NET MVC framework does is automatically initializing the parameters of the action method using the values of the query string parameter with the same name.

This has two big advantages over manually reading the Request object:

  1. it automatically casts to the correct type (in the sample you have a integer) and raises an error if the parameter is of the wrong type. Additionally if the parameters is a complex type (not just string or integer) it is automatically initialized setting values for all its properties. Imagine doing this manually reading the Request object.
  2. it isolates the action method from the environment so that the it is just a normal method with some input parameters and a return value. A side effect of this separation is that you can test the action by just supplying the input values to the method, and without the need to mock the Request object.

Having said that, I admit that there are some scenarios, like when accessing the Cookies collection or when reading the raw request content, this is the only option. But unless you are doing these exotic things, the best solution is using the idiomatic way, and let the framework do all the work for you.

Hope I clarified this a bit more.

Tags: