asp.net 狀態(tài)的傳遞和保存

字號(hào):


    1,http協(xié)議是無(wú)狀態(tài)的。服務(wù)器不會(huì)記住上次給瀏覽器的處理結(jié)果,如果需要上次處理結(jié)果(上次狀態(tài))就需要瀏覽器把處理結(jié)果值(上次狀態(tài))再次給服務(wù)器。
    2,url傳值:通過(guò)url參數(shù)或者通過(guò)form表單進(jìn)行頁(yè)面件的傳值 (不能做到很自由的存取和讀取,而且不安全)
    3,cookie :①cookie可以用來(lái)進(jìn)行更加自由的數(shù)據(jù)的存取和讀取。
    ②cookie是和站點(diǎn)相關(guān)的,自己域名寫(xiě)的只有自己的域名才可以讀取。
    ③客戶(hù)端向服務(wù)器發(fā)送請(qǐng)求的時(shí)候 處理發(fā)送form表單信息以外還會(huì)把和站點(diǎn)有關(guān)的所有的cookie發(fā)送給服務(wù)器,是強(qiáng)制的。
    ④服務(wù)器返回的數(shù)據(jù)處理html數(shù)據(jù)以外,還會(huì)返回修改的cookie,瀏覽器拿到修改后的cookie更新到本地的cookie
    ⑤服務(wù)器端使用cookie案例,記住用戶(hù)名功能:
    a,設(shè)置頁(yè)面值: response.setcookie(new httpcookie("username",username))
    b,讀取頁(yè)面值: username=request.cookies["username"].value
    ⑥瀏覽器關(guān)閉以后cookie的聲明周期到期,也就是cookie的默認(rèn)生命周期是瀏覽器的生命周期??梢酝ㄟ^(guò)設(shè)置expires屬性設(shè)置cookie的過(guò)期時(shí)間:cookie.expires=datetime.now.adddays(-1)
    ⑦cookie在客戶(hù)端是以鍵值對(duì)存在的
    4,cookie缺點(diǎn):①客戶(hù)端額可以手動(dòng)清楚cookie 所以cookie里面存放的信息是可有可無(wú)的信息
    ②瀏覽器對(duì) cookie 的大小有限制,因此只有不超過(guò) 4096 字節(jié)才能保證被接受
    ③機(jī)密信息不能放到cookie里面
    ④cookie不能跨瀏覽器
    5,cookie的寫(xiě)和讀: a,新建cookietest.html頁(yè)面并添加 兩個(gè)按鈕分別用于cookie的讀和寫(xiě)
    代碼如下:
    <!doctype html>
    <html xm lns="http://www.w3.org/1999/xhtml">
    <head>
    <me ta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
    </head>
    <body>
    <form>
    <in put type="submit" name="read" value="讀取cookie" />
    <in put type="submit" name="write" value="寫(xiě)入cookie" />
    <br />
    讀取出來(lái)的cookie: $model.cookievalue
    </form>
    </body>
    </html>
    b,建立對(duì)應(yīng)的cookietest.ashx頁(yè)面 實(shí)現(xiàn)cookie的新建寫(xiě)入本地以及讀取cookie的值
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    namespace httpnostatus
    {
    /// <summary>
    /// httpcookie 的摘要說(shuō)明
    /// </summary>
    public class cookietest : ihttphandler
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/html";
    //if else 判斷是點(diǎn)擊的那個(gè)按鈕
    if (!string.isnullorempty(context.request["read"]))
    {
    if (context.request.cookies["age"] != null)
    {
    httpcookie cookie = context.request.cookies["age"];
    string strvalue = cookie.value;
    var data = new { cookievalue = strvalue };
    //加載模板頁(yè)面并傳遞 cookie value的值
    string strhtml = common_nvelocity.renderhtml("cookietest.html", data);
    context.response.write(strhtml);
    }
    else
    {
    context.response.write("cookie 不存在");
    }
    }
    else if (!string.isnullorempty(context.request["write"]))
    {
    //寫(xiě)入新的cookie
    httpcookie acookie = new httpcookie("age");
    acookie.value = "25";
    acookie.expires = datetime.maxvalue;
    context.response.cookies.add(acookie);
    //cookie不存在 直接加載模板頁(yè)面
    string strhtml = common_nvelocity.renderhtml("cookietest.html", null);
    context.response.write(strhtml);
    }
    else
    {
    //第一次加載頁(yè)面
    string strhtml = common_nvelocity.renderhtml("cookietest.html", null);
    context.response.write(strhtml);
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    6,cookie最主要的一個(gè)功能是保存用戶(hù)的登陸名,這樣用戶(hù)在下次登陸的時(shí)候系統(tǒng)就可以自動(dòng)填寫(xiě)登陸名稱(chēng)
    a,新建logincookie.html頁(yè)面,頁(yè)面中添加我們經(jīng)常見(jiàn)到的 用戶(hù)名,用戶(hù)密碼,登陸
    登陸頁(yè)面第一次加載的時(shí)候,設(shè)置默認(rèn)的登陸名為空,登陸成功以及再次登陸的時(shí)候系統(tǒng)就自動(dòng)補(bǔ)充登陸用戶(hù)名
    <!doctype html>
    <html xm lns="http://www.w3.org/1999/xhtml">
    <head>
    <me ta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
    </head>
    <body>
    <form action="logincookie.ashx" method="post">
    <table>
    <tr>
    <td>登陸名</td>
    <td>
    <in put type="text" name="username" value="$model.loginuser" /></td>
    </tr>
    <tr>
    <td>密碼</td>
    <td>
    <in put type="password" name="password" /></td>
    </tr>
    <tr>
    <td>
    <in put type="submit" name="login" value="登陸" /></td>
    <td></td>
    </tr>
    </table>
    </form>
    </body>
    </html>
    b, 新建對(duì)應(yīng)的logincookie.ashx頁(yè)面,實(shí)現(xiàn)把用戶(hù)名讀取出來(lái)并寫(xiě)入cookie "ckloginuser"
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    namespace httpnostatus
    {
    /// <summary>
    /// logincookie 的摘要說(shuō)明
    /// </summary>
    public class logincookie : ihttphandler
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/html";
    //加載頁(yè)面直接顯示 頁(yè)面
    if (context.request.form["login"] == null)
    {
    string strhtml = "";
    var data = new { loginuser = "" }; //登陸賬號(hào)默認(rèn)為空
    //判斷cookie是否存在,如果存在 把cookie的值傳遞到html頁(yè)面,如果不存在就是默認(rèn)的空
    if (context.request.cookies["ckloginuser"] != null)
    {
    data = new { loginuser = context.request.cookies["ckloginuser"].value.tostring() };
    }
    strhtml = common_nvelocity.renderhtml("logincookie.html", data);
    context.response.write(strhtml);
    }
    else
    {
    //用戶(hù)登陸,保存用戶(hù)名到cookie
    httpcookie loginuser = new httpcookie("ckloginuser");
    loginuser.value = context.request.form["username"];
    loginuser.expires = datetime.now.adddays(30);
    context.response.cookies.add(loginuser);
    //加載頁(yè)面直接顯示 頁(yè)面
    string strhtml = common_nvelocity.renderhtml("logincookie.html", new { loginuser = context.request.form["username"] });
    context.response.write(strhtml);
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    7,以上方法把登陸賬號(hào)以cookie的形式存放在客戶(hù)端,這樣每一次的請(qǐng)求就可以帶出用戶(hù)登陸名稱(chēng)了
    有一種情況: 用戶(hù)登陸成功以后就可以訪(fǎng)問(wèn)網(wǎng)站的其他所有頁(yè)面,其他頁(yè)面就需要先判斷用戶(hù)是否登陸成功。
    如果登陸成功為true放到cookie中,這樣的客戶(hù)端就可以進(jìn)行篡改把false改為true從而可以非法訪(fǎng)問(wèn)為授權(quán)頁(yè)面了,這樣放到cookie就不安全了。
    如果登陸成功放到服務(wù)器端,那么網(wǎng)站的多個(gè)頁(yè)面就可以直接讀取到這個(gè)值,而且是安全的不會(huì)被客戶(hù)端篡改的了。
    8,session原理: 把數(shù)據(jù)value值存儲(chǔ)在服務(wù)器端并在客戶(hù)端存放value對(duì)應(yīng)的id 。(id,value)都存放服務(wù)器 另外把id以cookie的形式存放客戶(hù)端。這樣就可以從客戶(hù)端cookie中抓取id,然后從服務(wù)器端讀取到id對(duì)應(yīng)的value。
    10,下面示例以session原理實(shí)現(xiàn)頁(yè)面判斷用戶(hù)是否有成功登陸:成功登陸的用戶(hù)可以對(duì)特定頁(yè)面進(jìn)行訪(fǎng)問(wèn)、如果沒(méi)有成功登陸就跳轉(zhuǎn)到登陸頁(yè)面。
    a. 添加類(lèi) sessionmgr.cs 在服務(wù)器端存儲(chǔ) 鍵值對(duì) id/value
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    namespace httpnostatus
    {
    public class sessionmgr
    {
    //定義鍵值對(duì),存儲(chǔ)登陸信息
    private static dictionary<guid, string> keyvalue = new dictionary<guid, string>();
    //設(shè)置鍵值對(duì)的值
    public static void setkeyvalue(guid id, string value)
    {
    keyvalue[id] = value;
    }
    /// <summary>
    /// 檢查客戶(hù)端傳遞過(guò)來(lái)的鍵值對(duì)是否存在
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public static bool ifidexist(guid id)
    {
    return keyvalue.keys.contains(id);
    }
    //返回服務(wù)器端id對(duì)應(yīng)的value值
    public static string getvalue(guid id)
    {
    return keyvalue[id].tostring();
    }
    }
    }
    b. 添加 loginsession.ashx 判斷用戶(hù)是否登陸成功,如果登陸成功把存儲(chǔ)對(duì)應(yīng)的鍵值對(duì)的值
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    namespace httpnostatus
    {
    /// <summary>
    /// loginsession 的摘要說(shuō)明
    /// </summary>
    public class loginsession : ihttphandler
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/html";
    string strhtml = "";
    //讀取用戶(hù)名和密碼
    string strusername = context.request.form["txtusername"];
    string strpwd = context.request.form["txtpassword"];
    if (strpwd == "123456")
    {
    //登陸成功,設(shè)置對(duì)應(yīng)的鍵值對(duì)
    guid id = guid.newguid(); // 產(chǎn)生唯一的id
    sessionmgr.setkeyvalue(id, strusername);
    //id 保存在客戶(hù)端cookie中
    httpcookie logincookie = new httpcookie("logincookie");
    logincookie.value = id.tostring();
    logincookie.expires = datetime.now.adddays(7);
    context.response.cookies.add(logincookie);
    //跳轉(zhuǎn)到授權(quán)頁(yè)面
    context.response.redirect("authorizationpage.ashx");
    }
    else
    {
    //登陸失敗 , 加載登陸頁(yè)面
    strhtml = common_nvelocity.renderhtml("loginsession.html", null);
    context.response.write(strhtml);
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    c. templates文件夾下添加loginsession.html 登陸頁(yè)面
    <!doctype html>
    <html xm lns="http://www.w3.org/1999/xhtml">
    <head>
    <me ta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
    </head>
    <body>
    <form action="loginsession.ashx" method="post">
    <table>
    <tr>
    <td>登陸名</td>
    <td>
    <in put type="text" name="txtusername" /></td>
    </tr>
    <tr>
    <td>密碼</td>
    <td>
    <in put type="password" name="txtpassword" /></td>
    </tr>
    <tr>
    <td>
    <in put type="submit" name="login" value="登陸" /></td>
    <td></td>
    </tr>
    </table>
    </form>
    </body>
    </html>
    d. 添加authorizationpage.ashx頁(yè)面,只有登陸后的賬戶(hù)才有權(quán)限訪(fǎng)問(wèn)這個(gè)頁(yè)面
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    namespace httpnostatus.templates
    {
    /// <summary>
    /// authorizationpage 的摘要說(shuō)明
    /// </summary>
    public class authorizationpage : ihttphandler
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/html";
    //抓取客戶(hù)端 cookie的id值
    httpcookie logincookie = context.request.cookies["logincookie"];
    if (logincookie != null)
    {
    guid id = new guid(logincookie.value);
    // 讀取id對(duì)應(yīng)的value
    string strvalue = sessionmgr.getvalue(id);
    //輸出value值,并提示該賬號(hào)是已經(jīng)登陸的賬號(hào)
    context.response.write(strvalue + ",您已經(jīng)登陸本網(wǎng)站,有權(quán)限訪(fǎng)問(wèn)此頁(yè)面");
    }
    //如果cookie不存在,則直接跳轉(zhuǎn)到登頁(yè)面
    else
    {
    context.response.redirect("loginsession.ashx");
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    ------------------------------------------------------------gif 動(dòng)畫(huà)演示----------------------------------------------------------------
    11,上面的示例是也就是session原理。asp.net已經(jīng)內(nèi)置了session機(jī)制,下面我們直接用asp.net session實(shí)現(xiàn) 判斷用戶(hù)是否有登陸成功:
    (一般處理程序httphandler操作session, 要實(shí)現(xiàn)irequiressessionstate接口)
    分別添加頁(yè)面: loginsessionnew.ashx(登陸一般處理程序) , loginsessionnew.html(登陸模板), authorizationpagenew.ashx(登陸后才有權(quán)限訪(fǎng)問(wèn)的頁(yè)面)。
    a,loginsessionnew.ashx(登陸一般處理程序)
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    using system.web.sessionstate;
    namespace httpnostatus
    {
    /// <summary>
    /// loginsessionnew 的摘要說(shuō)明
    /// </summary>
    public class loginsessionnew : ihttphandler, irequiressessionstate
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/html";
    string strhtml = "";
    //讀取用戶(hù)名和密碼
    string strusername = context.request.form["txtusername"];
    string strpwd = context.request.form["txtpassword"];
    if (strpwd == "123456")
    {
    //登陸成功,直接保存session值
    context.session["loginusername"] = strusername;
    //跳轉(zhuǎn)到授權(quán)頁(yè)面
    context.response.redirect("authorizationpagenew.ashx");
    }
    else
    {
    //登陸失敗 , 加載登陸頁(yè)面
    strhtml = common_nvelocity.renderhtml("loginsessionnew.html", null);
    context.response.write(strhtml);
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    b,templates模板下新建loginsessionnew.html(登陸模板)
    <!doctype html>
    <html xm lns="http://www.w3.org/1999/xhtml">
    <head>
    <me ta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title></title>
    </head>
    <body>
    <form action="loginsessionnew.ashx" method="post">
    <table>
    <tr>
    <td>登陸名</td>
    <td>
    <in put type="text" name="txtusername" /></td>
    </tr>
    <tr>
    <td>密碼</td>
    <td>
    <in put type="password" name="txtpassword" /></td>
    </tr>
    <tr>
    <td>
    <in put type="submit" name="login" value="登陸" /></td>
    <td></td>
    </tr>
    </table>
    </form>
    </body>
    </html>
    c,authorizationpagenew.ashx(登陸后才有權(quán)限訪(fǎng)問(wèn)的頁(yè)面)
    using system;
    using system.collections.generic;
    using system.linq;
    using system.web;
    using system.web.sessionstate;
    namespace httpnostatus
    {
    /// <summary>
    /// authorizationpagenew 的摘要說(shuō)明
    /// </summary>
    public class authorizationpagenew : ihttphandler, irequiressessionstate
    {
    public void processrequest(httpcontext context)
    {
    context.response.contenttype = "text/plain";
    //檢查session是否存在
    ob ject obj = context.session["loginusername"];
    if (obj != null)
    {
    //session存在,讀取session值,并提示該賬號(hào)是已經(jīng)登陸的賬號(hào)
    context.response.write(obj.tostring() + ",您已經(jīng)登陸本網(wǎng)站,有權(quán)限訪(fǎng)問(wèn)此頁(yè)面");
    }
    //如果session不存在,則直接跳轉(zhuǎn)到登頁(yè)面
    else
    {
    context.response.redirect("loginsessionnew.ashx");
    }
    }
    public bool isreusable
    {
    get
    {
    return false;
    }
    }
    }
    }
    · asp.net內(nèi)置session機(jī)制同樣實(shí)現(xiàn)了對(duì)用戶(hù)是否登陸成功的判斷:loginsessionnew.ashx頁(yè)面headers中我們看到了cookie中多了asp.net_sessionid
    session機(jī)制在客戶(hù)端存放了asp.net_sessionid
    · 權(quán)限訪(fǎng)問(wèn)頁(yè)面,請(qǐng)求頭中讀取到了客戶(hù)端cookie中的asp.net_sessionid
    12, asp.net的session機(jī)制: session依賴(lài)于cookie , 借助cookie在客戶(hù)端瀏覽器中記錄了id, 在服務(wù)器端存儲(chǔ)了value值。
    13,session的值是放到了服務(wù)器內(nèi)存中,所以session存放小數(shù)據(jù)。
    session(會(huì)話(huà))有自動(dòng)銷(xiāo)毀機(jī)制,如果一段時(shí)間內(nèi)瀏覽器沒(méi)有和服務(wù)器交互,則session會(huì)定時(shí)自動(dòng)銷(xiāo)毀。
    登陸賬號(hào)后,一段時(shí)間內(nèi)如果不操作 系統(tǒng)就會(huì)自動(dòng)退出,這就是session自動(dòng)銷(xiāo)毀了。