書(shū)名: 計(jì)算機(jī)協(xié)同學(xué)習(xí)技術(shù)及應(yīng)用作者名: 仇芒仙 李海明著本章字?jǐn)?shù): 755字更新時(shí)間: 2018-12-29 22:06:49
第1章 ASP.NET應(yīng)用開(kāi)發(fā)概覽
ASP.NET是下一代的活動(dòng)服務(wù)頁(yè)面框架。ASP.NET是.NET框架中的固有部分,利用ASP.NET提供的服務(wù),可以開(kāi)發(fā)出新一代的Web應(yīng)用。
本章將介紹下面內(nèi)容:
● HTML、ASP應(yīng)用和ASP.NET應(yīng)用的比較
● ASP.NET應(yīng)用開(kāi)發(fā)前的準(zhǔn)備工作
● 用Visual Studio.NET開(kāi)發(fā)第一個(gè)ASP.NET應(yīng)用
1.1 HTML、ASP和ASP.NET
在開(kāi)始ASP.NET介紹之前,我們先簡(jiǎn)單追述一下Web應(yīng)用開(kāi)發(fā)的歷史。最初的Web應(yīng)用是基于靜態(tài)的HTML文本。利用一些預(yù)定義的標(biāo)志,諸如FrontPage等工具就可以產(chǎn)生這樣的文本。HTML較好地解決了信息的顯示問(wèn)題,但這些信息和控制顯示格式的標(biāo)志在服務(wù)器端是編碼存儲(chǔ)的,這時(shí)應(yīng)用程序的執(zhí)行模式為:客戶(hù)請(qǐng)求某一個(gè)靜態(tài)HTML文本,服務(wù)器返回該文本。下面是一個(gè)典型的HTML文本的示例:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <meta http-equiv="Content-Language" content="zh-cn"> <title>主頁(yè)</title> <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> <meta name="ProgId" content="FrontPage.Editor.Document"> <meta name="Microsoft Theme" content="strtedge 011, default"> <meta name="Microsoft Border" content="tl, default"> </head> <body> <p><font size="4">歡迎光顧我的站點(diǎn)!</font></p> <p>主頁(yè)是讓到訪(fǎng)者了解本站點(diǎn)主旨的最佳場(chǎng)所。主頁(yè)向到訪(fǎng)者展示了您站點(diǎn)的風(fēng)格。 </p> <p> </p> <p>此網(wǎng)頁(yè)最近更新于<!--webbot bot="Timestamp" s-type="REGENERATED" s-format= "%y年%m月%d日" -->。</p> <p align="right"><a ><img src="images/frontpag.gif" border="0" width="88" height="44"></a></p> </body> </html> 上述HTML文本是用FrontPage工具創(chuàng)建的。文本的結(jié)構(gòu)大致如下: <html> <head> <title>主頁(yè)</title> </head> <body> </body> </html>
標(biāo)志<html></html>之間的是HTML文件的內(nèi)容。<html>標(biāo)志指示上述文件為一個(gè)HTML文檔,<title></title>標(biāo)志指示文本的標(biāo)題,<bod></body>之間的是HTML文件的正文。
提示
IE瀏覽器能夠解釋結(jié)構(gòu)不完整的HTML文件,所以上述文件中去掉第一行的<html>和最后一行的</html>,也能在瀏覽器中正確地顯示。但建議讀者在設(shè)計(jì)HTML文件時(shí),保證其結(jié)構(gòu)的完整性,因?yàn)檫@樣可以增強(qiáng)代碼的可讀性。
觀察上述HTML文件,會(huì)發(fā)現(xiàn)每個(gè)標(biāo)志都有若干屬性,例如,<font size="4">中的font標(biāo)志有size屬性,表示size字體為4號(hào)字。格式信息正是通過(guò)標(biāo)志和標(biāo)志屬性設(shè)置的。在IE瀏覽器下,上述HTML文件的瀏覽效果如圖1-1所示。

圖1-1 瀏覽器下查看HTML
從瀏覽效果來(lái)看,HTML文件提供了比較豐富的界面元素。其外觀效果遠(yuǎn)非文本效果可以比擬。但HTML的內(nèi)容都是靜態(tài)準(zhǔn)備好的,如果打算制作網(wǎng)頁(yè)反映股票信息,實(shí)現(xiàn)這樣的任務(wù)幾乎是不可能的,因?yàn)楣善毙畔r(shí)刻在變,而為了反映這種變化,就必須時(shí)刻重新編寫(xiě)HTML。為了解決動(dòng)態(tài)信息的發(fā)布問(wèn)題,活動(dòng)服務(wù)頁(yè)面ASP誕生了。
活動(dòng)服務(wù)頁(yè)面在HTML的基礎(chǔ)上引入了一些額外的標(biāo)志,這些標(biāo)志指示服務(wù)器在返回用戶(hù)請(qǐng)求的頁(yè)面之前進(jìn)行進(jìn)一步的處理。對(duì)客戶(hù)而言,它最終仍然會(huì)得到一個(gè)HTML文件,但該HTML文件是在服務(wù)器端動(dòng)態(tài)生成的。對(duì)服務(wù)器而言,它要根據(jù)用戶(hù)的請(qǐng)求把活動(dòng)頁(yè)面中的內(nèi)容翻譯成HTML代碼,開(kāi)發(fā)ASP應(yīng)用工具有InterDev等。下面是一個(gè)ASP文件(demo.asp)的示例:
<html> <head> <title>演示ASP</title> </head> <body> <% Response.Write("Hello," +Request("user")) %> </body> </html>
ASP文件跟HTML文件類(lèi)似,也可以包括<html>等標(biāo)志,但其中有一種特殊的<% %>標(biāo)志,該標(biāo)志指示期間的代碼要在服務(wù)器上執(zhí)行,執(zhí)行的結(jié)果將作為HTML文件的一部分返回給客戶(hù)。
其中Response對(duì)象是ASP內(nèi)置的對(duì)象之一,表示對(duì)用戶(hù)的回應(yīng),Response.Write方法用以向客戶(hù)端寫(xiě)入回應(yīng)消息。Request對(duì)象是另一個(gè)內(nèi)置對(duì)象,表示用戶(hù)的請(qǐng)求,例如通過(guò)該對(duì)象可以獲得用戶(hù)獲取的Form表單(如果通過(guò)Post方法提交)或者通過(guò)Get方法提交請(qǐng)求時(shí)的參數(shù)。代碼Request(“user”)表示獲得Get參數(shù)列表中的user參數(shù)。
下面的命令用以請(qǐng)求demo.asp,并指定user參數(shù)為“曉華”:
http://localhost/demo.asp?user=曉華
瀏覽器的顯示結(jié)果如圖1-2所示。

圖1-2 客戶(hù)端瀏覽器顯示請(qǐng)求響應(yīng)
提示
響應(yīng)返回的是HTML文檔,該文檔是由服務(wù)器動(dòng)態(tài)構(gòu)造的,其內(nèi)容如下:
<html> <head> <title>演示ASP</title> </head> <body> Hello,曉華 </body> </html>
活動(dòng)服務(wù)頁(yè)面能根據(jù)用戶(hù)的請(qǐng)求動(dòng)態(tài)產(chǎn)生HTML文件,這是相對(duì)于靜態(tài)HTML應(yīng)用的一大進(jìn)步。它即充分利用了HTML強(qiáng)大的顯示功能,又充分表達(dá)了動(dòng)態(tài)的信息,但ASP仍存在下面的不足:
● 界面和代碼沒(méi)有分開(kāi)
ASP應(yīng)用中的代碼包含在界面元素之間,這樣導(dǎo)致程序結(jié)構(gòu)不清晰,增加了維護(hù)代碼的難度。
● 解釋性的腳本語(yǔ)言
ASP中所用到的編程語(yǔ)言是解釋性的腳本語(yǔ)言,如VBScript或JScript。每次服務(wù)器響應(yīng)客戶(hù)的請(qǐng)求,都要調(diào)用某種語(yǔ)言引擎解釋腳本代碼,這樣降低了程序的執(zhí)行效率,會(huì)影響對(duì)客戶(hù)的響應(yīng)。
ASP.NET克服了ASP上述不足,利用Visual Studio.NET集成開(kāi)發(fā)工具,開(kāi)發(fā)人員甚至可以像設(shè)計(jì)Visual Basic程序那樣開(kāi)發(fā)ASP.NET應(yīng)用。
通過(guò)一種所謂的隱藏代碼技術(shù),徹底實(shí)現(xiàn)了界面和代碼分離。下面是一個(gè)利用Visual Studio.NET產(chǎn)生的空白頁(yè)面示例,它由兩部分組成,界面和代碼,兩部分都被保存為一個(gè)獨(dú)立的文件。界面文件以.aspx為后綴,下面是其內(nèi)容:
[Visual Basic] <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="CH1.WebForm1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>WebForm1</title> <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.0"> <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </head> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> </form> </body> </html> [C#] <%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="CSCH1.WebForm1" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > <HTML> <HEAD> <title>WebForm1</title> <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0"> <meta name="CODE_LANGUAGE" Content="C#"> <meta name="vs_defaultClientScript" content="JavaScript"> <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> 98 </form> </body> </HTML>
首先注意.aspx文件的第一行,該行是一個(gè)頁(yè)面Page指令。Language指示頁(yè)面的編程語(yǔ)言,可以為C#、Visual Basic或任意一種.NET平臺(tái)下的編程語(yǔ)言。Codebihand屬性指示于界面元素關(guān)聯(lián)的代碼文件,Inherits屬性用以指示當(dāng)前頁(yè)面的父類(lèi),AutoEventWireup屬性指示是否在頁(yè)面加載時(shí),自動(dòng)調(diào)用頁(yè)面中定義的Page_Init和Page_Load方法。
提示
一個(gè).aspx文件實(shí)際上隱含定義一個(gè)Page派生類(lèi),它們直接或間接地從Page類(lèi)派生。
我們?cè)倏纯创a隱藏文件,隱藏代碼定義了一個(gè)頁(yè)面類(lèi),它直接從System.Web.UI.Page派生。下面是其具體內(nèi)容:
[Visual Basic] Public Class WebForm1 Inherits System.Web.UI.Page #Region"Web 窗體設(shè)計(jì)器生成的代碼 " '該調(diào)用是 Web 窗體設(shè)計(jì)器所必需的。 <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() End Sub Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init 'CODEGEN: 此方法調(diào)用是 Web 窗體設(shè)計(jì)器所必需的。 '不要使用代碼編輯器修改它。 InitializeComponent() End Sub #End Region Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '在此處放置初始化頁(yè)的用戶(hù)代碼 End Sub End Class [C#] using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace CSCH1 { /// <summary> ///WebForm1 的摘要說(shuō)明。 /// </summary> public class WebForm1 : System.Web.UI.Page { private void Page_Load(object sender, System.EventArgs e) { // 在此處放置用戶(hù)代碼以初始化頁(yè)面 //Request.Form } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // //CODEGEN:該調(diào)用是 ASP.NET Web 窗體設(shè)計(jì)器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 設(shè)計(jì)器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內(nèi)容。 /// </summary> private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } }
如果讀者有Visual Basic.NET或C#的編程經(jīng)驗(yàn),讀懂上述代碼應(yīng)該沒(méi)有任何問(wèn)題。上述代碼的主題是重載父類(lèi)的OnInit方法和為L(zhǎng)oad事件添加處理代碼。通過(guò)下面的方法掛鉤事件:
[Visual Basic]
方法后跟Handlers關(guān)鍵字指示處理的事件,上例中的Page_Load方法即是一例。
提示
為了保證該方法正確的處理事件,必須保證該方法的簽名符合事件類(lèi)型。在Visual Basic中,事件類(lèi)型用委托來(lái)定義,例如:Web窗體的Load事件由下面的委托定義:
<Serializable> Public Delegate Sub EventHandler( _ ByVal sender As Object, _ ByVal e As EventArgs _ )
所以Page_Load方法的的第一個(gè)參數(shù)必須為Object類(lèi)型,第二個(gè)參數(shù)必須為EventArgs類(lèi)型,并且該方法無(wú)返回值(為過(guò)程)。
[C#]
把委托實(shí)例跟事件直接掛鉤。把本例中掛鉤事件的處理代碼重寫(xiě)如下:
this.Load += new System.EventHandler(this.Page_Load);
代碼右邊生成一個(gè)EventHandler委托實(shí)例。this.Page_Load方法的簽名必須符合該委托。代碼左邊是要處理的事件(實(shí)際上是一個(gè)委托變量),運(yùn)算符+=將左邊的委托實(shí)例和右邊的事件關(guān)聯(lián)起來(lái)。
提示
C#中this關(guān)鍵字表示對(duì)象自身,而Visual Basic中對(duì)應(yīng)的關(guān)鍵字是Me。
從上面的例子可以看出,ASP.NET真正實(shí)現(xiàn)了將代碼和內(nèi)容分開(kāi),已有的開(kāi)發(fā)其他.NET應(yīng)用的經(jīng)驗(yàn)可以直接用到ASP.NET應(yīng)用開(kāi)發(fā)中來(lái)。
需要指出,代碼隱藏文件并不是必須的,但利用它,可以將代碼和界面分離,因此是一種值得推薦的做法。另外一種替換的編程方式跟傳統(tǒng)的ASP應(yīng)用開(kāi)發(fā)類(lèi)似,即把所有的代碼和一些HTML標(biāo)志元素混在一起,并保存為一個(gè)單獨(dú)的文件(這樣的文件仍以.aspx文為后綴)。下面是單文件的窗體示例:
[Visual Basic] <html> <!-- 演示ASP.NET !--> <Script language="vb" runat="server"> public sub Page_Load(sender as Object, e as EventArgs) if not IsPostBack then Message.Text="Hello,World!" end if end sub </Script> <body> <h4><font face="verdana"> <asp:Label id="Message" runat="server"/> </font></h4> </body> </html> [C#] <html> <!-- 演示ASP.NET !--> <Script language="C#" runat="server"> public void Page_Load(Object sender, EventArgs e) { if(!IsPostBack) Message.Text="Hello,World!" ; } </Script> <body> <h4><font face="verdana"> <asp:Label id="Message" runat="server"/> </font></h4> </body> </html>
觀察上述文件,讀者會(huì)注意到單文件的ASP.NET窗體跟以前的ASP非常類(lèi)似,但仔細(xì)觀察,你會(huì)發(fā)現(xiàn)Label控件前有asp命名控件限制,它表示Label為Web控件。ASP.NET頁(yè)面引擎會(huì)根據(jù)Label控件的相關(guān)屬性(例如Text屬性)將它轉(zhuǎn)化為適當(dāng)?shù)腍TML代碼。runat="server"表示該控件在服務(wù)端運(yùn)行,也就是說(shuō)由服務(wù)器將其翻譯成HTML代碼。
除了上述兩點(diǎn)顯而易見(jiàn)的好處之外,ASP.NET還增加了許多具有吸引力的新功能,大部分功能都是.NET框架特性的一部分。下面是列表是這些新功能的不完全清單:
● 狀態(tài)視圖
ASP.NET提供狀態(tài)視圖在頁(yè)面的一個(gè)往返行程之間保存頁(yè)面的狀態(tài)。這就為開(kāi)發(fā)人員提供了更多的選擇:他們就可以使用傳統(tǒng)的Session或Application對(duì)象保存狀態(tài)或數(shù)據(jù)庫(kù)在服務(wù)端保持頁(yè)面狀態(tài),還可以狀態(tài)視圖在客戶(hù)端保存頁(yè)面狀態(tài)。狀態(tài)視圖通過(guò)隱藏域?qū)崿F(xiàn),因此除了往返行程的流量開(kāi)銷(xiāo)外幾乎沒(méi)有其他限制。
● 一致的事件模型
處理Web窗體的事件就跟處理傳統(tǒng)的Window窗體的事件類(lèi)似。經(jīng)過(guò)ASP.NET框架的精心包裝,客戶(hù)端(遠(yuǎn)程的瀏覽器)引發(fā)的事件可以透明傳遞到服務(wù)器,開(kāi)發(fā)人員像處理本地事件一樣處理這些事件。
Web窗體中的事件處理也是基于委托的,委托相當(dāng)于一個(gè)智能的函數(shù)指針。Web窗體的事件和本機(jī)窗口事件都表示為委托,并通過(guò)實(shí)例化委托將事件和事件處理代碼掛鉤。
● 基于XML文件的配置
可以為任何ASP.NET應(yīng)用編寫(xiě)一個(gè)XML文件格式的配置文件。利用配置文件,可以方便地設(shè)置ASP.NET應(yīng)用的安全性、進(jìn)程模型、語(yǔ)言編碼等。
開(kāi)發(fā)人員可以隨時(shí)添加或修改配置設(shè)置,但同時(shí),ASP.NET框架可以保證這種修改對(duì)運(yùn)作著的Web應(yīng)用程序和服務(wù)器產(chǎn)生最小的影響。
● 靈活地使用任何組件
因?yàn)锳SP.NET應(yīng)用最終被編譯成程序集,所以可以使用.NET框架類(lèi)庫(kù)中的任何組件。而程序員要做的只是添加對(duì)程序集的引用和引入命名空間。
以往的COM組件也可以繼續(xù)使用,但在使用之前,它們通過(guò).NET框架提供的互操作服務(wù)轉(zhuǎn)化為互操作程序集。
提示
在使用COM組件的背后,會(huì)發(fā)生很多事情,但集成開(kāi)發(fā)工具使得程序員可以通過(guò)添加引用的方式使用任何COM對(duì)象。
利用集成開(kāi)發(fā)環(huán)境,可以向ASP.NETWeb應(yīng)用中添加各種編程元素,例如窗體、類(lèi)、樣式等,如圖1-3所示。

圖1-3 集成開(kāi)發(fā)環(huán)境下向Web應(yīng)用中添加各種編程元素
● 支持Web服務(wù)
Web服務(wù)是基于一系列開(kāi)發(fā)標(biāo)準(zhǔn)之上的可通過(guò)Web調(diào)用的功能。它把整個(gè)網(wǎng)絡(luò)變成一個(gè)可編程的計(jì)算平臺(tái)。ASP.NET支持創(chuàng)建基于XML的Web服務(wù),并可以方便地使用Web服務(wù)。
1.2 開(kāi)發(fā)之前
在開(kāi)始我們的第一個(gè)ASP.NET應(yīng)用之前,筆者還希望讀者了解下面一些問(wèn)題。
第一個(gè)問(wèn)題是:選用何種編程語(yǔ)言。跟前期的ASP不同,現(xiàn)在的ASP.NET應(yīng)用可以用任何適用于.NET框架的編程語(yǔ)言。這樣讀者可選擇的范圍就擴(kuò)大了,例如C#、Visual Basic、托管C++、JScript等。本質(zhì)上,這些語(yǔ)言只有語(yǔ)法上的差異,因?yàn)樗鼈冏罱K都編譯成微軟中間代碼,所以,選用何種語(yǔ)言完全取決于個(gè)人的愛(ài)好。如果讀者是一位新手,建議使用C#語(yǔ)言,該語(yǔ)言是.NET平臺(tái)下的標(biāo)準(zhǔn)編程語(yǔ)言。而對(duì)以往的VBScript程序員可能會(huì)選擇Visual Basic,因?yàn)橐酝慕?jīng)驗(yàn)可以縮短他們了解Visual Basic.NET語(yǔ)言所花的時(shí)間。
如果用集成開(kāi)發(fā)環(huán)境開(kāi)發(fā)ASP.NET應(yīng)用,那么整個(gè)項(xiàng)目中的所有隱藏代碼只能采取同一種編程語(yǔ)言。因?yàn)橥粋€(gè)項(xiàng)目中的所有這些文件要被同一個(gè)編譯器編譯成一個(gè)程序集。
提示
配置文件中用下面的代碼來(lái)規(guī)定默認(rèn)的編程語(yǔ)言。
<compilation defaultLanguage="vb" />
另外,每個(gè)頁(yè)面也可以用Page指令設(shè)定編程語(yǔ)言。例如:
<%@ Page Language="vb" "%>
如果不指定Page的Language屬性,那么將采用在配置文件中的默認(rèn)設(shè)置。
提示
利用Page指令的Language屬性,可以單獨(dú)設(shè)置.aspx文件中的編程語(yǔ)言,同一個(gè)頁(yè)面只能設(shè)置成一種編程語(yǔ)言,如下面的代碼:
<%@ Page Language="cs" AutoEventWireup="false" %> <HTML> <body MS_POSITIONING="GridLayout"> <form id="Form1" method="post" runat="server"> <FONT face="宋體"> <asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 172px; POSITION: absolute; TOP: 90px" runat="server" Width="256px" Height="53px">Label</asp:Label></FONT> </form> <Script language=vb runat="server"id="Script1"> Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '在此處放置初始化頁(yè)的用戶(hù)代碼 if not IsPostBack then Label1.Text="Hello" end if End Sub </Script> </body> </HTML>
把上述文件保存到wwwroot目錄下的demo2.aspx文件下,然后啟動(dòng)瀏覽器執(zhí)行http://localhost/demo2.aspx,執(zhí)行結(jié)果如圖1-4所示。

圖1-4 執(zhí)行結(jié)果
為了解決這個(gè)問(wèn)題,請(qǐng)把第一行中的代碼修改為:
<%@ Page Language="vb" AutoEventWireup="false" %>
第二個(gè)問(wèn)題是:選用何種編程工具。目前開(kāi)發(fā)ASP.NET應(yīng)用最好的工具就是Visual Studio.NET,它提供了Web窗體設(shè)計(jì)器,并支持隱藏代碼模型。利用它可以快速地開(kāi)發(fā)出ASP.NET應(yīng)用,而不用關(guān)心實(shí)現(xiàn)的細(xì)節(jié),但目前Visual Studio.NET對(duì)單文件的.aspx撰寫(xiě)提供的支持還非常有限。例如,不支持.aspx文件中的代碼高亮度顯示,沒(méi)有智能提示等。
第三個(gè)問(wèn)題是:關(guān)于學(xué)習(xí)ASP.NET應(yīng)用開(kāi)發(fā)的最佳方法是什么。一般而言,按照本書(shū)安排的學(xué)習(xí)順序,讀者將能完全掌握ASP.NET應(yīng)用開(kāi)發(fā)技術(shù),但為了獲得更好的學(xué)習(xí)效果,下面的一些建議可能是有益的。
● 熟悉選用的編程語(yǔ)言
本書(shū)的目的不是向大家介紹編程語(yǔ)言。如果讀者決定用Visual Basic或C#等語(yǔ)言開(kāi)發(fā)ASP.NET應(yīng)用,那么就要花一些時(shí)間來(lái)熟悉這些語(yǔ)言,主要是屬性常見(jiàn)的語(yǔ)句,例如類(lèi)型定義、變量聲明、循環(huán)、分支等。讀者可以參考本社已出版的《Visual Basic.NET編程指南》一書(shū)和《C#編程指南》中的第2章,從中獲得有關(guān)編程語(yǔ)言本身的知識(shí)。
● 熟悉常見(jiàn).NET框架類(lèi)庫(kù)
.NET框架類(lèi)庫(kù)為所有的.NET應(yīng)用共有,ASP.NET應(yīng)用也不例外。了解常用的.NET框架類(lèi),例如集合、數(shù)組、字符串等,無(wú)疑可以提高ASP.NET應(yīng)用開(kāi)發(fā)水平,并能更好地理解本書(shū)中所有的范例。
1.3 第一個(gè)ASP.NET應(yīng)用
將要開(kāi)發(fā)的ASP.NET應(yīng)用所演示的技術(shù)在開(kāi)發(fā)實(shí)際站點(diǎn)時(shí)經(jīng)常用到——用戶(hù)登錄,并驗(yàn)證用戶(hù)的身份,以確保只有特定的用戶(hù)才能訪(fǎng)問(wèn)本應(yīng)用(本例設(shè)定為只有曉華輸入正確的口令“1234”時(shí),才可訪(fǎng)問(wèn)本應(yīng)用)。下面將詳細(xì)描述該應(yīng)用的實(shí)現(xiàn)步驟。
1.3.1 第一步:新建一個(gè)ASP.NET應(yīng)用
將其位置設(shè)定為:
[Visual Basic] http://localhost/DEMO/CH1 [C#] http://localhost/DEMOCS/CH1
執(zhí)行結(jié)果如圖1-5所示。

圖1-5 新建ASP.NET應(yīng)用
1.3.2 第二步:檢查生成的文件
請(qǐng)切換到項(xiàng)目資源視圖,以查看項(xiàng)目下的所有文件,如圖1-6所示。

圖1-6 生成的文件
各個(gè)文件的功能和內(nèi)容分別介紹如下:
● 應(yīng)用配置文件
web.config文件是ASP.NET應(yīng)用配置文件,其內(nèi)容如下,其中的注釋說(shuō)明了每個(gè)配置元素的含義。本書(shū)后續(xù)章節(jié)將對(duì)每個(gè)配置元素做詳細(xì)講解。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <!-- 動(dòng)態(tài)調(diào)試編譯 設(shè)置 compilation debug="true" 以啟用 .aspx 調(diào)試。否則,將此值設(shè)置為 false,將提高此應(yīng)用程序的運(yùn)行時(shí)性能。 設(shè)置 compilation debug="true" 以將調(diào)試符號(hào)(.pdb 信息) 插入到編譯頁(yè)中。因?yàn)檫@將創(chuàng)建執(zhí)行起來(lái) 較慢的大文件,所以應(yīng)該只在調(diào)試時(shí)將該值設(shè)置為 true,而在其他的時(shí)候都設(shè)置為 false。有關(guān)更多信息,請(qǐng)參考有關(guān)調(diào)試 ASP.NET 文件的文檔。 --> <!-- 設(shè)置默認(rèn)的編程語(yǔ)言,如果選擇建立Visual Basic語(yǔ)言的ASP.NET應(yīng)用,則 defaultLanguage="vb" --> <compilation defaultLanguage="c#" debug="true" /> <!-- 自定義錯(cuò)誤信息 設(shè)置 customError 模式值可以控制應(yīng)向 用戶(hù)顯示用戶(hù)友好錯(cuò)誤信息而不是錯(cuò)誤詳細(xì)信息: “On”始終顯示自定義(友好的)信息。 “Off”始終顯示詳細(xì)的 ASP.NET 錯(cuò)誤信息。 “RemoteOnly”只對(duì)不在本地 Web 服務(wù)器上運(yùn)行的 用戶(hù)顯示自定義(友好的)信息。出于安全目的,建議使用此設(shè)置,以便 不向遠(yuǎn)程客戶(hù)端顯示應(yīng)用程序的詳細(xì)信息。 --> <customErrors mode="RemoteOnly" /> <!-- 身份驗(yàn)證 此節(jié)設(shè)置應(yīng)用程序的身份驗(yàn)證策略。可能的模式是“Windows”、“Forms”、 “Passport”和“None” --> <authentication mode="Windows" /> <!-- 應(yīng)用程序級(jí)別跟蹤記錄 應(yīng)用程序級(jí)別跟蹤在應(yīng)用程序內(nèi)為每一頁(yè)啟用跟蹤日志輸出。 設(shè)置 trace enabled="true" 以啟用應(yīng)用程序跟蹤記錄。如果 pageOutput="true",則 跟蹤信息將顯示在每一頁(yè)的底部。否則,可以通過(guò)從 Web 應(yīng)用程序 和瀏覽 "trace.axd" 頁(yè)來(lái)查看應(yīng)用程序跟蹤日志。 --> <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" /> <!-- 會(huì)話(huà)狀態(tài)設(shè)置 默認(rèn)情況下,ASP.NET 使用Cookie 標(biāo)識(shí)哪些請(qǐng)求屬于特定的會(huì)話(huà)。 如果 Cookie 不可用,則可以通過(guò)將會(huì)話(huà)標(biāo)識(shí)符添加到 URL_來(lái)跟蹤會(huì)話(huà)。 若要禁用 Cookie,請(qǐng)?jiān)O(shè)置 sessionState Cookieless="true"。 --> <sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;user id=sa;password=" Cookieless="false" timeout="20" /> <!-- 全球化 此節(jié)設(shè)置應(yīng)用程序的全球化設(shè)置。 --> <globalization requestEncoding="utf-8" responseEncoding="utf-8" /> </system.web> </configuration>
● 窗體文件
窗體文件包括以.aspx為后綴的界面文件和代碼隱藏文件。
● Global.asax文件
它定義一些跟ASP.NET應(yīng)用相關(guān)的全局變量。其典型用途是定義ASP.NET應(yīng)用啟動(dòng)和結(jié)束、一個(gè)會(huì)話(huà)啟動(dòng)和結(jié)束時(shí)的響應(yīng)函數(shù)。下面的代碼清單可以非常清楚地看出Global.asax文件的作用。
[Visual Basic] Imports System.Web Imports System.Web.SessionState Public Class Global Inherits System.Web.HTTPApplication #Region" 組件設(shè)計(jì)器生成的代碼 " Public Sub New() MyBase.New() '該調(diào)用是組件設(shè)計(jì)器所必需的。 InitializeComponent() '在 InitializeComponent() 調(diào)用之后添加任何初始化 End Sub '組件設(shè)計(jì)器所必需的 Private components As System.ComponentModel.IContainer '注意:以下過(guò)程是組件設(shè)計(jì)器所必需的 '可以使用組件設(shè)計(jì)器修改此過(guò)程。 '不要使用代碼編輯器修改它。 <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container() End Sub #End Region Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) ' 在應(yīng)用程序啟動(dòng)時(shí)激發(fā) End Sub Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) ' 在會(huì)話(huà)啟動(dòng)時(shí)激發(fā) End Sub Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs) ' 在每個(gè)請(qǐng)求開(kāi)始時(shí)激發(fā) End Sub Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs) ' 嘗試對(duì)使用進(jìn)行身份驗(yàn)證時(shí)激發(fā) End Sub Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) ' 在發(fā)生錯(cuò)誤時(shí)激發(fā) End Sub Sub Session_End(ByVal sender As Object, ByVal e As EventArgs) ' 在會(huì)話(huà)結(jié)束時(shí)激發(fā) End Sub Sub Application_End(ByVal sender As Object, ByVal e As EventArgs) ' 在應(yīng)用程序結(jié)束時(shí)激發(fā) End Sub End Class [C#] using System; using System.Collections; using System.ComponentModel; using System.Web; using System.Web.SessionState; namespace CSCH1 { /// <summary> ///Global 的摘要說(shuō)明。 /// </summary> public class Global : System.Web.HTTPApplication { public Global() { InitializeComponent(); } protected void Application_Start(Object sender, EventArgs e) { } protected void Session_Start(Object sender, EventArgs e) { } protected void Application_BeginRequest(Object sender, EventArgs e) { } protected void Application_EndRequest(Object sender, EventArgs e) { } protected void Application_AuthenticateRequest(Object sender, EventArgs e) { } protected void Application_Error(Object sender, EventArgs e) { } protected void Session_End(Object sender, EventArgs e) { } protected void Application_End(Object sender, EventArgs e) { } #region Web Form Designer generated code ///<summary> /// 設(shè)計(jì)器支持所需的方法 - 不要使用代碼編輯器修改 /// 此方法的內(nèi)容。 ///</summary> private void InitializeComponent() { } #endregion
在本書(shū)后續(xù)章節(jié)將詳細(xì)討論如何編寫(xiě)上述清單中的各個(gè)方法。
● Styles.css文件
新Web應(yīng)用程序項(xiàng)目的默認(rèn)CSS樣式表,使用樣式的好處是省去了為每個(gè)標(biāo)志設(shè)置屬性的麻煩。樣式的定義語(yǔ)法為:
元素名稱(chēng){樣式名:值;樣式名:值…}
下面是該文件中定義的若干樣式類(lèi):
BODY { BACKGROUND-COLOR: white; FONT-FAMILY: Verdana, Helvetica, sans-serif; FONT-SIZE: .8em; FONT-WEIGHT: normal; LETTER-SPACING: normal; TEXT-TRANSFORM: none; WORD-SPACING: normal } H1, H2, H3, H4, H5, TH, THEAD, TFOOT { COLOR: #003366; } H1 { font-family:Verdana,Arial,Helvetica,sans-serif; font-size: 2em; font-weight: 700; font-style: normal; text-decoration: none; word-spacing: normal; letter-spacing: normal; text-transform: none; } IMG { margin-top: 5px; margin-left: 10px; margin-right: 10px; }
如果為.aspx文件指定了應(yīng)用上述樣式,那么<body>標(biāo)志內(nèi)的HTML元素自動(dòng)以下面的設(shè)置為默認(rèn)值:
BACKGROUND-COLOR: white;
FONT-FAMILY: Verdana, Helvetica, sans-serif;
FONT-SIZE: .8em;
FONT-WEIGHT: normal;
LETTER-SPACING: normal;
TEXT-TRANSFORM: none;
WORD-SPACING: normal
但如果對(duì)<body>內(nèi)的某個(gè)子元素重新設(shè)置了相應(yīng)的屬性,例如“FONT-SIZE”,那么以新設(shè)置的屬性為主。為了具體說(shuō)明樣式的作用效果和規(guī)則,我們?cè)陧?xiàng)目中添加一個(gè)名為democss.html的超文本文件,其內(nèi)容如下:
<html> <head> <link ref="stysheet" href="styles.css" type="text/css"></link> </head> <body> <h1>使用默認(rèn)樣式的效果</h1> <h1 style="color:red;font-size:20pt"> 定制的樣式覆蓋了默認(rèn)樣式中的文字顏色和大小 </h1> </body> </html>
瀏覽器中的瀏覽效果如圖1-7所示。

圖1-7 使用樣式后的瀏覽效果
<body>內(nèi)的第一個(gè)<h1>元素采用<body>和<h1>中的默認(rèn)屬性,而第二個(gè)<h2>重寫(xiě)了文字顏色和大小兩個(gè)屬性。
其中第三句代碼用以引用外部設(shè)定的樣式文件,還可以使用內(nèi)嵌的樣式,這時(shí)樣式在<style>標(biāo)志內(nèi)定義,例如:
<html> <head> <!-- <link ref="stysheet" href="styles.css" type="text/css"></link> --> <style> BODY { BACKGROUND-COLOR: white; FONT-FAMILY: Verdana, Helvetica, sans-serif; FONT-SIZE: .8em; FONT-WEIGHT: normal; LETTER-SPACING: normal; TEXT-TRANSFORM: none; WORD-SPACING: normal } H1, H2, H3, H4, H5, TH, THEAD, TFOOT { COLOR: #003366; } H1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 2em; font-weight: 700; font-style: normal; text-decoration: none; word-spacing: normal; letter-spacing: normal; text-transform: none; } </style> </head> <body> <h1>使用默認(rèn)樣式的效果</h1> <h1 style="color:red;font-size:20pt"> 定制的樣式覆蓋了默認(rèn)樣式中的文字顏色和大小 </h1> </body> </html>
● 程序集信息文件
隱藏代碼被編譯為一個(gè)程序集。程序集信息文件設(shè)置該程序集的若干信息,如版本、區(qū)域性、密鑰文件等。
[Visual Basic] Imports System.Reflection Imports System.Runtime.InteropServices ' 程序集的常規(guī)信息通過(guò)下列 ' 屬性集控制。更改這些屬性值可 ' 修改與程序集關(guān)聯(lián)的信息。 ' 檢查程序集的屬性值 <Assembly: AssemblyTitle("")> <Assembly: AssemblyDeScription("")> <Assembly: AssemblyCompany("")> <Assembly: AssemblyProduct("")> <Assembly: AssemblyCopyright("")> <Assembly: AssemblyTrademark("")> <Assembly: CLSCompliant(True)> '如果該項(xiàng)目向 COM 公開(kāi),則下列 GUID 用于類(lèi)型庫(kù)的 ID <Assembly: Guid("FF8D28EA-4294-4189-924A-FF51319DB917")> ' 程序集的版本信息由下列 4 個(gè)值組成: ' ' 主版本 ' 次版本 ' 內(nèi)部版本號(hào) ' 修訂號(hào) ' ' 您可以指定所有這些值,也可以使用“內(nèi)部版本號(hào)”和“修訂號(hào)”的默認(rèn)值,方法是按 ' 如下所示使用“*”: <Assembly: AssemblyVersion("1.0.*")> [C#] using System.Reflection; using System.Runtime.CompilerServices; // // 有關(guān)程序集的常規(guī)信息是通過(guò)下列 //屬性集控制的。更改這些屬性值可修改與程序集 //關(guān)聯(lián)的信息。 // [assembly: AssemblyTitle("")] [assembly: AssemblyDeScription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // 程序集的版本信息包含下列 4 個(gè)值: // // 主版本 // 次版本 // 內(nèi)部版本號(hào) // 修訂號(hào) // // 您可以指定所有值,或使用“修訂號(hào)”和“內(nèi)部版本號(hào)”的默認(rèn)值,方法為按如下方式 // 使用“*”: [assembly: AssemblyVersion("1.0.*")] // // 要對(duì)程序集進(jìn)行簽名,必須指定要使用的密鑰。有關(guān)程序集簽名的更多信息,請(qǐng)參考 //Microsoft.NET 框架文檔。 // // 使用下面的屬性控制用于簽名的密鑰。 // // 注意: // (*) 如果未指定密鑰,則程序集不會(huì)被簽名。 // (*)KeyName 是指已經(jīng)安裝在 // 計(jì)算機(jī)上的加密服務(wù)提供程序 (CSP) 中的密鑰。KeyFile 是指包含 // 密鑰的文件。 // (*) 如果 KeyFile 和 KeyName 值都已指定,則發(fā)生下面的處理: // (1) 如果在 CSP 中可以找到 KeyName,則使用該密鑰。 // (2) 如果 KeyName 不存在而 KeyFile 存在,則 // KeyFile 中的密鑰安裝到 CSP 中并且使用該密鑰。 // (*) 要?jiǎng)?chuàng)建 KeyFile,可以使用 sn.exe(強(qiáng)名稱(chēng))實(shí)用工具。 // 在指定 KeyFile 時(shí),KeyFile 的位置應(yīng)該 // 相對(duì)于“項(xiàng)目輸出目錄”。項(xiàng)目輸出 // 目錄的位置取決于您是在使用本地項(xiàng)目還是 Web 項(xiàng)目。 // 對(duì)于本地項(xiàng)目,項(xiàng)目輸出目錄定義為 // <Project Directory>\obj\<Configuration>。例如,如果 KeyFile 位于該 // 項(xiàng)目目錄中,應(yīng)將 AssemblyKeyFile // 屬性指定為 [assembly:AssemblyKeyFile("..\\..\\mykey.snk")] // 對(duì)于 Web 項(xiàng)目,項(xiàng)目輸出目錄定義為 // %HOMEPATH%\VSWebCache\<Machine Name>\<Project Directory>\obj\<Configuration>。 // (*)“延遲簽名”是一個(gè)高級(jí)選項(xiàng) - 有關(guān)它的更多信息,請(qǐng)參閱 Microsoft.NET 框架文檔。 // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")]
提示
上述文件主要是利用程序集層次的相關(guān)特性來(lái)設(shè)置程序集的屬性。特性是.NET框架提供的功能,用以對(duì)程序集作批注,例如可以用Assembly層次上的AssemblyVersion特性設(shè)置程序集版本:
[Visual Basic] <Assembly: AssemblyVersion("1.0.*")> [C#] [assembly: AssemblyVersion("1.0.*")]
其中參數(shù)“1.0.*.*”是Assembly: AssemblyVersion特性的占位參數(shù)(也就是AssemblyVersion特性類(lèi)構(gòu)造函數(shù)中的一個(gè)參數(shù))。
1.3.3 第三步:設(shè)計(jì)WebForm1窗體
把WebForm1窗體設(shè)計(jì)成一個(gè)如圖1-8所示的登錄界面。

圖1-8 設(shè)計(jì)好的登錄界面
圖1-8中各個(gè)標(biāo)號(hào)所指的控件分別是:
①和②是Web窗體下的標(biāo)簽控件,將①、②所指的標(biāo)簽分別設(shè)置為“用戶(hù)名”和“口令”。
提示
Web控件的屬性不同于HTML元素的屬性。ASP.NET框架根據(jù)Web控件的屬性設(shè)置轉(zhuǎn)化為相應(yīng)的HTML標(biāo)志并設(shè)置其屬性。
③所指的為Web按鈕控件,將其Text屬性設(shè)置為“提交”。
④所指的為Web驗(yàn)證匯總控件ValidationSummary,將其屬性保持為默認(rèn)值。
⑤所指的是Web文本框TextBox控件,將其ID屬性設(shè)置為username。
提示
代碼中通過(guò)ID引用相應(yīng)的屬性。
⑥所指的是HTML口令Password控件,將其ID屬性設(shè)置為pwd。然后選中該控件,單擊右鍵,單擊【作為服務(wù)器控件運(yùn)行】按鈕,如圖1-9所示。

圖1-9 將HTML控件設(shè)置為作為服務(wù)器控件運(yùn)行
說(shuō)明
默認(rèn)情況下,HTML控件作為客戶(hù)端控件運(yùn)行,這樣服務(wù)端的代碼就不用通過(guò)其ID引用該控件。轉(zhuǎn)化為服務(wù)器端控件運(yùn)行后,自動(dòng)將其runat屬性設(shè)置為server。
⑦所指的是Web必須域RequiredFieldValidator驗(yàn)證控件,將其Text屬性設(shè)置為“*”,將其ErrorMessage屬性設(shè)置為“用戶(hù)名不能為空”,將其ControlToValidate屬性設(shè)置為⑤所指的文本框控件的ID“username”。
提示
RequiredFieldValidator驗(yàn)證控件驗(yàn)證其ControlToValidate屬性所指的控件的值是否為空,如果為空,則將顯示其Text屬性所設(shè)的值,同時(shí)向驗(yàn)證匯總控件ValidationSummary中添加一條由其ErrorMessage所指的錯(cuò)誤消息。
⑧所指的也是Web必須域RequiredFieldValidator驗(yàn)證控件,將其Text屬性設(shè)置為“*”,將其ErrorMessage屬性設(shè)置為“口令不能為空”,將其ControlToValidate屬性設(shè)置為⑥所指的文本框控件的ID“pwd”。
提示
在窗體的設(shè)計(jì)視圖下,圖1-9中所有的控件都可以從工具箱中拖放到窗體上。Web控件位于工具箱的“Web窗體”頁(yè)下,HTML控件則位于“HTML”頁(yè)下。
切換到HTML視圖下,可以查看Web窗體的代碼。本例中設(shè)計(jì)完成后的窗體具有下面清單所示的代碼:
<%@ Page Language="cs" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits= "CH1.WebForm1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <title>WebForm1</title> <meta content="Microsoft Visual Studio.NET 7.0"name="GENERATOR"> <meta content="Visual Basic 7.0"name="CODE_LANGUAGE"> <meta content="JavaScript"name="vs_defaultClientScript"> <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema"> </HEAD> <body MS_POSITIONING="GridLayout"> <form id="Form1"method="post"runat="server"> <FONT face="宋體"> <asp:label id="Label1" style="Z-INDEX: 101; LEFT: 63px; POSITION: absolute; TOP: 41px" runat="server" Width="68px" Height="24px"> 用 戶(hù) 名 </asp:label><asp:requiredfieldvalidator id="RequiredFieldValidator2" style="Z-INDEX: 106; LEFT: 382px; POSITION: absolute; TOP: 96px" runat="server" ErrorMessage=" 口 令 不 能 為 空 " ControlToValidate="pwd">*</asp:requiredfieldvalidator><asp:label id="Label2" style="Z-INDEX: 103; LEFT: 65px; POSITION: absolute; TOP: 98px" runat="server" Width="68px" Height="24px">口令 </asp:label> <asp:TextBox id="username" style="Z-INDEX: 102; LEFT: 156px; POSITION:absolute;TOP:36px"runat="server"Width="201px"Height="30px"></asp:TextBox> <INPUT id="pwd" style="Z-INDEX: 104; LEFT: 152px; POSITION: absolute;TOP:97px"type="password"name="Password1"runat="server"> <asp:RequiredFieldValidator id="RequiredFieldValidator1" style="Z-INDEX: 105; LEFT: 381px; POSITION: absolute; TOP: 39px" runat="server" ErrorMessage="用戶(hù)名不能為空" ControlToValidate="username"Display="None">*</asp:RequiredFieldValidator> <asp:ValidationSummary id="ValidationSummary1" style="Z-INDEX: 107; LEFT: 74px; POSITION: absolute; TOP: 216px" runat="server" Width="228px" Height="36px"></asp:ValidationSummary> <asp:Button id="Button1" style="Z-INDEX: 108; LEFT: 75px; POSITION: absolute; TOP: 149px" runat="server" Width="313px" Height="32px" Text=" 提 交 "></asp:Button></FONT></form> </body> </HTML>
說(shuō)明
上面清單只列出了編程語(yǔ)言為Visual Basic的窗體界面代碼。如果編程語(yǔ)言為C#,那么把設(shè)置特定語(yǔ)言的代碼中的“vb”替換為“cs”(或C#)即可。
1.3.4 第四步:編碼
雙擊WebForm1上的按鈕控件,ASP.NET自動(dòng)在代碼隱藏文件中添加處理按鈕控件事件的代碼框架。
[Visual Basic] Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click End Sub [C#] private void Button1_Click(object sender, System.EventArgs e) { }說(shuō)明
Web窗體設(shè)計(jì)器還自動(dòng)在InitializeComponent方法中添加掛鉤事件的代碼:
this.Button1.Click += new System.EventHandler(this.Button1_Click);
然后在Button1_Click函數(shù)體內(nèi)輸入下面的代碼:
[Visual Basic] If username.Text = "曉華" And pwd.Value = "1234" Then FormsAuthentication.RedirectFromLoginPage("曉華", True) Else Response.Redirect("webform1.aspx") End If [C#] if(username.Text == "曉華" && pwd.Value == "1234" ) { FormsAuthentication.RedirectFromLoginPage("曉華", true); } else Response.Redirect("webform1.aspx");
上述代碼判斷用戶(hù)是否是特定的用戶(hù)(用戶(hù)名為“曉華”,口令為“1234”),如果是則在客戶(hù)端生成標(biāo)志用戶(hù)身份的Coockie,并定位到請(qǐng)求的網(wǎng)頁(yè)。否則將重定向到登錄界面。
為了順利編譯上述代碼,請(qǐng)引入FormsAuthentication所在的命名空間:
[Visual Basic] Imports System.Web.Security [C#] using System.Web.Security;
說(shuō)明
FormsAuthentication.RedirectFromLoginPage將已驗(yàn)證身份的用戶(hù)重定向最初請(qǐng)求的URL。第一個(gè)參數(shù)表示用于Cookie身份驗(yàn)證的用戶(hù)名稱(chēng),該名稱(chēng)不必是Windows系統(tǒng)中的賬戶(hù)。第二個(gè)參數(shù)指示是應(yīng)當(dāng)發(fā)出持久性Cookie。
如果沒(méi)有指定請(qǐng)求的網(wǎng)頁(yè)(例如本例中通過(guò)點(diǎn)擊按鈕提交WebForm1窗體就是如此),那么FormsAuthentication.RedirectFromLoginPage將重定向到Default.aspx。正是這個(gè)原因,稍后我們要往項(xiàng)目中添加一個(gè)名為Default.aspx的窗體。
Response.Redirect方法將結(jié)果導(dǎo)到指定的網(wǎng)頁(yè)作為回應(yīng)。Web窗體的Response屬性封裝了跟客戶(hù)端的響應(yīng)相關(guān)的操作。
1.3.5 第五步:添加Default.aspx窗體
在資源管理器視圖下,選中ASP.NET應(yīng)用項(xiàng)目,單擊右鍵,指向【添加Web窗體】,在彈出的子菜單中單擊【添加】按鈕,如圖1-10所示。

圖1-10 添加Web窗體的菜單
這時(shí)會(huì)彈出如圖1-11所示的“添加新項(xiàng)”對(duì)話(huà)框,將新建的窗體命名為Default.aspx,然后單擊【打開(kāi)】按鈕。

圖1-11 “添加新項(xiàng)”對(duì)話(huà)框
這時(shí)添加的DefaultWeb窗體處于設(shè)計(jì)視圖下,按照如圖1-12所示設(shè)計(jì)其界面。

圖1-12 設(shè)計(jì)DefaultWeb窗體的界面
DefaultWeb窗體上包含了一個(gè)Web標(biāo)簽控件和一個(gè)Web按鈕控件。
然后雙擊按鈕,添加處理按鈕單擊的代碼:
[Visual Basic] Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click FormsAuthentication.SignOut() End Sub [C#] private void Button1_Click(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); }
同樣在代碼隱藏文件的開(kāi)頭引入FormsAuthentication所在的命名空間:
[Visual Basic] Imports System.Web.Security [C#] using System.Web.Security;
FormsAuthentication.SignOut方法移除身份驗(yàn)證憑據(jù),調(diào)用后,客戶(hù)端表示用戶(hù)身份的持久性Cookie或會(huì)話(huà)Cookie將被刪除。
1.3.6 第六步:配置
雙擊web.config文件,找到下面的代碼:
<authentication mode="Windows" />
用下面的代碼替換上面的代碼:
<authentication mode="Forms"> <forms loginURL="webform1.aspx" /> </authentication>
上述配置的含義是將驗(yàn)證模式設(shè)置為窗體驗(yàn)證模式,并設(shè)置登錄窗體為webform1.aspx。窗體驗(yàn)證模式允許ASP.NETWeb應(yīng)用通過(guò)窗體收集用戶(hù)的信息,并驗(yàn)證用戶(hù)是否合法。
然后找到<authorization></authorization>元素,用下面的內(nèi)容替換該元素及其內(nèi)部的代碼:
<authorization> <deny users="?" /> </authorization>
<deny users="?" />禁止沒(méi)有通過(guò)身份驗(yàn)證的用戶(hù)訪(fǎng)問(wèn)本W(wǎng)eb應(yīng)用程序。
1.3.7 第七步:測(cè)試
按【Ctrl+Shift+B】鍵編譯項(xiàng)目,然后按【Ctrl+F5】鍵運(yùn)行程序。
說(shuō)明
ASP.NET應(yīng)用的隱藏代碼在執(zhí)行前要被編譯成程序集,對(duì)ASP應(yīng)用開(kāi)發(fā)比較熟悉的讀者一定要注意這一點(diǎn)。直接按【Ctrl+F5】鍵,在執(zhí)行之前要先編譯項(xiàng)目,然后執(zhí)行項(xiàng)目的啟動(dòng)頁(yè)面。
讀者可能會(huì)對(duì)集成開(kāi)發(fā)工具具體的編譯過(guò)程感到好奇。在用戶(hù)發(fā)出編譯命令后,集成開(kāi)發(fā)環(huán)境將調(diào)用特定編程語(yǔ)言的編譯器(Visual Basic為vbc.exe、C#為csc.exe)把項(xiàng)目中的隱藏代碼文件編譯成一個(gè)DLL形式的程序集(也叫類(lèi)庫(kù)),生成后的程序集位于應(yīng)用程序根目錄下的bin子目錄下。默認(rèn)情況下,生成的程序集的名字跟項(xiàng)目名相同,但可以通過(guò)設(shè)置項(xiàng)目的相關(guān)屬性改變。改變的方法是在項(xiàng)目資源管理器視圖下單擊要設(shè)置的項(xiàng)目,單擊鼠標(biāo)右鍵,單擊【屬性】按鈕,這時(shí)會(huì)彈出項(xiàng)目的“屬性”對(duì)話(huà)框。展開(kāi)【通用屬性】節(jié)點(diǎn),單擊【常規(guī)】子項(xiàng),就出現(xiàn)如圖1-13所示(如果項(xiàng)目的編程語(yǔ)言為C#,則對(duì)應(yīng)的畫(huà)面如圖1-14所示)的畫(huà)面,在該畫(huà)面下可以設(shè)置程序集的名稱(chēng)。

圖1-13 設(shè)置項(xiàng)目輸出的程序集(Visual Basic)

圖1-14 設(shè)置項(xiàng)目輸出的程序集(C#)
在介紹ASP.NET Web應(yīng)用部署的時(shí)候,我們將進(jìn)一步介紹相關(guān)的編譯命令vbc.exe和csc.exe。現(xiàn)在大家只要知道,ASP.NET Web應(yīng)用可以引用位于bin子目錄下的程序集就夠了。
可以引用某個(gè)程序集的含義是可以使用該程序集內(nèi)實(shí)現(xiàn)的各種類(lèi)型。程序集包含了它依賴(lài)的其他程序集的信息,以及其中定義的所有類(lèi)型的信息,這些信息叫做程序集清單。為了使用某個(gè)程序集實(shí)現(xiàn)的組件,不用注冊(cè)該組件,直接將該程序集拷貝到bin子目錄下即可。
提示
bin子目下的程序集是ASP.NET Web應(yīng)用的專(zhuān)用程序集。某些情況下,可能希望同一個(gè)程序集內(nèi)的組件被多個(gè)ASP.NET Web應(yīng)用(或其他類(lèi)型的.NET應(yīng)用,如本地窗體應(yīng)用、控制臺(tái)應(yīng)用等),那么可以將該組件轉(zhuǎn)化為強(qiáng)名程序集,并將之放入全局程序集緩存,這樣的程序集叫做共享程序集。.NET應(yīng)用不必在私有的庫(kù)目錄(對(duì)ASP.NET Web應(yīng)用而言,該目錄是BIN子目錄)保存共享程序集的拷貝。大家可能注意到,.NET框架類(lèi)庫(kù)就是共享的程序集,這些程序集都有強(qiáng)名字并被預(yù)先放入了全局程序集緩存,所以ASP.NET Web應(yīng)用可以自由引用.NET框架庫(kù),而不會(huì)在bin子目錄下保存它們的副本。
程序集是.NET應(yīng)用的核心,多花些時(shí)間深入了解程序集是值得的。本書(shū)后面介紹ASP.NET Web應(yīng)用的部署的時(shí)候?qū)?huì)對(duì)程序集做進(jìn)一步介紹。
隱藏代碼在運(yùn)行之前就編譯成了bin子目錄下的程序集,那么Web窗體的界面元素文件(后綴為.aspx的文件)又如何呢?答案是在第一次請(qǐng)求.aspx文件時(shí),該文件被動(dòng)態(tài)編譯成程序集,該程序集實(shí)現(xiàn)一個(gè)從代碼隱藏類(lèi)實(shí)現(xiàn)的Web窗體的派生類(lèi)。我們?cè)诨仡^看看webform1.aspx文件的第一行代碼:
[Visual Basic] <%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="CH1.WebForm1"%> [C#] <%@ Page Language="cs" AutoEventWireup="false" Codebehind="WebForm1.aspx.cs" Inherits="CH1.WebForm1"%>
其中Inherits屬性就指定了本頁(yè)面的父類(lèi),而其中的Codebehind只是用來(lái)把界面元素和隱藏代碼關(guān)聯(lián)起來(lái),只在編輯代碼時(shí)候起到同步界面視圖和隱藏代碼的作用,對(duì)最后的.aspx文件及隱藏代碼文件的編譯并沒(méi)有影響。讀者可以試著刪除代碼中的Codebehind屬性設(shè)置,應(yīng)該會(huì)發(fā)現(xiàn)代碼運(yùn)行后沒(méi)有任何不同。
上面討論的內(nèi)容是為了幫助讀者了解一些內(nèi)幕信息。這樣對(duì)程序設(shè)計(jì)過(guò)程中不致于被出現(xiàn)的一些意外所惑。順便提一下,程序集中的代碼是一種所謂的微軟中間代碼(MSIL),不能直接在CPUT上執(zhí)行,但.NET運(yùn)行時(shí),提供的即時(shí)編譯JIT技術(shù)能夠動(dòng)態(tài)地把MSIL轉(zhuǎn)化為可被特定的CPU(例如X86芯片)執(zhí)行的二進(jìn)制代碼。轉(zhuǎn)化后的二進(jìn)制代碼將被緩存,并可以在響應(yīng)后續(xù)請(qǐng)求時(shí)直接在CPU上運(yùn)行。
上面的討論實(shí)質(zhì)上揭示了一個(gè)ASP.NET應(yīng)用被編譯直至運(yùn)行過(guò)程中涉及的一些底層細(xì)節(jié)。本書(shū)后續(xù)章節(jié)將會(huì)對(duì)這些內(nèi)容做進(jìn)一步的探討。下面回到測(cè)試的主題上來(lái),運(yùn)行項(xiàng)目后,將出現(xiàn)如圖1-15所示的登錄畫(huà)面。

圖1-15 登錄畫(huà)面
先實(shí)驗(yàn)一下必須域驗(yàn)證的效果。保持用戶(hù)名和口令為空,直接單擊【提交】按鈕,將出現(xiàn)如圖1-16所示的畫(huà)面。因?yàn)楸仨氂蝌?yàn)證控件檢查到輸入用戶(hù)名和口令中輸入為空,從而顯示提示文本(由其Text屬性設(shè)定),并且錯(cuò)誤信息(由驗(yàn)證控件的ErrorMessage屬性設(shè)置)出現(xiàn)在驗(yàn)證匯總控件中。

圖1-16 驗(yàn)證未通過(guò)
從執(zhí)行結(jié)果可以看出,通過(guò)使用相關(guān)的驗(yàn)證控件,可以保證提交到服務(wù)器上的數(shù)據(jù)為有效數(shù)據(jù)。如果輸入了無(wú)效數(shù)據(jù),驗(yàn)證將不能通過(guò),這時(shí)原來(lái)提交的請(qǐng)求頁(yè)面,以及添加了若干驗(yàn)證信息的頁(yè)面被返回。
在用戶(hù)名文本框中輸入“曉華”,再單擊【提交】按鈕,執(zhí)行結(jié)果如圖1-17所示。從執(zhí)行結(jié)果可以看出,驗(yàn)證提示信息變化了,因?yàn)橹挥锌诹顬榭眨斎氲挠脩?hù)名則在往返行程中保持不變。

圖1-17 保持口令為空時(shí)的驗(yàn)證結(jié)果
在口令框中輸入口令“1234”后,單擊【提交】按鈕,將彈出如圖1-18所示的畫(huà)面。彈出的“自動(dòng)完成”對(duì)話(huà)框提示是否根據(jù)用戶(hù)名文本框自動(dòng)設(shè)置口令框中的口令,單擊【否】繼續(xù)。

圖1-18 提示是否自動(dòng)完成
這時(shí)將返回默認(rèn)頁(yè)面default.aspx的執(zhí)行結(jié)果,如圖1-19所示。服務(wù)器端將在客戶(hù)端設(shè)置標(biāo)志用戶(hù)“曉華”身份的Coockie。

圖1-19 成功登錄后的畫(huà)面
在圖1-19中單擊【Sign Out】按鈕,將在客戶(hù)端取消標(biāo)志用戶(hù)“曉華”身份的Coockie。如果試圖不經(jīng)過(guò)登錄界面直接請(qǐng)求default.aspx頁(yè)面,則ASP.NET框架首先驗(yàn)證用戶(hù)的身份;如果客戶(hù)端標(biāo)志用戶(hù)的Coockie,則把用戶(hù)當(dāng)成未經(jīng)身份驗(yàn)證的匿名用戶(hù),而本示例通過(guò)配置文件中授權(quán)設(shè)置<deny users="?" />拒絕匿名用戶(hù)的訪(fǎng)問(wèn)請(qǐng)求,并自動(dòng)重定向到身份驗(yàn)證配置部分的Forms元素的loginURL屬性設(shè)定的登錄頁(yè)面。
提示
如果客戶(hù)端已經(jīng)有了標(biāo)志用戶(hù)曉華身份的Coockie,則可以直接獲得請(qǐng)求的頁(yè)面。
從上面的測(cè)試可以看出,本示例中設(shè)計(jì)的登錄界面的確保證了只有特定的用戶(hù)才能成功登錄,任何不經(jīng)身份驗(yàn)證而直接獲取本應(yīng)用的請(qǐng)求都將失敗。
注意
身份驗(yàn)證本身不能提供任何安全措施,安全的實(shí)施是通過(guò)對(duì)用戶(hù)的授權(quán)實(shí)現(xiàn)的。本示例中,如果允許所有的用戶(hù)都能登錄,也就是在web.config文件的授權(quán)部分添加<deny users="?" />,那么任何用戶(hù)都可以直接請(qǐng)求default.aspx。當(dāng)然對(duì)webform1.aspx頁(yè)面而言,仍然只有當(dāng)用戶(hù)名為“曉華”,口令為“1234”時(shí),才會(huì)進(jìn)入default.aspx頁(yè)面,但這種設(shè)防已經(jīng)毫無(wú)意義!
提示
可以在default.aspx頁(yè)面內(nèi)顯示當(dāng)前登錄的用戶(hù)名,這時(shí)請(qǐng)打開(kāi)default.aspx的隱藏代碼文件,并把Page_Load方法的代碼修改為:
[Visual Basic] Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '在此處放置初始化頁(yè)的用戶(hù)代碼 If Not IsPostBack Then Label1.Text = User.Identity.Name & ",歡迎光臨" End If End Sub [C#] private void Page_Load(object sender, System.EventArgs e) { // 在此處放置用戶(hù)代碼以初始化頁(yè)面 Label1.Text = User.Identity.Name + ",歡迎光臨"; }
其中,User.Identity獲得當(dāng)前用戶(hù)的標(biāo)志。
1.3.8 第八步:功能完善
上面示例僅允許一個(gè)特定的用戶(hù)登錄,假設(shè)隨著程序的運(yùn)行,需要允許更多的用戶(hù)例如小楊等人也可以登錄,那么就必須修改webform1.aspx的提交按鈕的處理代碼:
[Visual Basic] If (username.Text = "曉華" And pwd.Value = "1234") Or (username.Text = "小楊" And pwd.Value = "5157") Then ‘… end if [C#] if((username.Text=="曉華"&&pwd.Value=="1234")|| (username.Text=="小楊"&& pwd.Value == "5157" )) { }
隨著允許訪(fǎng)問(wèn)的用戶(hù)名單的增加,上述代碼還會(huì)進(jìn)一步增加,因此必須考慮另外一種更一般的方法。答案在于FormsAuthentication.Authenticate方法,它接收兩個(gè)分別表示用戶(hù)名和口令的參數(shù),并根據(jù)配置文件中的身份驗(yàn)證節(jié)中的配置信息驗(yàn)證用戶(hù)的身份。為了支持“曉華”和“小楊”兩個(gè)用戶(hù)登錄,可以把web.config中配置身份驗(yàn)證的部分修改為如下所示:
<authentication mode="Forms"> <forms loginURL="webform1.aspx"> <credentials passwordFormat = "Clear" > <user name="小楊" password="5157"/> <user name="曉華" password="1234"/> </credentials> </forms> </authentication>
credentials元素的passwordFormat屬性設(shè)置為Clear,表示用戶(hù)的密碼用明文表示,因此用戶(hù)“小楊”的密碼就是“5157”,用戶(hù)“曉華”的密碼就是“1234”。
注意
passwordFormat屬性區(qū)分大小寫(xiě),不要把Clear誤寫(xiě)為clear。
然后把webform1的提交按鈕的單擊事件處理代碼修改為如下所示:
[Visual Basic] Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If FormsAuthentication.Authenticate(username.Text, pwd.Value) Then FormsAuthentication.RedirectFromLoginPage(username.Text, True) Else Response.Redirect("webform1.aspx") End If End Sub [C#] private void Button1_Click(object sender, System.EventArgs e) { if( FormsAuthentication.Authenticate(username.Text, pwd.Value)) { FormsAuthentication.RedirectFromLoginPage(username.Text, true); } else Response.Redirect("webform1.aspx"); }
重新編譯項(xiàng)目后啟動(dòng),然后在輸入用戶(hù)名“小楊”及口令“5157”,如圖1-20所示。

圖1-20 測(cè)試改進(jìn)后的應(yīng)用
在圖1-19所示的畫(huà)面中單擊【提交】按鈕,將出現(xiàn)如圖1-21所示的畫(huà)面。

圖1-21 小楊登錄后的界面
還可以通過(guò)配置文件修改授權(quán),例如下面的授權(quán)配置拒絕用戶(hù)“曉華”和匿名用戶(hù)登錄:
<authorization> <deny users="?,曉華"/> <allow users="*" /> </authorization>
從本例可以看出,利用配置文件可以不用修改源代碼而改變ASP.NET Web應(yīng)用的行為。對(duì)開(kāi)發(fā)人員而言,靈活地使用配置文件,也是一項(xiàng)重要的技能。
注意
在修改源代碼后,請(qǐng)不要忘了先編譯再執(zhí)行!
1.3.9 第九步:部署
因?yàn)锳SP.NET中所使用的組件都包含在程序集中,而程序集通過(guò)一個(gè)詳細(xì)的清單實(shí)現(xiàn)了自描述,所以ASP.NET應(yīng)用部署過(guò)程中不用考慮組件(例如傳統(tǒng)的COM組件)的注冊(cè)問(wèn)題,可以通過(guò)復(fù)制策略把ASP.NET應(yīng)用從開(kāi)發(fā)服務(wù)器部署到最終的發(fā)行服務(wù)器上。集成開(kāi)發(fā)環(huán)境提供了兩種方法實(shí)現(xiàn)ASP.NET應(yīng)用的部署:拷貝項(xiàng)目和使用安裝項(xiàng)目。
假設(shè)我們要把開(kāi)發(fā)服務(wù)器localhost上的ASP.NET應(yīng)用CH1部署到發(fā)行服務(wù)器diana的CH1RELEASE虛目錄下,則可以:
1.利用項(xiàng)目復(fù)制功能步驟
(1)選中要復(fù)制的ASP.NET項(xiàng)目。
(2)選擇【項(xiàng)目】菜單,繼續(xù)選擇【復(fù)制項(xiàng)目】子菜單。
(3)這時(shí)將彈出“復(fù)制項(xiàng)目”對(duì)話(huà)框,如圖1-22所示。設(shè)置好目標(biāo)項(xiàng)目文件夾的名稱(chēng)和相關(guān)的復(fù)制選項(xiàng),然后單擊【確定】按鈕。

圖1-22 “復(fù)制項(xiàng)目”對(duì)話(huà)框
(4)這時(shí)會(huì)出現(xiàn)如圖1-23所示的對(duì)話(huà)框指示復(fù)制進(jìn)度。當(dāng)項(xiàng)目復(fù)制完畢后,該對(duì)話(huà)框自動(dòng)關(guān)閉。

圖1-23 復(fù)制進(jìn)度進(jìn)度圖
(5)復(fù)制結(jié)束后,通過(guò)瀏覽器訪(fǎng)問(wèn)發(fā)行服務(wù)器上的ASP.NET應(yīng)用。
在瀏覽器的地址欄中發(fā)行服務(wù)器上的應(yīng)用地址,如圖1-24所示,將會(huì)出現(xiàn)開(kāi)發(fā)服務(wù)器上類(lèi)似的界面。

圖1-24 訪(fǎng)問(wèn)部署到發(fā)行服務(wù)器上的ASP.NET應(yīng)用
2.用Web安裝項(xiàng)目部署步驟
(1)在解決方案資源視圖下,右鍵單擊解決方案,鼠標(biāo)指向【新建項(xiàng)目】,然后在彈出的子菜單中單擊【添加】按鈕,如圖1-25所示。

圖1-25 往解決方案中添加項(xiàng)目
(2)這時(shí)會(huì)彈出“添加新項(xiàng)目”對(duì)話(huà)框,如圖1-26所示。選擇左邊的“項(xiàng)目類(lèi)型”列表框中的【安裝和部署項(xiàng)目】,在右邊的“模板”列表框中單擊【W(wǎng)eb安裝項(xiàng)目】,在設(shè)置安裝項(xiàng)目的名稱(chēng)和保存該項(xiàng)目的目錄后,單擊【確定】按鈕。

圖1-26 “添加新項(xiàng)目”對(duì)話(huà)框
(3)解決方案資源視圖下的項(xiàng)目列表框中會(huì)出現(xiàn)新建的安裝項(xiàng)目,右鍵單擊該項(xiàng)目,鼠標(biāo)引向【添加】后單擊【項(xiàng)目輸出】。
(4)這時(shí)會(huì)彈出如圖1-27所示的“添加項(xiàng)目輸出組”對(duì)話(huà)框。選擇項(xiàng)目“CH1”,在列表框中選中“主輸出”和“內(nèi)容文件”,單擊【確定】按鈕,關(guān)閉對(duì)話(huà)框。

圖1-27 “添加項(xiàng)目輸出組”對(duì)話(huà)框
提示
對(duì)于CH1項(xiàng)目,只用發(fā)行編譯后的程序集(項(xiàng)目主輸出)和所有的*.aspx文件(內(nèi)容文件)。至于代碼隱藏文件(源文件)和資源和調(diào)試符號(hào)則不用部署到目標(biāo)服務(wù)器上。
(5)右鍵單擊安裝項(xiàng)目,指向【視圖】,單擊【自定義操作】按鈕。
(6)選中【自定義操作】節(jié)點(diǎn),單擊右鍵,單擊【添加自定義操作】按鈕。
(7)按照如圖1-28所示進(jìn)行選擇,設(shè)置好后,單擊【確定】按鈕,關(guān)閉對(duì)話(huà)框。

圖1-28 選擇項(xiàng)目中的項(xiàng)
(8)右鍵單擊安裝項(xiàng)目,單擊【生成】按鈕,這時(shí)輸出窗口將輸入如圖1-29所示的信息。

圖1-29 編譯安裝項(xiàng)目時(shí)的輸出窗口
(9)查看安裝項(xiàng)目的調(diào)試(或發(fā)行)目錄生成的安裝文件,如圖1-30所示。

圖1-30 安裝項(xiàng)目的生成文件
(10)把安裝項(xiàng)目生成的安裝文件復(fù)制到ASP.NET應(yīng)用發(fā)行服務(wù)器Diana。
(11)在發(fā)行服務(wù)器Diana上運(yùn)行安裝文件。
啟動(dòng)安裝后,會(huì)依次出現(xiàn)如圖1-31至圖1-35所示的畫(huà)面。

圖1-31 歡迎畫(huà)面

圖1-35 安裝結(jié)束

圖1-32 設(shè)置安裝地址

圖1-33 確認(rèn)安裝

圖1-34 正在安裝
(12)在瀏覽器上輸入http://diana/WebSetupCH1/webform1.aspx,測(cè)試發(fā)行服務(wù)器上的ASP.NET應(yīng)用。
提示
通過(guò)控制面板下的“添加/刪除程序”工具刪除安裝的ASP.NET應(yīng)用,如圖1-36所示。

圖1-36 通過(guò)“添加/刪除程序”工具刪除安裝的ASP.NET應(yīng)用
從整個(gè)安裝實(shí)例來(lái)看,ASP.NET應(yīng)用的部署是比較容易的。如果涉及到數(shù)據(jù)庫(kù)訪(fǎng)問(wèn),則部署ASP.NET應(yīng)用時(shí),還要考慮數(shù)據(jù)庫(kù)的部署。
1.4 小結(jié)
本章簡(jiǎn)單介紹了直到ASP.NET誕生,Web應(yīng)用開(kāi)發(fā)的歷史。本章的重點(diǎn)是通過(guò)開(kāi)發(fā)一個(gè)基于窗體驗(yàn)證的登錄Web窗體,介紹了ASP.NET應(yīng)用開(kāi)發(fā)的全貌。本章所涉及到的大量技術(shù),在本書(shū)后面都有詳細(xì)介紹。
- 2019年全國(guó)導(dǎo)游人員資格考試輔導(dǎo)教材-吉林導(dǎo)游服務(wù)能力
- 經(jīng)濟(jì)、金融、會(huì)計(jì)(農(nóng)村信用社招聘考試專(zhuān)用系列教材·2013最新版)
- 人力資源管理專(zhuān)業(yè)知識(shí)與實(shí)務(wù)十年真題精析(中級(jí))(2016版)
- 銀行業(yè)專(zhuān)業(yè)人員初級(jí)職業(yè)資格考試專(zhuān)用教材:個(gè)人理財(cái)(新大綱)
- 2020年中國(guó)科學(xué)院大學(xué)601高等數(shù)學(xué)(甲)考試大綱解析
- 物業(yè)管理師《物業(yè)經(jīng)營(yíng)管理》過(guò)關(guān)必做1000題(含歷年真題)
- 企業(yè)人力資源管理師職業(yè)資格考試專(zhuān)用輔導(dǎo)教材(二級(jí)):教材精解(圖解版)+題庫(kù)解析+歷年真題+押題預(yù)測(cè)
- 2020年新疆維吾爾自治區(qū)社區(qū)工作者公開(kāi)招聘考試《行政職業(yè)能力》專(zhuān)項(xiàng)題庫(kù)【真題精選+章節(jié)題庫(kù)+模擬試題】
- 物業(yè)管理師《物業(yè)管理實(shí)務(wù)》過(guò)關(guān)必做習(xí)題集(含歷年真題)
- 二級(jí)建造師考試指南:建設(shè)工程施工管理
- 啟視未來(lái):2018—2019新東方留學(xué)指南英聯(lián)邦國(guó)家
- 《物業(yè)管理實(shí)務(wù)》命題點(diǎn)全面解讀
- 多媒體課件設(shè)計(jì)與制作(視頻指導(dǎo)版)
- 新駕考錦囊:輕松考過(guò)科目四
- 2019年全國(guó)導(dǎo)游人員資格考試輔導(dǎo)教材-湖北導(dǎo)游基礎(chǔ)知識(shí)