积极答复者
ASP.NET(MVC)中Session["key"] 完全相等于 HttpContext.Session["key"]原理是什么?

问题
-
[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:43
答案
-
[1]
Controller中的Session,在MSDN中的解释就是:
Gets the HttpSessionStateBase object for the current HTTP request.
HttpContext.Session,在MSDN中的解释类似
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
全部回复
-
[1]
Controller中的Session,在MSDN中的解释就是:
Gets the HttpSessionStateBase object for the current HTTP request.
HttpContext.Session,在MSDN中的解释类似
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
-
如果你只想看metadata的话,可以使用SDK自带的Ildasm.exe , 在Visual Studio *** Command Prompt中运行Ildasm即可。打开你要查看的dll,然后在View里面执行MetaInfo -> Show.
不过Ildasm只能显示IL,如果你想看源代码,需要用第三方的工具。我目前使用的是ILSpy(http://ilspy.net/)