1、簡介
ASP.NET 是建立微軟.Net平臺上的WEB編程框架,可用於在服務器上生成功能強大、結構清晰的 Web 應用程序。有必要指出的是,由於 ASP.NET 基於.Net公共語言運行庫,因此在ASP.NET中可以利用整個.Net平臺的全部功能。
本文通過對ASP.NET開發中的頁面訪問控制問題的描述,涉及到了Request、Response、Session、Cookie這幾個對象,並對ASP.NET的工作方式、Session安全性、ASP頁面的生命週期做了較爲詳細的分析,以期提供一個ASP.NET開發快速入門的參考。
2、環境介紹及預備知識:
(1)、Windows XP Professional(Windows 2000、Windows 2003)+IIS
(2)、.Net Framework SDK 1.1(VS.Net 2003中自帶)
(3)、Visual Studio.Net 2003
請根據指南正確對IIS、VS.Net2003的加以安裝。使用Windows2003的用戶:在VS.Net 2003安裝好以後,請確認IIS 中的ASP.NET Web服務擴展是允許的,否則,您將無法使用ASP.NET。
本文假設您能使用C#在.Net平臺上做簡單的WinForm開發,並瞭解一定的HTML知識。
3、正文:
(1)、創建項目
啓動VS.NET 2003,選擇菜單命令新建->項目,彈出新建項目對話框,新建一個ASP.NET項目,本文裏使用的項目位置爲http://localhost/WebApplication1。
單擊確認,IDE將創建項目。在解決方案管理器中,我們可以發現IDE自動爲我們添加了一個名位WebForm1.aspx的頁面,請刪掉它,然後爲我們的項目添加兩個ASP.NET頁面,名稱分別爲SignIn.aspx、Protected.aspx。
查看SignIn.aspx的HTML代碼,在第一行你可以發現:
<%@ Page language="c#" Codebehind="SignIn.aspx.cs" AutoEventWireup="false" Inherits="WebApplication1.SignIn" %>
很有必要介紹一下Codebehind屬性和Inherits屬性。ASP.NET較之ASP一個最大的進步,就是實現了Web開發中HTML 代碼(負責呈現用戶界面)和程序代碼(負責實現業務邏輯)的分離。
ASP.NET頁面在運行時,首先時被解釋加以編譯成爲一個類,這個類繼承了Inherits屬性指定的預先編譯在程序集中的類,然後ASP.NET頁面編譯後生成的類被啓動來處理請求(注意:繼承的方式在ASP.NET2.0中已被取消,在2.0版本中,頁面連同程序代碼編譯成同一類)。
有了上面的敘述,我們可以知道Codebehind屬性指示了ASP.NET頁面所要繼承父類的代碼文件(提示:在ASPX頁面中添加了WEB控件後,然後打開頁面對應的代碼文件,查看父類代碼發生了那些變化,你將瞭解上述的ASP.NET頁面執行模式)。
(2)、完成代碼
查看SignIn.aspx的HTML代碼,在<FONT face="宋體">和</FONT>中插入如下非常常見的HTML代碼:
用戶名:<input name="username" type="text" size="16"><BR>
密碼:<input name="password" type="password" size="16"><BR>
<input type="submit" name="Submit" value="登入">
<input type="reset" name="Reset" value="重填">
然後切換到SigIn.aspx頁面的設計視圖,如下所示:
在登入按鈕上單擊鼠標右鍵,選擇“作爲服務器控件運行”,我們可以發現,登入按鈕的左上角多了一個帶邊框的綠色小三角,如此將兩個文本框也轉換爲服務器控件。
在ASP.NET中,服務器控件具有在服務器上可見並可編程的屬性。在上述操作中,我們通過將 HTML 元素轉換爲 HTML 服務器控件,將其公開爲可在服務器上編程的元素,這使得我們可以使用類似WinForm編程的方法來使用它們(提示:原有的HTML設計代碼可以按同樣的方法非常方便的重用到ASPX頁面中)。
雙擊登入按鈕,窗口切換到代碼文件SignIn.aspx.cs,你可以發現,IDE已經自動添加了該按鈕的事件處理函數,在該函數裏填入我們的程序代碼,如下:
Session的安全性和Cookie的安全性問題。
{
if(Text1.Value=="asp"&&Password1.Value=="net")
{
//填入Session,用作權限控制
Session["USERNAME"]="asp";
Session["AccessCount"] = 1;
//創建Cookie
System.Web.HttpCookie cookie=new HttpCookie("UserInfo");
cookie["UserName"] = "asp";
cookie["AccessCount"] = "1";
cookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(cookie);
//重定向到受保護頁面
Response.Redirect("Protected.aspx?Message=Parameter In Url");
}
}
上述程序代碼非常簡單,參看註釋可以快速理解。這裏值得提一下的是
我們知道,HTTP是無狀態的,但是Web 應用必須提供對某些跨請求狀態信息的維持,最常見的例子就是Web購物站點的購物車,因此所有的Web編程環境均提供了會話(Session)支持。在ASP.NET中,會話都是使用 120 位的 SessionID 字符串進行標識和跟蹤的,SessionID 值是使用保證唯一性和隨機性的算法(例如MD5算法)生成的,SessionID隨機性使得懷有惡意的用戶不能使用新的 SessionID 來計算現有會話的 SessionID。
在默認狀態下,SessionID是保存在客戶端的會話Cookie中的,假如客戶端禁用了Cookie,通過設置Web.config文件中的<sessionState>節點的屬性cookieless="true",你可以使得SessionID附在URL中。此時,在你的Session有效期內,假如你將你的SessionID(從URL中獲得)告訴你的朋友,他就可以使用你的SessionID從其它機器訪問同一個Web應用,他將和你同用一個的Session內容。這個情況說明了實現SessionID的唯一性和隨機性的原因所在。
SessionID由客戶端加以維護,保存在會話Cookie中或URL中。會話狀態則由服務端維護,ASP.NET 中有三種會話狀態的存儲模式。您可以在進程內、狀態服務器(StateServer)和 SQL Server 之間選擇。具體設置可以參考如下MSDN。
Session是面向用戶的,它不能跨 Web 應用程序邊界。所謂的在本地自建相同Session就可以訪問其他Web站點的說法是無稽之談。從應用的角度來看,Session是安全的,且無法僞造。但是這並不是說,使用Session的Web站點是絕對安全的!最後,值得指出的是,黑客攻擊中的會話劫持不是劫持Web應用中的Session,而是指網絡應用連接,例如HTTP會話、Telnet會話等。
Cookie是存放在本地的,而且不是加密存放的,所以,不要將重要的信息例如信用卡、密碼等資料存放在Cookie中。
請切換到Protected.aspx的代碼窗口查看Protected.aspx.cs文件,在Page_Load中輸入訪問控制代碼,完成後的代碼如下:
頁面的Page_Load事件在每次頁面Postback回服務端後均會觸發,值得注意的是,其Page_Load觸發時間要先於服務器控件事件(例如按鈕的單擊事件)。請看下面有關ASP.NET頁面的生命週期的簡要敘述如下,詳情請參見MSDN網站:
{
// 在此處放置用戶代碼以初始化頁面
/* 頁面的訪問控制代碼 */
string username = (string)Session["UserName"];
if(username==null)//Session中爲空
{
System.Web.HttpCookie cookie= Request.Cookies["UserInfo"];
if(cookie!=null)//Cookie不爲空
{
username=cookie["UserName"];
int AccessCount=int.Parse(cookie["AccessCount"]) + 1;
cookie["AccessCount"]=AccessCount.ToString();
cookie.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(cookie);
//填入Session信息
Session["UserName"] = username;
Session["AccessCount"] = AccessCount;
}
else//Cookie爲空
Response.Redirect("SignIn.aspx",true);
}
Response.Write("Welcome " + (string)Session["UserName"] + "<BR>");
Response.Write("You have visited for " + Session["AccessCount"].ToString() + " times" + "<BR>");
//下面的語句使用了Request.QueryString屬性取得附在URL中的參數
Response.Write("QueryString Message=" + Request.QueryString["Message"]);
}
1、Initialization-頁面初始化(初始化頁面及其控件);
2、Load View State-載入視圖狀態(載入視圖狀態到頁面,視圖狀態存儲了上次訪問後頁面的狀態信息,該事件僅在頁面Postback後觸發);
3、Load Postback Data-載入返回數據(載入控件被修改的屬性信息並予以更新,該事件也僅在頁面Postback後觸發);
4、Load-載入(即Page_Load事件,該事件發生表示頁面已經恢復到上次訪問時的狀態);
5、Raise Postback Event(那些屬性值發生了改變的服務器控件將觸發Postback事件,注意,該階段並未使用視圖狀態的信息,該事件也僅在頁面Postback後觸發)
6、Save View State(保存頁面的視圖狀態信息)、
7、Render(產生最終顯示給客戶端的HTML代碼)。
在這裏,我們在Protected.aspx頁面的Page_Load事件處理函數添加了頁面的訪問控制代碼,其先檢查Session,假如Session中找不到授權信息(這裏是Session[“UserName”]不爲空),再試圖從獲取客戶端的Cookie信息來判斷是否用戶已經登入過。
最後,簡單提一下刪除Cookie和清除Session的代碼,你可以在Protected.aspx頁面上添加一個按鈕,然後將它添加到這個按鈕的Click事件中,就可以實現註銷功能:
if(cookie!=null)//Cookie不爲空
{
cookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(cookie);
}
//清空Session信息
Session.Clear();
Session.Abandon();
在VS.NET中選擇生成->生成解決方案。然後在瀏覽器地址欄中輸入:
http://localhost/WebApplication1/Protected.aspx
頁面自動定向到SignIn.aspx,輸入asp、net後可以訪問受保護的Protected.aspx頁面,關閉瀏覽器後重新打開,然後再輸入上述的地址可以訪問Protected.aspx,這是讀取了Cookie信息的緣故。
4、小結。
本文通過操作Request、Response、Session、Cookie這幾個對象實現了簡單的Web頁面訪問控制,目的是希望藉此說明:ASP.NET的工作方式、Session安全性、ASP頁面的生命週期和幾個常用對象的使用,爲初學者澄清一些問題,提供一個入門的參考。
最後需要強調的是,使用ASP.NET做開發要注意充分可以利用整個.Net平臺的全部功能,比如ADO.NET在ASP.NET開發使用和在WinForm中並無任何差別。