我們的第一個案例,就來看看過去在ASP時代中稍具難度的使用者登入介面,說它稍具難度,是因為如果初次接觸ASP的程式設計師,絕對無法立刻撰寫出登入介面,但是對於稍稍熟悉ASP的程式設計師,登入介面可能就是家常便飯了。
3-1-1 過去ASP時代的做法
登入介面的設計可能因人而異,但是一般來說,ASP登入介面的基本流程,會以底下這樣的方式來進行:
此例是把A網頁和B網頁合併的例子,因此注意程式中第1到16行,就是我們在上圖中所謂的B網頁,後面17行到43行則是A網頁的部分(但記得此例中我們合併成一個網頁login.asp)。
網頁第一次執行的時候,由於Account=Request.form("UserAccount")和Password=Request.form("Password")都不會取得資料,因此後面的帳號密碼判斷式當然都不會成立,因此繼續執行,直到出現底下的網頁(透過17行到43行):
注意第22行的<form method="POST" action="login.asp">敘述,當使用者輸入密碼之後,由於action位置為login.asp,所以按下[提交]鈕之後,網頁會Submit到Login.asp自己,同時將表單<FORM>裡面的內容傳遞給Login.asp自己,這次執行網頁時,Account=Request.form("UserAccount")就會接收到使用者輸入的帳號和密碼等資料,因此:
Account=”Milk_Lin” 且 Password=”good” |
後面的判斷式就會成立,session("isLogin")被設為true,然後轉址(Response.redirect)到Process.asp,登入介面就這樣完成了。
至於Process.asp,我們則會加上下面這一段程式(第2行):
process.asp |
0001:<% 0002:if session("isLogin")<>true then response.redirect("login.asp") 0003:%> 0004:<html> 0005:<head> 0006:<title>被保護的網頁</title> 0007:</head> 0008:<body> 0009:<p>被保護的網頁</p> 0010:</body> 0011:</html> |
第2行中的if session("isLogin")<>true then response.redirect("login.asp")是防止不法使用者在還沒透過Login.asp登入的狀況下,直接輸入網址process.asp闖關的措施。如果session("isLogin")不為true,則表示該使用者還沒合法的透過Login.asp登入過,因此直接轉向到login.asp。
好了,這是過去ASP的做法,而ASP.NET呢?有何不同?
我們看一個效果完全一樣的ASP.NET網頁,我們先使用Visual Studio.NET,新增一個Web專案:
接著我們在專案中新增一個Web Form網頁,命名為login.aspx:
我們利用Visual Basic.NET工具箱,拖曳兩個Form控制項TextBox 和一個Web控制項Button,放置到Web Form網頁上:
曳到Web Form上面後,您可以在控制項上按下滑鼠右鍵,出現選單後按下『屬性』,將會出現屬性視窗,可設定該Web控制項的名稱:
請分別將該按鈕名稱設為Button_Submit,另外兩個TextBox設為txtAccount和txtPassword。
完成後應如下圖所示:
您可以先在上圖的編輯畫面中,切換到HTML碼部分:
0001:<%@ Page Language="vb" AutoEventWireup="false" Codebehind="login.aspx.vb" Inherits="AspxDemo.login"%> 0002:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 0003:<HTML> 0004: <HEAD> 0005: <title>login</title> 0006: <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.0"> 0007: <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> 0008: <meta name="vs_defaultClientScript" content="JavaScript"> 0009: <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> 0010: </HEAD> 0011: <body> 0012: <form id="Form1" method="post" runat="server"> 0013: <P><FONT face="新細明體">帳號: 0014: <asp:TextBox id="txtAccount" runat="server" DESIGNTIMEDRAGDROP="14"></asp:TextBox></FONT></P> 0015: <P><FONT face="新細明體">密碼: 0016: <asp:TextBox id="txtPassword" runat="server" TextMode="Password"></asp:TextBox> 0017: <asp:Button id="Button_Submit" runat="server" Text="提交"></asp:Button></FONT></P> 0018: </form> 0019: </body> 0020:</HTML> |
扣除<HEAD>之外,真正核心的HTML碼在第11行到19行的部分,您可以對比前面我們該才介紹過的ASP網頁,兩者有著幾個地方相當不同:
n 第12行<FORM>的部分加上了runat="server",變成<form id="Form1" method="post" runat="server">
n 第14行和第16行的<asp:TextBox …></asp:TextBox >是我們不曾看過的指令,該指令用來表示.NET Web Form上面的TextBox控制項
n 第17行的<asp:Button>也是我們不曾看過的,用來表示Button控制項
n 第1行多了:<%@ Page Language="vb" AutoEventWireup="false" Codebehind="login.aspx.vb" Inherits="AspxDemo.login"%>
上面這幾個不同之處,我們後面介紹Web Form時會仔細的說明,我們先切回Visual Basic.NET中的『設計』畫面,然後在按鈕上Double-Click,Visual Basic.NET會切換到程式設計畫面:
請在Button_Submit_Click中鍵入下列6-12行的程式:
0001: Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 0002: '在此加入要初始化頁面的使用者程式碼 0003: End Sub 0004: 0005: Private Sub Button_Submit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Submit.Click 0006: If Me.txtAccount.Text = "Milk_Lin" And Me.txtPassword.Text = "good" Then 0007: '設定 session 表示使用者已經 login 0008: Session("isLogin") = True 0009: 0010: '轉到實際被保護的網頁 0011: Response.Redirect("Process.aspx") 0012: End If 0013: End Sub |
這段程式幾乎和我們在ASP中設計的一模一樣,唯一最大的不同是什麼?沒錯,少了原本在login.asp的第5,6行,表單的Request.Form(“xxx”)接值動作。取而代之的是『Me.txtAccount.Text』和『Me.txtPassword.Text』。
撰寫ASP.NET的程式時,Web Form設計概念上相當接近VB的Event-Driven觀念,當使用者按下了網頁上的Button之後,會觸發Button_Submit_Click事件,進而執行上面第6到12行程式。
Web Form網頁,在VB.NET程式碼中可用『me』表示,而網頁上的Web控制項,則可表示成『Me.txtAccount』。使用者輸入的值,則可透過『Me.txtAccount.Text』來取得。因此透過第6行的判斷式,我們即可判斷使用者輸入的帳號密碼,若正確,一樣設定Session("isLogin")的值,並且轉址到Process.aspx。
我們用同樣的方式來新增Process.aspx網頁,然後在空白頁面上Double-Click,則會直接出現程式設計畫面:
我們輸入底下程式:
0001: Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 0002: '在此加入要初始化頁面的使用者程式碼 0003: If Session("isLogin") <> True Then Response.Redirect("login.aspx") 0004: End Sub |
第3行的程式和我們之前設計的ASP網頁一模一樣,有趣的是,剛才當我們在網域上直接Double-Click頁面的時候,程式設計畫面也會直接跳到『Page_Load』事件的程式碼中(和在VB裡面設計程式一模一樣)。
Page_Load裡面撰寫的程式代表著當網頁被載入的時候要執行的動作。當我們輸入好上面的程式後,接著我們直接按下選單上的『建置→建置方案』,然後輸入網址Process.aspx來執行該網頁。
執行結果如下,和我們之前的ASP網頁一模一樣:
回憶一下剛才的整個動作,您會發現ASP和ASP.NET在設計理念上相當不同,除了之前我們看到的<asp:TextBox>和runat="server"等怪怪的指令之外,ASP.NET的核心物件 ─ Web Form,則是整個.NET在Web應用程式設計上的重點。
Web Form有下列幾個特性:
n 一個Web Form即表示一張網頁,副檔名為.aspx,地位同等於過去的.asp。
n Web Form本身即是一個物件,類似VB程式設計中的表單物件Form。
n 每個Web Form上面都可以佈置一些Web控制項,這點也類似VB。
n Web Form和Web控制項,都擁有自己的事件、屬性、方法…。
n Web Form和程式碼可以分開(Code Behind)。
因此,從ASP到ASP.NET,在設計方式上有著不少的差異,整個流程變成下圖的方式,其中架構上完全一致,但最大的不同則是,對於程式設計師來說,ASP.NET『似乎』少了Submit這個動作(注意,我們說『似乎』是因為實際上這個動作依然存在,只是被Web Form包裝起來在背景完成了):
過去我們在程式中會在接收Submit動作的網頁上,撰寫Request.form(“物件ID”),來取得從上個網頁裡面的<FORM>表單中傳來的物件值,然後進行處理,而這個動作在ASP.NET中則被Web Form取代了(或說封裝起來)。我們在程式中,可以不需要理會複雜的表單傳值與接值的動作,而直接對資料進行操作。
這樣有什麼好處?對程式設計師來說,這樣可以專注在處理資料,而非傳值與接值這類的『虛工』上。在過去,ASP網頁上的傳接值這類工作,是由於網際網路的特性而產生,在程式設計上並非必要(並非必要的意思是,不會因為這樣的動作而產生任何的『效益或價值』,只是花時間),特別是倘若表單上的欄位相當多的時候(不像此例只有帳號和密碼),您就知道傳值和接值佔去了程式設計師多少時間,也容易造成了相當多的錯誤。
除此以外,Web Form的出現,為網際網路程式設計帶來底下幾個革命性的發展:
n 網頁和控制項的物件化:
您會發現,使用.NET開發Web應用程式非常接近Visual Basic開發Windows應用程式的方式,網頁和控制項被物件化,這樣程式設計師對於網頁和網頁上的控制項能夠更靈活的操作,撰寫程式也更加地容易。
您會發現,使用.NET開發Web應用程式非常接近Visual Basic開發Windows應用程式的方式,網頁和控制項被物件化,這樣程式設計師對於網頁和網頁上的控制項能夠更靈活的操作,撰寫程式也更加地容易。
n 可用Event-Driven的概念撰寫程式:
以前在網頁上寫程式,本質上是Script概念,沒有『按了哪個按鈕,或是點選哪個控制項,就做哪一件事情』這種Event-Driven概念。然而Event-Driven概念是Windows介面上行之有年的程式設計觀念,許多熟悉Windows應用程式設計的讀者就知道,Event-Driven觀念對於物件導向程式設計有著相當大的幫助,不僅加快程式設計速度,也容易維護程式,且提高程式的可讀性。
以前在網頁上寫程式,本質上是Script概念,沒有『按了哪個按鈕,或是點選哪個控制項,就做哪一件事情』這種Event-Driven概念。然而Event-Driven概念是Windows介面上行之有年的程式設計觀念,許多熟悉Windows應用程式設計的讀者就知道,Event-Driven觀念對於物件導向程式設計有著相當大的幫助,不僅加快程式設計速度,也容易維護程式,且提高程式的可讀性。
n 網頁和程式碼分離(Code Behind):
過去的ASP程式和網頁是連體嬰, HTML碼中有程式,程式碼中有HTML的情況隨處可見,加上ASP沒有Event-Driven觀念(在此種『連體』情況中也不可能達成Event-Driven),因此系統愈寫愈大之後,將會變得相當難以維護。而ASP.NET則靠著Code Behind達成網頁與程式碼分離的架構(雖然分離,但卻可以緊密合作)。不僅便於程式維護,此架構對於達成Event-Driven概念有著絕對的幫助。
過去的ASP程式和網頁是連體嬰, HTML碼中有程式,程式碼中有HTML的情況隨處可見,加上ASP沒有Event-Driven觀念(在此種『連體』情況中也不可能達成Event-Driven),因此系統愈寫愈大之後,將會變得相當難以維護。而ASP.NET則靠著Code Behind達成網頁與程式碼分離的架構(雖然分離,但卻可以緊密合作)。不僅便於程式維護,此架構對於達成Event-Driven概念有著絕對的幫助。
除了上述幾個重點之外,Web Form的出現,對於程式設計師來說,有效的縮短了開發時程,透過剛才提到的幾個重點,同樣的一支程式,在ASP可能需要兩三天時間撰寫,到了ASP.NET,可能只需要一個下午,這是筆者親身體驗,我們在後面的實例中會逐漸體驗到ASP.NET的強大。
透過這兩個實例比較之後,您應該不難發現,ASP.NET的設計架構,完全以Web Form為基底,然後透過操作Web Form,和Web Form上面的Web控制項(其實還有HTML控制項,容後在述)來達成需要的功能,因此我們會在後面詳細的介紹Web Form這個物件。
在這個段流程中,會涉及三個網頁的運作,我們先稱之為A網頁(Login.asp)、B網頁(Check.asp)和C網頁(Process.asp)。
這三個網頁的功能分別是:
n A網頁:提供讓使用者輸入帳號密碼的畫面,網頁中包含<FORM>。
n B網頁:使用者在A網頁輸入帳號密碼後,按下[登入]鈕,會從A網頁Submit到此網頁,在此網頁中透過Request.Form(“xxx”)接收A網頁傳來的值,然後進行檢查帳號密碼的工作。
n C網頁:包含使用者真正要執行的功能,亦包含檢查是否已經登入過的程式。
在上面這個流程中,很多程式設計師習慣把A網頁和B網頁合併,由於B網頁本身沒有介面,只有程式,因此將A網頁和B網頁合併的設計方式將較為簡便,在此種方式下,A網頁中的<FORM>架構依舊存在,而僅僅將B網頁中檢查帳號密碼的程式碼,移到A網頁上來執行(一般來說習慣放在A網頁最上方),形成A網頁自己(供使用者輸入帳號密碼後)Submit給自己(來判斷帳號密碼),若密碼正確再轉址到C網頁的情況。
C網頁則是需要被保護的網頁,是通過帳號密碼檢查才能看到的,該網頁除了原本要呈現的資料之外,還需包含一段檢查使用者是否已經登入過的程式。
過去ASP時代,實際程式約莫如下:
Login.asp |
0001:<% ‘底下這段原本應該是 check.asp ,很多程式設計師習慣和 login.asp合併在一起 0002:dim Account 0003:dim Password 0004: 0005:Account=Request.form("UserAccount") 0006:Password=Request.form("Password") 0007: 0008:'檢查帳號密碼程式 0009:if Account="Milk_Lin" and Password="good" then 0010: '設定 session 表示使用者已經 login 0011: session("isLogin")=true 0012: 0013: '轉到實際被保護的網頁 0014: response.redirect("Process.asp") 0015:end if 0016:%> 0017:<html> 0018:<head> 0019:<title>登入</title> 0020:</head> 0021:<body> 0022:<form method="POST" action="login.asp"> 0023: <table border="0" width="100%"> 0024: <tr> 0025: <td width="35%" align="right"></td> 0026: <td width="65%"></td> 0027: </tr> 0028: <tr> 0029: <td width="35%" align="right">帳號:</td> 0030: <td width="65%"><input type="text" name="UserAccount" size="20"></td> 0031: </tr> 0032: <tr> 0033: <td width="35%" align="right">密碼:</td> 0034: <td width="65%"><input type="password" name="password" size="20"></td> 0035: </tr> 0036: <tr> 0037: <td width="35%" align="right"></td> 0038: <td width="65%"><input type="submit" value="提交" name="B1"></td> 0039: </tr> 0040: </table> 0041:</form> 0042:</body> 0043:</html> |
沒有留言:
張貼留言