First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

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:
posted on Friday, June 5, 2009 6:53 PM

Comments on this entry:

# re: Using Request inside Actions: why it is a bad idea

Left by raffaeu at 6/5/2009 8:06 PM

That's great Simone. I already known about the actions and do it from the action directly, but it's better to have a clear explanation by someone. Of course I didn't think about the direct cast ...
Thanks for your 2 cents!

# re: Using Request inside Actions: why it is a bad idea

Left by Kazi Manzur Rashid at 6/6/2009 5:51 AM

I think one more benefits which Simone might have forgot to mention is that it does not matter from where is the value is coming, it might be from QueryString, Forms or the ActionParameters defined in the Route.

# re: Using Request inside Actions: why it is a bad idea

Left by Simone at 6/6/2009 2:34 PM

@Kazi: good point. Actually I left this out for sake of simplicity, but it's another advantage of having the framework initialize the parameters for you: you can change Get to Post, or even putting the variable as route parameter, and your action doesn't need to be changed

# re: Using Request inside Actions: why it is a bad idea

Left by Dennis Leng at 6/8/2009 1:09 AM

good point, how about uploading files, the only way i could think of is to read from request.files

cheers

# re: Using Request inside Actions: why it is a bad idea

Left by Simone at 6/8/2009 1:16 AM

@Dennis: you don't need to.
Just specify an action parameter of type "HttpPostedFileBase"
You can read more about how to do file uploads with ASP.NET MVC at the following url:
www.codethinked.com/.../...-ASPNET-MVC-10-RTM.aspx

HTH

# re: Using Request inside Actions: why it is a bad idea

Left by Dennis Leng at 6/8/2009 7:34 AM

Thank you for your quick reply. Simon :) what if i expect a view object for the action parameter. e.g. public actionResult Edit(Student student), student has a photo byte[] property. on the view page, student's name and gender could be updated as well as upload a photo, when comes to save, in edit action how you access the uploaded file without accessing Request. Sorry for my bad English. hope i made myself clear. :)

Thank you.

# re: Using Request inside Actions: why it is a bad idea

Left by Simone at 6/8/2009 10:05 AM

@Dennis: if yo made "view object" on purpose for submitting data to the Action, then I'd change your byte array to HttpPostedFileBase.
If you are using one of your generic domain model object you have two options:
1 - use a custom view object and then maps it to your domain object (an during the process save the HttpPostedFileBase to your byte array)
2 - Write a ModelBinder that initialize any byte array taking the value from the HttpPostedFileBase object that is sent from the view.

Comments have been closed on this topic.