As web developers we are tempted to be general about our use or the request object and submitted parameters.
The temptation to access
Request["someKey"] is high because it frees us from wondering whether MyPage.aspx was posted to using POST or GET and we might also convince ourselves that it’s more flexible because it means that both POST and GET would work. Well, it would do something, that’s for sure. But do we always get consistent results?
Where does val come from? HttpRequest class scans QueryString, Form, Cookies and ServerVariables of the request object, in that order. First match gets you an answer. This also means that if a query string param named “SID” exists and a form field named “SID” exists, you will get the query string value (GET). The implementation essentially is
Note here that as a last resort, the key is looked up against the ServerVariables collection. That’s makes me a bit uneasy. Not that I ever wanted a form variable named “USER_AGENT” but now that I know it scans for it, I’ll be careful about my variable naming.
Moving on, consider:
string val = Context.Request.Params["MyKey"];
val come from? You wouldn’t necessarily know. Params is built on first request, and accessed throughout the lifetime of the HttpRequest object. Building it is done by creating a new collection, which includes all 4 request sources, as listed below. Since it is a
Collections.Specialized.NameValueCollection type, if a key exists in more than one of the 4 sources, the value would be appended as a comma separated list. So if “PID” was both a query string GET parameter (say value 123) and a form POST variable (say value 456), then
(Request.Params["PID"] == "123,456") == true;
What can we conclude from these observations?
If you called Request.Params, even once, you now created a new collection, allocating enough memory to hold ALL parameters from the various sources. If you know what the parameter’s source is, you would be more efficient using that source collection directly. If you or your buddy working on the same code tree called Request.Params, however, the hit is taken, and subsequent references would not re-allocate collections.
Precedence of parameters applies when you call Request[key], but not when you call
The effect of Params collection sporting a comma separated list is a double whammy:
Upon insert, (Request.Params[“myKey”] = “myvalue”) an arraylist is created and appended to (repetitive allocation for each value).
Upon assignment from Request.Params:
string  GetValues()method is used, the
ArrayListgets converted to a
string just for you each time (it’s not cached or preserved as an internal variable).
string Get()is used, private static string
GetAsOneString(ArrayList list), a string builder object is created just for you to concatenate the values and return them to you.
Although both methods are coded as efficiently, neither gets you a reference to an existing object, and both have to create another object and copy data to it on the fly each time. For that reason, it’s less efficient than if you knew exactly the source of your parameter and used that collection as the source.
This issue can manifest if your application combines things like flash movies, remote static HTML forms submitting to your site (think affiliate marketing programs) and various hard coded links which were created to a specific form from menus, site maps and other corners of your application. When you work with forms designed by visual studio and sue asp form controls you generally don’t encounter this because then you have access to strongly typed properties. More often than not I have run across a hybrid of asp form controls and hand coded links from CMS parts of your app or other rouge text links so it’s worth knowing and paying attention.
To reign in the parameters and ensure no rouge parameters exist ever, I’d recommend creating a utility class that would wrap the Request object and use a set of well known parameters only which would encompass all usable parameter names.
In conclusion, for both efficiency and un-ambiguity you would benefit from using concise parameter sources such as
Request.Form["name"], and not rely on the “catchall” of Params or
Reqest["name"] as shorthand. If you do find the need, inspect and ensure that parameter names do not collide so that you don’t end up with a peculiar value.