zoukankan      html  css  js  c++  java
  • 说说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

  • 相关阅读:
    单例模式 (线程安全)
    Hystrix (容错,回退,降级,缓存)
    Feign负载均衡
    Ribbon远程调用
    Eureka服务注册与发现
    适配器模式
    docker学习(二)
    使用Eclipse进行远程调试(转)
    docker学习(一)
    Mysql批量更新的一个坑-&allowMultiQueries=true允许批量更新(转)
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/6284971.html
Copyright © 2011-2022 走看看