• Session详解、ASP.NET核心知识(8)


    介绍一下Session

    1.作用

            Cookie是存在客户端,Session是存在服务器端,目的是一样的:保存和当前客户端相关的数据(当前网站的任何一个页面都能取到Session)。

            在本篇博文的姊妹篇《Cookie详解》中,黑兔在最后说了几点Cookie的缺陷,简单的说就是无法存储重要数据。那么关乎重要数据的状态如何存储?Cookie妹妹Session讲给你一个很好的答案。

    2.医生的账本

     

            需要一种“服务器端的Cookie”:医生需要一个私人账本,记录病人编号和身份的对应关系。由于身份证无法造假,所以能够保证信息不被假冒。(身份证无法造假,这个身份证就可以唯一标识这个用户;)核心信息放到服务器上,客户端无法去篡改。这就是Session的大体原理。

     

    3.IRequiresSessionState 

            Cookie不能存储机密数据。要使用ASP.Net已经内置的Session机制。普通的HttpHandler要能够操作Session,要实现IRequiresSessionState接口,这个接口是没有任何方法的“标记接口”,因为session处理会稍微降低系统性能,所以 HttpHandler 默认不处理Session,asp.net引擎如果看到ashx实现了IRequiresSessionState,则帮咱们处理。

    4.自毁装置

            Session有自动销毁机制,如果一段时间内浏览器没有和服务器发生任何的交互,则Session会定时销毁。这也就是为什么一段时间不操作,系统就会自动退出。

            当然Session也可以手动设置销毁,比如做安全退出的功能。就需要用到。 context.Session.Abandon();//销毁Session

    5.自毁倒计时

            在web.config的system.web节点下配置sessionState节点的timeout,单位是分钟,默认是20(也只是一个建议,也许服务器10分钟的时候就让Session失效了)

    .NET中如何使用Session

    1.Session中可以存放任意类型

    1      //Cookie 的值是String
    2      //Session的值可以是几乎任何类型
    3      context.Response.ContentType = "text/html";
    4      context.Session["test1"] = "HelloWorld";
    5      context.Session["test2"]=888;

     

    2.登录案例

            这个案例意图在演示Session的使用,而绝对不是真的登录,项目中这样写,肯定被打死。。。

    1)Login页面

     1         //一个比较好的小习惯,吧Session的名字设置成一个常量字段,
     2         //以后可以直接引用这个字段,防止写错。
     3         public const string LOGINUSERNAME = "LoginUserName";
     4         public void ProcessRequest(HttpContext context)
     5         {
     6             context.Response.ContentType = "text/html";
     7             string username = context.Request["username"];
     8             string password = context.Request["password"];
     9             if (password == "123")
    10             {
    11                 context.Session[LOGINUSERNAME] = username;
    12                 context.Response.Redirect("Main.ashx");
    13             }
    14             else
    15             {
    16                 context.Response.Write("密码错误");
    17             }
    18         }

    2)需要登录才能看到的页面

     1  public void ProcessRequest(HttpContext context)
     2         {
     3             context.Response.ContentType = "text/html";
     4             string username = (string)context.Session[Login1.LOGINUSERNAME];
     5             if (username == null)
     6             {
     7                 context.Response.Redirect("login.html");
     8             }
     9             else if (username == "admin")
    10             {
    11                 context.Response.Write("哇,老大好!");
    12             }
    13             else
    14             {
    15                 context.Response.Write("当前登录用户名"+username+"没有权限查看");
    16             }
    17         }

    3.验证码 

            关于验证码的问题,Session可以记录验证码的值,黑兔在《详细说说如何生成验证码》一文中有过详细的说明,这里多说了。

    Session原理

    1.看看http报文

    clipboard

            通过http报文,我们发现报文里Cookie中有一段ASP.NET_SessionId=a4dsx.....的字符,这段什么意思?没错她就是Session。

    2.Session是服务器里的Cookie

            正常情况下Session存储在服务器的内容中,浏览器端存储这一个带有SessionId 内容的Cookie。存有Session的服务器内存就想一个银行,与之对应的浏览器Cookie就想银行卡,SessionId就是银行卡号。浏览器中不存储任何重要信息,仅有一个“钥匙”可以打开这个银行。 这就是Session的原理。

    3.用Cookie模拟一个Session 

     1     public class MySession
     2     {
     3         //MySessionId是存储卡号的 Cookie名。Cookie中的value是真正的SessionId。
     4         private const string MYSESSIONID = "MySessionId";
     5         private HttpContext context;
     6         private string sessionId;
     7         public MySession(HttpContext context)
     8         {
     9             this.context = context;
    10             HttpCookie cookie = context.Request.Cookies[MYSESSIONID];
    11             if (cookie==null)
    12             {
    13                 CreateSession();
    14             }
    15             else
    16             {
    17                 this.sessionId = cookie.Value;
    18             }
    19         }
    20 
    21         private void CreateSession()
    22         {
    23             //姑且用Guid模拟一个SessionId
    24             Guid guid = Guid.NewGuid();
    25             this.sessionId = guid.ToString();
    26             HttpCookie cookie = new HttpCookie(MYSESSIONID);
    27             cookie.Value = sessionId;
    28             context.Response.SetCookie(cookie);
    29         }
    30 
    31         public void SetValue(string name, string value)
    32         {
    33             //保存路径,在服务器端。
    34             string fullpath = context.Server.MapPath("~/MySession/" + sessionId);
    35             Dictionary<string, string> dict;
    36             if (File.Exists(fullpath))//如果文件存在,则先把之前的数据反序列化出来
    37             {
    38                 using (Stream stream = File.OpenRead(fullpath))
    39                 {
    40                     BinaryFormatter bf = new BinaryFormatter();
    41                     dict = (Dictionary<string, string>)bf.Deserialize(stream);
    42                 }
    43             }
    44             else
    45             {
    46                 dict = new Dictionary<string, string>();//如果不存在,则创建空的字典
    47             }
    48             dict[name] = value;
    49             //dict.Add(name, value);//设置值
    50             using (Stream stream = File.OpenWrite(fullpath))//重新序列化把dict保存到文件
    51             {
    52                 BinaryFormatter bf = new BinaryFormatter();
    53                 bf.Serialize(stream,dict);
    54             }
    55         }
    56 
    57         public string GetValue(string name)
    58         {
    59             string fullpath = context.Server.MapPath("~/MySession/" + sessionId);
    60             Dictionary<string, string> dict;
    61             if (File.Exists(fullpath))//如果文件存在,则先把之前的数据反序列化出来
    62             {
    63                 using (Stream stream = File.OpenRead(fullpath))
    64                 {
    65                     BinaryFormatter bf = new BinaryFormatter();
    66                     dict = (Dictionary<string, string>)bf.Deserialize(stream);
    67                 }
    68             }
    69             else
    70             {
    71                 dict = new Dictionary<string, string>();//如果不存在,则创建空的字典
    72             }
    73             if (dict.ContainsKey(name))
    74             {
    75                 return dict[name];
    76             }
    77             else
    78             {
    79                 return null;
    80             }
    81         }
    82     }
    View Code

            1)这个例子用使用了一个名为MySessionId的Cookie存储SessionId。SessionId=context.Request.Cookies[MYSESSIONID].value。SessionId作为服务器端存储Session数据的文件名。

            2)通过序列化,和反序列的方式把一个Dictionary对象 存储在服务器端。

            3)SessionId的值,是由Guid生成的。 ASP.NET如何命名的,我不晓得姑且用GUID做一个标识,总之唯一就好了。

            4)总之这个案例演示的就是这样一个原理图。这个原理图与Seesion机制基本一致。

                clipboard[1]    

    进程外Session

    1.进程外Session?

            刚刚说了,常规情况下Session是保存在服务器的内存中的。这种方式,会带来一定的性能损耗。进程外Session就是把Session从内存中拿到其他地方存储。

    2.Session保存在SQLServer中配置方法

            1)运行.NetFramework安装目录下对应版本的aspnet_regsql.exe 来创建相关的数据库、表和存储过程等,比如:

    C:WindowsMicrosoft.NETFrameworkv4.0.30319>aspnet_regsql.exe -ssadd -sstype p -S 127.0.0.1 -U sa -P 123456

     

            其中-sstype p表示数据库名固定为ASPState,-S(大写)为数据库服务器地址,-U和-P分别为数据库的用户名和密码,

    参数详细解释见 http://blog.csdn.net/yuanzhuohang/article/details/6758304

            2)修改web.config中sessionState节点的配置:<sessionState mode="SQLServer" timeout="20" sqlConnectionString="server=.;uid=sa;password=123456;" ></sessionState>

    本文的姊妹篇Cookie

    Cookie详解

  • 相关阅读:
    gitlab 升级
    通过 备份文件 恢复/迁移 gitlab
    gitlab 远程 定时备份
    PHP 中替换若干字符串字串为数组中的值,不用循环,非常高效
    php 在客户端生成txt文件并且下载
    Mysql时间戳函数
    mysql中在表中insert数据时,有重复主键id时,变成update
    css中解决img在a元素中使得a元素撑大写法
    php以excel的形式将数据输出
    css中常用的hack
  • 原文地址:https://www.cnblogs.com/mcad/p/Session.html
Copyright © 2020-2023  润新知