2012年3月6日 星期二

ASP.NET Params Collection vs. QueryString, Forms vs. Request["index"] and Double Decoding


轉:http://www.hanselman.com/blog/ASPNETParamsCollectionVsQueryStringFormsVsRequestindexAndDoubleDecoding.aspx


In ASP.NET you can yank a value out of the QueryString like this, where QueryString is of type NameValueCollection but is internally an HttpValueCollection that includes some extra helper methods.


string foo = Request.QueryString["foo"];
But you can also go like this:
string foo = Request["foo"];
And folks know (passed through myth and legend) that the line above will search through the QueryString, Form, Cookies, and ServerVariables collections. However, it's important (for performance) to know what order the collections are searched. Here's the code from Reflector:  
    1 public string get_Item(string key)
    2 {
    3     string text1 = this.QueryString[key];
    4     if (text1 != null)
    5     {
    6         return text1;
    7     }
    8     text1 = this.Form[key];
    9     if (text1 != null)
   10     {
   11         return text1;
   12     }
   13     HttpCookie cookie1 = this.Cookies[key];
   14     if (cookie1 != null)
   15     {
   16         return cookie1.Value;
   17     }
   18     text1 = this.ServerVariables[key];
   19     if (text1 != null)
   20     {
   21         return text1;
   22     }
   23     return null;
   24 }
So you can see what order things are searched in. However, personally, I don't like this default Item indexer. I prefer to be more explicit. I'd hate to accidentally retrieve a Cookie because a QueryString variable was missing. It's always better to be explicit and ask for what you want.
Interestingly, there is ANOTHER collection of QueryString, Form, Cookies, and ServerVariables, but rather than a "pseudo-collection" as we see above, this is an actual combined collection.
  432 public NameValueCollection Params
  433 {
  434     get
  435     {
  436         InternalSecurityPermissions.AspNetHostingPermissionLevelLow.Demand();
  437         if (this._params == null)
  438         {
  439             this._params = new HttpValueCollection();
  440             this.FillInParamsCollection();
  441             this._params.MakeReadOnly();
  442         }
  443         return this._params;
  444     }
  445 }
  446  
  447 private void FillInParamsCollection()
  448 {
  449     this._params.Add(this.QueryString);
  450     this._params.Add(this.Form);
  451     this._params.Add(this.Cookies);
  452     this._params.Add(this.ServerVariables);
  453 }
  454  
The internal collection "_params" inside is a special derived NameValueCollection of type HttpValueCollection, and is exposed as NameValueCollection.
Important Note: The constructor for HttpRequest will parse the actual string QueryString and UrlDecode the values for you. Be careful not to DOUBLE DECODE. Know what's encoded, when, and who does the decoding.  Likely it's not you that needs to do anything. If you double decode you can get into some weird situations. Ben Suter reminded me that if you pass in /somepage.aspx?someParam=A%2bB you expect to get "A+B" as that param is the equivalent of HttpUtility.UrlEncode("A+B"). But, if you make a mistake and do HttpUtility.UrlDecode(Request.Params("someParam")), you'll get "A B" as the + was double-decoded as a space.
Here's the trick though. If you have BOTH a QueryString parameter "Foo=Bar1" AND a Forms item called "Foo=Bar2" if you say string foo = Request.Params["Foo"]; you'll get a string back "Bar1,Bar2"! It's a collection, not a HashTable. So, never make assumptions when you use HttpRequest.Params, or you will get in trouble. If there's a chance you could get multiple values back, you need to consider using an explicit collection or be smart about your string.Split() code.
------------------------------------------------------------另一看法
看起来Request.Params更好一些,但是还是不明白既然Param包括了所有,为什么还要有QueryString呢?
request.params其实是一个集合,它依次包括request.querystring、request.form、request.cookies和request.servervariables。

如果要在两个页面传递数据的话,只能用request.querystring、request.form、request.cookies

Request.Params 是在 QueryString、Form、Server Variable 以及 Cookies 找数据, 他首先在 QueryString 集合查找数据,如果在 QueryString 找到数据,就返回数据,如果没有找到就去 Form 集合中查找数据,找到就返回,否则在往下一下个集合查找数据。

Request.Params["id"] ,Request.Form["id"] ,Request.QueryString["id"] 的用法以及区别?

Request.Params是所有post和get传过来的值的集合,Request.Form是取post传值, Request.QueryString是get传过来的值

沒有留言:

張貼留言