none
ASP.NET(MVC)中Session["key"] 完全相等于 HttpContext.Session["key"]原理是什么? RRS feed

  • 问题

  • [1]ASP.NET(MVC)中Session["key"] 完全相等于 HttpContext.Session["key"]原理是什么?

                HttpContext.Session["key"] = value;//value无论是简单类型还是引用类型,对结果无影响
                if (Session["key"] == HttpContext.Session["key"])
                {
                    return true;//永远是true
                }

    [2]会话存储数据的原理是什么?

    //Cart为类实例,这是获取Session会话的方法,本代码源于Adam Freeman的演示中 private Cart GetCart() { Cart cart = (Cart)Session["Cart"]; if (cart == null) { cart = new Cart(); Session["Cart"] = cart; } return cart;//请注意这里,当原会话未引用到对象时,返回的是新创建的类对象 }

    //曾有说法是:会话的实质是深拷贝,但是如果是深拷贝,请看上述代码,返回的cart对象与Session["Cart"]

    完全引用于两个完全不同的栈空间,与Adam Freeman的演示违背。




    Who Dares Wins


    2016年2月21日 14:33

答案

  • [1]

    Controller中的Session,在MSDN中的解释就是:

    Gets the HttpSessionStateBase object for the current HTTP request.

    Controller.Session Property


    HttpContext.Session,MSDN中的解释类似

    HttpContext.Session Property

    Gets the HttpSessionState object for the current HTTP request.

    他们都是指向同样的object.

    [2]

    Session对象保存在内存中,给Session赋值和变量赋值一样,值类型和引用类型行为不同

    • 对于值类型,把值得内容赋值给Session.
    • 对于引用类型,把引用赋给Session. Object还是只有一份。

    因此不涉及到深拷贝还是浅拷贝。

    我下面的代码做为实例:

    namespace MvcApplicationWebAPI.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                var testData = new SessionData() { i = 0, s = "a" };   //SessionData为引用类型,这里创建了新的Object, testData指向了它.
                Session["SessionData"] = testData;   //Session["SessionData"] 指向了同一个Object
    
                testData.i = 1;                      //通过testData引用 修改了Object的内容
    
                int temp = ((SessionData)Session["SessionData"]).i;    //使用Session["SessionData"]引用取得Object, 内容也被修改了,以为Object只有一份。
    
    
    
                int testInt = 0;                        //值类型
                Session["SessionInt"] = testInt;        //值类型赋值给Session["SessionInt"], 这个时候值得内容到了Session["SessionInt"]中,因此有两份实例了。
    
                testInt = 1;                            //修改testInt为 1
    
                int temp1 = (int)Session["SessionInt"];  //Session["SessionInt"]的内容还是0,两份实例之间互相不影响
    
    
    
                
                return View();
            }
        }
    
    
        public class SessionData
        {
            public int i { get; set; }
            public string s { get; set; }
        }
    }

    • 已标记为答案 周 靖添 2016年2月22日 4:16
    2016年2月22日 1:07

全部回复

  • [1]

    Controller中的Session,在MSDN中的解释就是:

    Gets the HttpSessionStateBase object for the current HTTP request.

    Controller.Session Property


    HttpContext.Session,MSDN中的解释类似

    HttpContext.Session Property

    Gets the HttpSessionState object for the current HTTP request.

    他们都是指向同样的object.

    [2]

    Session对象保存在内存中,给Session赋值和变量赋值一样,值类型和引用类型行为不同

    • 对于值类型,把值得内容赋值给Session.
    • 对于引用类型,把引用赋给Session. Object还是只有一份。

    因此不涉及到深拷贝还是浅拷贝。

    我下面的代码做为实例:

    namespace MvcApplicationWebAPI.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                var testData = new SessionData() { i = 0, s = "a" };   //SessionData为引用类型,这里创建了新的Object, testData指向了它.
                Session["SessionData"] = testData;   //Session["SessionData"] 指向了同一个Object
    
                testData.i = 1;                      //通过testData引用 修改了Object的内容
    
                int temp = ((SessionData)Session["SessionData"]).i;    //使用Session["SessionData"]引用取得Object, 内容也被修改了,以为Object只有一份。
    
    
    
                int testInt = 0;                        //值类型
                Session["SessionInt"] = testInt;        //值类型赋值给Session["SessionInt"], 这个时候值得内容到了Session["SessionInt"]中,因此有两份实例了。
    
                testInt = 1;                            //修改testInt为 1
    
                int temp1 = (int)Session["SessionInt"];  //Session["SessionInt"]的内容还是0,两份实例之间互相不影响
    
    
    
                
                return View();
            }
        }
    
    
        public class SessionData
        {
            public int i { get; set; }
            public string s { get; set; }
        }
    }

    • 已标记为答案 周 靖添 2016年2月22日 4:16
    2016年2月22日 1:07
  • 通过反编译工具查看System.Web.Mvc.Controller的代码Session就是从HttpCOntext.Session:

    2016年2月22日 1:12
  • 您好,非常感谢您的回答,您的回答对我起到很大帮助。

    在这里还有一个小小问题想要咨询您,如何使用反汇编工具查看元数据?


    Who Dares Wins


    2016年2月22日 4:16
  • 如果你只想看metadata的话,可以使用SDK自带的Ildasm.exe , 在Visual Studio *** Command Prompt中运行Ildasm即可。打开你要查看的dll,然后在View里面执行MetaInfo -> Show. 

    不过Ildasm只能显示IL,如果你想看源代码,需要用第三方的工具。我目前使用的是ILSpy(http://ilspy.net/)

    2016年2月22日 4:30
  • 非常感谢

    Who Dares Wins

    2016年2月22日 5:06