2014年6月6日 星期五

ASP .NET加入會員驗證

MSDN


為 ASP.NET 網站加入登入驗證的功能



使用ASP.NET開發使用者驗證功能之一
http://www.dbworld.com.tw/member/article/010413.htm

作者: 恆逸資訊 張書源
 上一期的專欄 之中,我們簡單的了解ASP.NET的執行環境以及新增的控制項。ASP.NET雖然是一個全新的執行環境,但是對於已經在利用ASP開發網際網路應用程式的設計師而言,只是一個更方便的開發環境。
式,我們往往需要使用許多的技巧,讓Server端可以偵測到Client端的執行狀態。例如,如果我們希望Server端可以偵測到Client端程式執行的狀態,可以使用hidden的欄位來做紀錄:
< Input type="hidden" name="myState" id="myState" >
如此當form將資料submit回server的時候,我們就可以取得Client端的資料了。但是,在ASP.NET的程式之中,你再也不需要做這樣的動作了,因為由Sevrer端所產生的form將會自動的產生這樣的機制來maintain表單之中控制項的狀態。我們試著在aspx的程式之中加入一個form:
< form id="form1" runat="server" >

< /form >
這個form在程式執行之後,在Client端的瀏覽器之中會產生下面的HTML程式碼:
< form name="form1" method="post" action="form.aspx" id="form1" >
< input type="hidden" name="__VIEWSTATE" value="YTB6MTU5MzY5NTM0X19feA==21126b0b" / >
當Server端在執行的時候,除了產生Client端所需要的form控制項之外,還會自動的產生出來一個名為 "__VIEWSTATE" 的hidden 欄位,而這一個hidden欄位就是用來記錄Client端表單之中控制項的狀態的。神奇吧! Server端已經幫我們將這樣的機制產生出來了! 這一期的專欄,就是要為各位介紹ASP.NET之中Page以及Form的運作原理。
基本上,ASP.NET和ASP的網頁都是由IIS所執行的。ASP程式是直譯式的程式,IIS接收到Client端的HTTP Request 之後,將網頁取出,及時將Server端的Script編譯之後,再將結果和HTML程式碼一並透過HTPP Response回應到Client端的瀏覽器之中。這樣的執行方式,並不需要利用太多的伺服器端的資源,因為IIS一次只針對一個網頁之中的程式執行編譯的動作。但是相較於CGI ( Common Getway Interface ) 等編譯式的技術,ASP的程式的執行效能似乎總是差了一點。
ASP.NET的環境大大的改進了ASP的缺點。在ASP.NET的環境之中,每一個頁面 ( Page ) 都是一個物件。當使用者發出一個HTTP Request,要求開啟ASPX網頁的時候,ASP.NET引擎 (xspisapi.dll) 會先將ASPX的網頁編譯成一個DLL檔案。接著將此網頁當成一個類別 (Class),在記憶體中建立此物件的實體 (Object Instance),並進行初始化作業。最後才將執行結果回傳到Client端。

或許你能然會有這樣的懷疑:這跟之前的ASP程式有什麼不一樣呢?就讓我們更詳細的了解一下ASP.NET程式執行的過程。

實際上,當Client端從瀏覽器發出一個ASPX網頁的要求到Web Server,Web Server會先檢查輸出快取 ( output cache ) 中是否有此網頁,或者此網頁是否已被編譯成DLL了。所謂的輸出快取,是ASP.NET之中加快程式處理的一個機制。當一個網頁被執行過之後,除了產生DLL之外,同時會有一份物件的實體 ( instance ) 儲存在輸出快取之中,這樣第二個使用者就可以很快的啟動該網頁了。這種方式兼顧了JIT ( just-in-time compiler ) 的好處及編譯式語言的執行速度,所以使用ASP.NET對網際網路程式設計而言,勢必是未來的趨勢。
若找不到此網頁的output cache或編譯過的DLL,此時便啟動parser將此網頁parse 成原始程式碼 (source code),然後由編譯器 (Compiler) 將其編譯成DLL。此時DLL將會存放在codeGen目錄之下 ( WINNT\Microsoft.NET\Framework\v1.0.2204\CodeGen\ )。

然後,ASP.NET的Engine ( xspisapi.dll ) 便從編譯過的程式碼來產生Page物件,並適時地回存網頁與控制項的狀態資訊,處理所回傳的事件,然後將執行的結果傳回到Client端。

若Client端再次要求執行同一個網頁時,伺服器便再一次從輸出快取中找尋此網頁,或找尋編譯過的DLL。不過此時若伺服器找到了編譯過的DLL,便省略掉編譯的步驟,直接從編譯過的DLL建立物件。接著和上面的過程一樣,適時地回存網頁與控制項的狀態資訊,處理發生的事件,然後將執行的結果回傳到Client端 。
我們建立一個ASP.NET應用程式來測試一下運作的原理。首先,在IIS中新增加一個應用程式的虛擬目錄。然後新增一支程式,Login.aspx,加入下面的程式碼:
< form id="form1" runat="server" >
請輸入使用者帳號及密碼:
< Table >

< TR >
< td >使用者帳號:
< td >< asp:TextBox id="Name" runat="server"/ >
< TR >
< td >密碼:
< td >< asp:TextBox id="Password"
TextMode="Password"
 runat="server"/ >
< /Table >
< asp:Label id="Message" runat="server"/ >
< /form >
在這一個程式之中,我們使用了ASP.NET的TextBox控制項作為使用者輸入資料的介面。TextBox控制項之中有一個TextMode屬性,是讓設定當使用者輸入資料時TextBox所展現的外觀。TextMode屬性共有三種值可以做設定:
屬 性 值
說 明
Single
單行顯示 ( 預設值 )
Multiline
多行顯示
Password
當使用者輸入資料時,輸入的資料以星號 ( * ) 展現
程式執行的結果為一般使用者輸入帳號密碼的畫面﹔

這一個表單在Client端除了產生表單以及表單之中的控制項之外,也會一並產生一個hidden的欄位,這一個hidden的欄位名稱為 "_ViewState"。這一個欄位之中會記錄Client端使用者對form的使用狀態。接著,我們加入一個送出的按鈕。在ASP.NET 伺服器控制項之中,所有的Button到了Client端都變成了Submit按鈕,這是為什麼呢?
在上一期的專欄之中曾經為各位介紹在ASP.NET之中,伺服器端控制項在程式執行的時候會變成伺服器端的物件,我們所撰寫的程式都將在Server端被執行。但是使用者所輸入的資料在Client端的瀏覽器之中,因此,需要將Client端所輸入的資料傳遞到Server端做處理。所以當Server端在產生Client端所需要的form的時候,會同時加入form控制項中method及action屬性的設定:
< form name="form1" method="post" action="Login.aspx" id="form1" >
你會發現action的屬性值是指向同一頁,這表示Client端控制項之中使用者所輸入的資料,將可以透過這一個機制送到Server端執行,這一個動作稱之為PostBack。當程式之中加入一個按鈕之後,Server端會自動的將這一個按鈕變成一個Submit按鈕。使用者按下按鈕之後,網頁就可以執行PostBack的動作,將Client端的資料回傳到Server端。我們在form之中加入一個按鈕:
< asp:button Text="送出" runat="server"/ >
Server端網頁執行的時候會將網頁編譯成Page物件,而在程式之中我們可以使用Page物件的IsPostBack屬性來判斷網頁是否為第一次載入Client端。所以我們可以加入下面的程式來判斷使用者輸入的資料:
< script language="C#" runat="server" >
void Page_Load(object sender,EventArgs e){
string strMessage="";
if (Page.IsPostBack){
if (Name.Text == "") strMessage+=" 請輸入帳號資料!!";
if (Password.Text == "") strMessage+=" 密碼不可為空白!!";
if (strMessage != "") Message.Text=strMessage;
else if (Password.Text != "password") Message.Text="密碼輸入錯誤!!";
else Message.Text = "使用者登入成功!!";
}
}
< /script >
當每次網頁載入到Client端的時候,都會觸發Page物件的Load事件。所以在 Page_Load 方法之中我們需要判斷這一個網頁是否處於PostBack的狀態。執行之後會有以下的結果:

  • 使用者如果沒有輸入任何的資料:

  • 使用者輸入密碼為 "password":
而事實上,並不是每一個控制項狀態改變的時候,都會執行PostBack的動作。像是CheckBox,ListControl,以及TextBox的控制項都必須要設定AutoPostBack的屬性為true之後,使用者對控制項的改變才會經由PostBack的動作傳回Server端。
在ASP.NET環境之中,你還可以使用一種新的控制項來驗證欄位的資料 - 驗證控制項 ( Validation Controls ) 。驗證控制項分為下面幾種:
  • 必要輸入欄位驗證控制項 ( RequiredFieldValidator Control )
  • 比較限制欄位驗證控制項 ( CompareValidator Control )
  • 範圍限制欄位驗證控制項 ( RangeValidator Control )
  • 特殊限制欄位驗證控制項 ( RegularExpressionValidator Control )
  • 自訂欄位限制欄位驗證控制項 ( CustomValidator Control )
  • 匯集驗證訊息控制項 ( ValidationSummary Control )
在這一個例子之中,我們可以加入必要輸入欄位驗證控制項 ( RequiredFieldValidator Control ) 來確保使用者必須輸入帳號名稱及密碼。我們先在程式之中加入一個必要輸入欄位驗證控制項:
< asp:RequiredFieldValidator id="rfv1" runat="server"
ControlToValidate="Name" Text="請輸入使用者帳號!!"
/ >
在必要輸入欄位驗證控制項之中,有兩個必須要設定的屬性:
  • ControlToValidate:所要驗證的控制項的id。
  • Text﹔錯誤訊息。
所以上面的程式會讓必要輸入欄位驗證控制項檢查輸入帳號的欄位:


所以密碼的欄位也可以如法炮製:
< asp:RequiredFieldValidator id="rfv1" runat="server"
ControlToValidate="Name" Text="請輸入使用者帳號!!"
/ >
< asp:RequiredFieldValidator id="rfv2" runat="server"
ControlToValidate="Password" Text="請輸入使用者密碼!!"
/ >
這樣一來就可以拿掉驗證的式子了。最後,加入一個按鈕清除狀態的資料,使用者驗證的表格就完成了。參考的程式碼如下:
< HTML >
< HEAD >
< META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0" >

< title >PC2000五月專欄< /title >

< script language="C#" runat="server" >
void Page_Load(object sender,EventArgs e){
string strMessage="";
if (Page.IsPostBack){
if (Password.Text != "password") Message.Text="密碼輸入錯誤!!";
else Message.Text = "使用者登入成功!!";
}
}

< /script >
< /HEAD >
< BODY >
< center >
< h1 >恆逸資訊學員管理系統< /H1 >
< hr >

< form id="form1" runat="server" >
請輸入使用者帳號及密碼:
< Table >
< TR >
< td >使用者帳號:
< td > < asp:TextBox id="Name" runat="server"/ >
< TR >
< td >密碼:
< td >< asp:TextBox id="Password"
TextMode="Password"
runat="server"/ >
< TR >
< td > < td >< asp:button Text="送出" runat="server"/ >
< input type="reset" runat="server"/ >
< /Table >
< asp:Label id="Message" runat="server"/ >
< asp:RequiredFieldValidator id="rfv1" runat="server"
ControlToValidate="Name" Text="請輸入使用者帳號!!"
/ >
< asp:RequiredFieldValidator id="rfv2" runat="server"
ControlToValidate="Password" Text="請輸入使用者密碼!!"
/ >
< /form >
< /center >
< /BODY >
< /HTML >
是不是很簡單呢?? 事實上,這只是使用者驗證的第一步。在ASP的程式之中,我們可以使用資料庫或是IIS來做驗證。ASP.NET的環境之中除了一樣可以使用資料庫驗證之外,還可以自訂一些IIS驗證的資訊,這一些自訂的IIS設定值放在專案之中的一個設定檔,Config.Web之中。在下一期專欄之中,我將從這一個例子出發,和各位討論如何讓這一個表單跟上述的兩種驗證方式結合,以及Config.Web設定檔的一些設定參數的意義。

沒有留言: