說說Request.Params[key]和Request[key]


摘要

其實你一看到,就應該會想到,這個不簡單嗎,不就是服務端接收參數的兩種方式嗎?是的。在asp.net編程中,QueryString、Form、Cookie是三種比較常見的接收客戶端參數的方式。QueryString:接收包含在url中的參數。Form:接收表單數據。Cookie可以獲取會話狀態中保存的信息(大部分情況下用來存儲用戶信息)。除了這些外,HttpRequest還提供了ServerVariables來讓我們獲取一些來自web服務器變量。

問題來了?

其實通常情況下,我們知道傳遞的參數來自哪,可以使用QueryString,Form明確的來接收url或者表單中的數據。但服務端接口為了既可以通過url獲取參數,又可以通過Form獲取參數,該如何呢?(當然,規定調用方必須通過url或者Form某一種方式除外)。那么就要用到Request[]或者Request.Params[]這兩種方式獲取來自客戶端提交的數據了。但,到底用哪個?

下面先看一個例子:

        public ActionResult Index()
        {
            ViewBag.requestParams = Request.Params["name"]; ;
            ViewBag.request = Request["name"];
            return View();
        }

有這樣一個action,我們用來獲取url中傳遞的參數name。這兩種方式有什么區別呢?你猜....

到這里,你會發現,這兩種方式,不一樣嗎?都可以接收正確的參數。但還是有特殊情況。

我們添加一個cookie的action,向客戶端添加一個以name為鍵的值,代碼如下:

   public string Cookie()
        {
            Response.Cookies.Add(new HttpCookie("name", "wolfy") { Expires = DateTime.Now.AddDays(1) });
            return "cookie writes successfully!";
        }

然后我們再訪問一下,Index頁面。

發現了不同了吧。你可以說,你這種方式太奇葩了,哪有那么巧參數名稱一樣,但一個項目多個人來合作完成,參數名稱名稱相同還是很有可能的。所以不小心就會出現這種問題,不小心就會中招,掉坑里的。

到底為什么?

源碼:https://github.com/Microsoft/referencesource

我們先看一下Params的實現。

        // Params collection - combination of query string, form, server vars
        //    Gets a combined collection of QueryString+Form+ ServerVariable+Cookies.
        public NameValueCollection Params {
            get {
                if (HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Low))
                    return GetParams();
                else
                    return GetParamsWithDemand();
            }
        }
        private NameValueCollection GetParams() {
            if (_params == null) {
                _params = new HttpValueCollection(64);
                FillInParamsCollection();
                _params.MakeReadOnly();
            }
            return _params;
        }

        [AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
        private NameValueCollection GetParamsWithDemand()
        {
            return GetParams();
        }
        // Params collection support
        private void FillInParamsCollection() {
            _params.Add(this.QueryString);
            _params.Add(this.Form);
            _params.Add(this.Cookies);
            _params.Add(this.ServerVariables);
        }

通過上面的代碼可以看到Params是NameValueCollection鍵值對類型的只讀屬性,在FillInParamsCollection方法中,將QueryString,Form,Cookies,ServerVariables加入到了字段中。這就說明了上面的例子中,為什么Params[key]會取到QueryString和cookie里面的值了。

我們在看一下Request[key]的實現。

        // Default property that goes through the collections
        //      QueryString, Form, Cookies, ClientCertificate and ServerVariables
        public String this[String key] {
            get {
                String s;

                s = QueryString[key];
                if (s != null)
                    return s;

                s = Form[key];
                if (s != null)
                    return s;

                HttpCookie c = Cookies[key];
                if (c != null)
                    return c.Value;

                s = ServerVariables[key];
                if (s != null)
                    return s;

                return null;
            }
        }

可以看到Request[key]的實現方式,查找順序是QueryString,Form,Cookies,ServerVariables,直到找到然后直接返回。

總結

一直對Request.Params[key]和Request[key]比較困惑,在這里也掉過坑,最近在項目中,又看到了,所以,就趁着扒了一下源碼。

感興趣的可以或者對以前用法不太理解的可以扒一扒源碼,或許可以可以解惑。

資料

https://github.com/Microsoft/referencesource


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM