《面向服務(wù)的計(jì)算和web數(shù)據(jù)管理》課件第5章_第1頁(yè)
《面向服務(wù)的計(jì)算和web數(shù)據(jù)管理》課件第5章_第2頁(yè)
《面向服務(wù)的計(jì)算和web數(shù)據(jù)管理》課件第5章_第3頁(yè)
《面向服務(wù)的計(jì)算和web數(shù)據(jù)管理》課件第5章_第4頁(yè)
《面向服務(wù)的計(jì)算和web數(shù)據(jù)管理》課件第5章_第5頁(yè)
已閱讀5頁(yè),還剩235頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第5章Web應(yīng)用和數(shù)據(jù)管理5.1Web應(yīng)用的結(jié)構(gòu)

5.2Web應(yīng)用模型

5.3狀態(tài)管理

5.4將用戶數(shù)據(jù)存到服務(wù)器文件系統(tǒng)

5.5高速緩存

5.6圖形數(shù)據(jù)的生成和表示

5.7討論傳統(tǒng)桌面應(yīng)用具有唯一的入口,整個(gè)應(yīng)用被編譯成獨(dú)立的可執(zhí)行文件。一個(gè)應(yīng)用可包含多個(gè)類和文件,并由一個(gè)工程文件組織在一起成為一個(gè)定義良好的工程域。另一方面,Web應(yīng)用包含很多頁(yè)面和其他文件,可以通過(guò)任意頁(yè)面進(jìn)入這個(gè)Web應(yīng)用,即使最常用的入口是主頁(yè)面或默認(rèn)頁(yè)面。為了更好的滿足交互性,Web應(yīng)用經(jīng)常是事件驅(qū)動(dòng)的。由于Web服務(wù)和HTTP協(xié)議是無(wú)狀態(tài)的,所以Web應(yīng)用中的狀態(tài)管理問(wèn)題很關(guān)鍵,并且需要采取的技術(shù)和面向?qū)ο筌浖_(kāi)發(fā)中的技術(shù)完全不同。

本章主要關(guān)注利用Internet上提供的已有Web服務(wù)以及應(yīng)用域創(chuàng)建的一些本地構(gòu)件來(lái)構(gòu)建Web應(yīng)用。

一個(gè)ASP.NetWeb站點(diǎn)應(yīng)用包含該應(yīng)用的目錄以及子目錄中所有文件,其中有的目錄和文件是系統(tǒng)生成的,其他是開(kāi)發(fā)者創(chuàng)建的。但是開(kāi)發(fā)者可以編輯所有的文件,包括那些系統(tǒng)生成的文件。5.1Web應(yīng)用的結(jié)構(gòu)5.1.1Web應(yīng)用的構(gòu)件

ASP.NetWeb站點(diǎn)應(yīng)用通常包含下面幾種類型的文件和構(gòu)件,其中有些是必需的,有些則是可選的。

(1)ASPX文件:ASPX文件采用Web格式,用于創(chuàng)建用戶與程序交互的GUI頁(yè)面。當(dāng)ASPXWeb站點(diǎn)應(yīng)用被創(chuàng)建時(shí),文件Default.aspx也被生成。一個(gè)ASP.NetWeb站點(diǎn)至少有一個(gè)ASPX文件,開(kāi)發(fā)者也可以添加更多的ASPX文件。

(2)ASCX文件:ASCX文件都通過(guò)服務(wù)器端腳本或頁(yè)面后臺(tái)代碼創(chuàng)建HTML頁(yè)面中的用戶控件。用戶控件不能創(chuàng)建完整的頁(yè)面,但是它可以在一個(gè)或多個(gè)ASPX頁(yè)面中添加(用戶控件)可重用項(xiàng)。

(3)Web.config文件:它包含模式定義、訪問(wèn)控制、參數(shù)化應(yīng)用的行為等配置設(shè)置。

(4)Global.asax全局應(yīng)用類:包含對(duì)全局事件的事件處理,例如應(yīng)用或新的會(huì)話的啟動(dòng)。在創(chuàng)建應(yīng)用時(shí),此文件放在其根目錄下。

(5)DLL(動(dòng)態(tài)鏈接庫(kù)):它包含Windows環(huán)境下的通用庫(kù)函數(shù),并與.exe文件有相同的格式。在任何時(shí)候,它們都可以被計(jì)算機(jī)上運(yùn)行的其他程序調(diào)用,例如,允許另外一個(gè)程序與特定設(shè)備,如打印機(jī)和鍵盤(pán)調(diào)用,通信程序通常被打包成DLL程序。支持特定設(shè)備操作的DLL文件被稱為設(shè)備驅(qū)動(dòng)程序。

(6)C#文件或者.cs文件用于頁(yè)面后臺(tái)的事件處理程序,用來(lái)處理諸如用戶輸入(鼠標(biāo)點(diǎn)擊)、程序回滾以及異常等事件。

(7)XHTML頁(yè)面:是ASPX頁(yè)面的標(biāo)記頁(yè)面。XHTML頁(yè)面可由ASPX設(shè)計(jì)頁(yè)面生成,也可由開(kāi)發(fā)者創(chuàng)建。另一方面,ASPX頁(yè)面可由XHTML頁(yè)面生成。XHTML頁(yè)面必可包含C#腳本。

應(yīng)用的根目錄通常包含Default.aspx、Global.asax文件、Web.config文件,以及任何其他頂層ASPX和ASCX文件。ASP.NetWeb站點(diǎn)應(yīng)用可創(chuàng)建多個(gè)子目錄分類存儲(chǔ)應(yīng)用生成的文件。通常來(lái)說(shuō),這些子目錄包括:

(1)Bin:包含可執(zhí)行碼和DLL文件;

(2)App_Code:包含程序源代碼,例如C#程序;

(3)App_Data:存儲(chǔ)XML文件和數(shù)據(jù)庫(kù)文件;

(4)App_WebReferences:存儲(chǔ)添加在應(yīng)用中的Web服務(wù)的引用。

最簡(jiǎn)單的Web應(yīng)用只包含一個(gè)文件,它是提供用戶GUI的ASPX文件。ASPX文件的計(jì)算能力是有限的。對(duì)于更復(fù)雜的應(yīng)用需要多個(gè)文件,這些文件組織成為一個(gè)樹(shù)形圖,如圖5.1。

圖5.1ASP.NetWeb站點(diǎn)應(yīng)用的組織全局文件定義之后必須放在根目錄下,并且任何應(yīng)用只能定義一個(gè)全局文件。任何目錄下都可以定義任意數(shù)目的ASPX文件、ASCX文件和DLL文件。每個(gè)目錄只定義一個(gè)Web.config文件。因?yàn)閃eb.config文件和應(yīng)用的安全性有關(guān),因此我們重點(diǎn)關(guān)注它。

ASP.Net可以創(chuàng)建允許進(jìn)行xcopy安裝的軟件,也就是,可通過(guò)拖拽軟件文件夾到用戶選定的安裝位置進(jìn)行安裝,刪除時(shí)也只需要?jiǎng)h除該文件夾。只要把Web.config文件放在應(yīng)用軟件所在的目錄中,而不是放在Windows系統(tǒng)注冊(cè)表中,就會(huì)支持XCOPY機(jī)制。Web.config文件的另一個(gè)意圖是參數(shù)化應(yīng)用的行為,即不用修改或者重新編譯源代碼就可修改行為。它本質(zhì)上是一種基于策略的計(jì)算?;诓呗缘挠?jì)算是SOA的常見(jiàn)特點(diǎn),但是,它目前是比較活躍的研究領(lǐng)域,因此本書(shū)不詳細(xì)討論。

Web應(yīng)用中的每個(gè)子目錄都可包含Web配置文件,都起名為Web.config。Web.config文件中的設(shè)置應(yīng)用于它所在的目錄和所有子目錄。一個(gè)目錄中Web.config文件中的設(shè)置優(yōu)先于(覆蓋)父目錄中的設(shè)置。用戶可以創(chuàng)建子目錄的Web.config文件,并用它們控制子頁(yè)的設(shè)置。圖5.1是一個(gè)應(yīng)用域中的文件和這些文件的組織的例子。

Web.config文件受IIS保護(hù),所以客戶端不能通過(guò)瀏覽器瀏覽。任何訪問(wèn)文件的嘗試都會(huì)收到拒絕訪問(wèn)的出錯(cuò)信息。

Web.config采用XML格式并作為簡(jiǎn)單的文本文件存儲(chǔ)。任何文本編輯器或者XML解析器都可創(chuàng)建編輯Web.config文件。Web.config包含兩部分?jǐn)?shù)據(jù),下面是它的基本框架:

<configuration>

<appSettings>

<!applicationsettingvaluesgohere>

</appSettings>

<system.web>

<!ASP.Netconfigurationsettingsgohere>

<system.web>

<configuration>

Web.config文件中的<appSetting>元素包含應(yīng)用中的一些特定值,例如,應(yīng)用訪問(wèn)數(shù)據(jù)庫(kù)時(shí)需要的鏈接字符串,它允許開(kāi)發(fā)者參數(shù)化應(yīng)用。下面的代碼將鏈接SQL數(shù)據(jù)庫(kù)的字符串硬編碼到C#程序中:

SqlDataAdapteradapter=newSqlDataAdapter("select*fromnamewhereyear=2008,"server=myServer;database=myDatabase;IntegratedSecurity=SSPI;UserID=myID;Password=MyPassWord");

DataSetrefDataSet=newDataSet();

adapter.Fill(refDataSet);這樣,如果要修改,例如密碼改變,會(huì)導(dǎo)致C#代碼被修改并重新編譯。最好的方式是在<appSetting>中定義鏈接字符串,這樣使用不同的數(shù)據(jù)庫(kù)時(shí),不需要修改代碼。下面的Web.config文件將和服務(wù)器相關(guān)的值放入<appSetting>元素:

<configuration>

<appSettings>

<addkey="MyConnectionString"value="server=myServer;database=myDatabase;

IntegratedSecurity=SSPI;UserID=myID;Password=MyPassWord"/>

</appSettings>

</configuration>

這樣,C#代碼使用路徑ConfigurationSettings.appSettings和參數(shù)(關(guān)鍵碼)MyConnectionString訪問(wèn)Web.config文件中的鏈接字符串,就像已在MSDN庫(kù)中定義的字符串。

StringrefString=ConfigurationSettings.appSettings[MyConnectionString];SqlDataAdapteradapter=newSqlDataAdapter("select*fromnamewhereyear=2008",

refString);DataSetrefDataSet=newDataSet();

adapter.Fill(refDataSet);5.1.2服務(wù)控件

ASPX頁(yè)面中的圖形用戶界面(GUI)可以通過(guò)工具箱中的服務(wù)控件來(lái)實(shí)現(xiàn)。服務(wù)控件是.Net類庫(kù)中控制類的對(duì)象。這些控件是ASPX頁(yè)面的組成部分??丶梢越邮蛰斎氩⒂纱思ぐl(fā)事件,這樣,我們可以給控件編寫(xiě)事件處理程序并以事件驅(qū)動(dòng)方式處理輸入。圖形化設(shè)計(jì)視圖中的控件也可以顯示成XHTML格式,可以發(fā)送到客戶端瀏覽器以顯示為Web頁(yè)面。ASP.Net提供了三種服務(wù)控件:Web控件、HTML控件、由用戶自己定義的類創(chuàng)建的用戶控件。

(1)HTML控件是在服務(wù)器端生成相當(dāng)于HTML構(gòu)件的對(duì)象,因此所有的HTML函數(shù)都可以在ASPX應(yīng)用中處理。通過(guò)事件,處理程序和控件連接起來(lái),所以,輸入控制或數(shù)據(jù)都能迅速被處理。

(2)Web控件提供了傳統(tǒng)的HTML頁(yè)面中不存在的構(gòu)件。這些構(gòu)件比HTML控件功能更強(qiáng)大。

(3)用戶控件:HTML控件和Web控件通過(guò).Net類庫(kù)中的類提供。如想使用庫(kù)中沒(méi)有提供的控件,可以創(chuàng)建用戶控件(對(duì)象)。用戶控件通過(guò)單獨(dú)的ASCX頁(yè)面定義,頁(yè)面包含服務(wù)器端腳本或頁(yè)面支持的后臺(tái)代碼。由于用戶控件被保存為單獨(dú)的XHTML文件,所以修改控件時(shí)不需要修改相關(guān)的ASPX頁(yè)面。一個(gè)用戶控件可以被多個(gè)ASPX頁(yè)面共享。

ASPX頁(yè)面和ASCX頁(yè)面有兩種不同的視圖:(圖形化)設(shè)計(jì)視圖和(XHTML)源碼視圖??梢杂脙煞N視圖開(kāi)發(fā)頁(yè)面。圖5.2顯示的是ASPX頁(yè)面的設(shè)計(jì)視圖。Web應(yīng)用包含兩個(gè)ASPX頁(yè)面:Sender.aspx和Receiver.aspx。此應(yīng)用中使用Web服務(wù)Encryptor進(jìn)行加密和解密。

圖5.2一個(gè)ASPX應(yīng)用的設(shè)計(jì)視圖如果在文本框中輸入普通文本消息,點(diǎn)擊“EncryptNow”按鈕,加密信息就就會(huì)顯示出來(lái)。例如鍵入“MypasswordisSuperMan1”,“EneryptedMessage”就顯示“箣軈澨?蹧???竭???Ⅴ?脫(因?yàn)榧用?所以顯示亂碼)”。如果點(diǎn)擊按鈕“SendtoReceiver”,加密信息會(huì)發(fā)送到接收頁(yè)面。接收頁(yè)面會(huì)自動(dòng)打開(kāi)。如果沒(méi)有自動(dòng)打開(kāi),則可以返回到應(yīng)用,選擇“Receiver.aspx”頁(yè)面,就會(huì)執(zhí)行應(yīng)用(不需要調(diào)試即開(kāi)始)。點(diǎn)擊按鈕“DecryptNow”,就會(huì)看見(jiàn)原始信息“MypasswordisSuperMan1”。下面給出ASPX頁(yè)面的源碼視圖。

<%@PageLanguage="C#"Debug="True"AutoEventWireup="true"CodeFile="Sender.aspx.cs"Inherits="Default"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"

"/TR/xhtml1/DTD/xhtml1transitional.dtd">

<htmlxmlns="/1999/xhtml">

<headrunat="server"><title>EncryptionSender</title>

</head>

<body>

<formid="form1"runat="server">

<p>Pleasetypeyourmessageinthetextbox</p>

<div>

<asp:TextBoxID="txtInput"runat="server"Width="616px">Pleaseentertexthere

</asp:TextBox></div>

<asp:ButtonID="btnEncrypt"runat="server"onclick="btnEncryptClick"

Text="EncryptNow"/>

<br/>

<asp:LabelID="lblEncryptedMessage"runat="server"Text="EncryptedMessage"></asp:Label>

<br/>

<asp:ButtonID="btnSend"runat="server"onclick="btnSendClick"Text="SendtoReceiver"/>

<br/></form>

</body>

</html>

XHTML的源碼視圖包含兩個(gè)HTML控件:<headrunat=“server”>和<formrunat=“server”>,任何包含屬性runat=“server”的HTML元素都是HTML控件。

XHTML的源碼視圖包含兩個(gè)Web控件:

<asp:Buttonrunat=“server”>和<asp:Lablerunat=“server”>,任何包含限定符asp和屬性runat=“server”的元素都是Web控件。關(guān)于XML和XHTML的定義,請(qǐng)參考第4章。

為了使這個(gè)例子可運(yùn)行,我們需要以Web引用的方式把Encryptor服務(wù)添加到應(yīng)用中。服務(wù)的網(wǎng)址為:

/WSRepository/Service/Encryption/Service.asmx

Sender.aspx頁(yè)面的后臺(tái)C#代碼如下:

publicpartialclassDefault:System.Web.UI.Page{

protectedvoidPageLoad(objectsender,EventArgse){}

protectedvoidbtnEncryptClick(objectsender,EventArgse){

//importremoteWebservicetodothedifficultpartofthework

Encryptor.ServiceprxyEncrypt=newEncryptor.Service();

//Takethemessagefromthetextbox

stringmsg1=txtInput.Text;

//CalltheEncryptionmethodintheWebservice

stringmsgEncrypted=prxyEncrypt.Encrypt(msg1);

//Displayencryptedmessageatthepositionofthelabel

lblEncryptedMessage.Text=msgEncrypted;

//SavetheencodedmessageintoaSessionVariable‖,sothat

//theReceiver.aspxpagecanretrievethemessage

Session["msgEncoded"]=(object)msgEncrypted;

}

protectedvoidbtnSendClick(objectsender,EventArgse){

Response.Redirect("Receiver.aspx");

}

}

應(yīng)用中的第二個(gè)ASPX頁(yè)面是Recerver.aspx,頁(yè)面的XHTML源碼如下:

<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Receiver.aspx.cs"Inherits="Receiver"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""/TR/xhtml1/DTD/xhtml1transitional.dtd">

<htmlxmlns="/1999/xhtml">

<headrunat="server">

<title>EncryptionReceiver</title>

</head>

<body>

<formid="form1"runat="server">

<div>Themessagereceived</div>

<asp:LabelID="lblMessageReceived"runat="server"></asp:Label>

<br/>

<br/><asp:ButtonID="btnDecrypt"runat="server"onclick="btnDecrypt_Click"

Text="DecrptNow"/><br/>

<asp:LabelID="lblMessageDecrypted"runat="server"Text="DecryptedMessage"></asp:Label>

</form>

</body></html>

Receiver.aspx頁(yè)面的后臺(tái)C#代碼如下:

publicpartialclassReceiver:System.Web.UI.Page{

protectedvoidPageLoad(objectsender,EventArgse){

lblMessageReceived.Text=(string)Session["msgEncoded"];

}

protectedvoidbtnDecryptClick(objectsender,EventArgse){

//importremoteWebservicetodothedifficultpartofthework

Encryptor.ServiceprxyDecrypt=newEncryptor.Service();

//Takethemessagefromthesessionvariableusingthesameindexstring

stringmsg1=(string)Session["msgEncoded"];

//Checkifthesessionvariablecontainsanydata.

if(Session.Count==0){

//(Session.Count==0)meansnodataisstoredbythesender

lblMessageDecrypted.Text="NoMessagetoDisplay";

}

else{

//CalltheDecryptionmethodintheWebservice

stringdecrypted=prxyDecrypt.Decrypt(msg1);

//Displaythedecryptedmessageatthelabel

lblMessageDecrypted.Text=decrypted;

}

}

}通過(guò)組裝GUI設(shè)計(jì)頁(yè)面和C#頁(yè)面,我們就得到一個(gè)可運(yùn)行的應(yīng)用。

這是HTML控件和Web控件的另一個(gè)例子。下面給出了常用的HTML控件列表:

<buttonrunat="server">HtmlButton<inputtype="button"runat="server">HtmlInputButton<inputtype="reset"runat="server">HtmlInputButton<inputtype="submit"runat="server">HtmlInputButton<inputtype="checkbox"runat="server">HtmllnputcheckBox<inputtype="file"runat="server">HtmlInputFile<inputtype="hidden"runat="server">HtmlInputHidden<inputtype="image"runat="server">HtmlInputImage<inputtype="radio"runat="server">HtmlInputRadioButton<inputtype="password"runat="server">HtmlInputText<inputtype="text"runat="server">HtmlInputText<arunat="server">tmlAnchor<formrunat="server">HtmlForm<selectrunat="server">HtmlSelect<tablerunat="server">HtmlTable<tdrunat="server">HtmlTableCell<thrunat="server">HtmlTableCell<trrunat="server">HtmlTableRow<textarearunat="server">HtmlTextArea<imgrunat="server">HtmlImage

.Net框架類庫(kù)(FCL,FrameworkClassLibrary)實(shí)現(xiàn)了許多Web控件,包括下面幾組控件:

●按鈕控件,用于創(chuàng)建ASPX頁(yè)面中各種類型的按鈕,如前面的例子所示。

●日歷控件,在ASPX頁(yè)面中添加交互式日歷。

●數(shù)據(jù)綁定控件,使用數(shù)據(jù)綁定顯示來(lái)自數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源的信息。

●列表控件,顯示列表項(xiàng)。

●簡(jiǎn)單控件,將簡(jiǎn)單HTML控件包裝成Web控件。5.1.3用戶控件

為了說(shuō)明用戶控件的應(yīng)用,我們給發(fā)送頁(yè)添加一個(gè)新的特征,在“SendtoReceiver”按鈕下顯示日期和時(shí)間。用戶控件可通過(guò)下列步驟實(shí)現(xiàn):

(1)選擇VisualStudio菜單命令Web站點(diǎn)→添加新項(xiàng)…

(2)在彈出的窗口中選擇Web用戶控件。

(3)把新項(xiàng)命名為SenderDateTime.ascx,點(diǎn)擊添加。用戶控件將會(huì)出現(xiàn)在應(yīng)用程序的SolutionExplorer中,如圖5.3所示。圖5.3用戶控件被添加到Solution中(4)雙擊文件名SenderDateTime.ascx打開(kāi)文件,出現(xiàn)“source”視圖,在頁(yè)面中添加兩個(gè)名為1b1DateMsg和1blDate的標(biāo)簽,如下所示。

<%@ControlLanguage="C#"AutoEventWireup="true"CodeFile="SenderDateTime.

ascx.cs"Inherits="SenderDateTime"%>

<asp:LabelID="lblDateMsg"runat="server"Text="Thedateandtimeare"></asp:Label>

<asp:LabelID="lblDate"runat="server"Text=""></asp:Label>

(5)點(diǎn)擊“design”標(biāo)簽,轉(zhuǎn)換到設(shè)計(jì)視圖,在圖形視圖中查看標(biāo)簽。

(6)雙擊頁(yè)面的空白區(qū)域打開(kāi)C#編碼頁(yè),添加下列C#代碼。

publicpartialclassSenderDateTime:System.Web.UI.UserControl{

protectedvoidPageLoad(objectsender,EventArgse)

{

Stringdate=DateTime.Now.ToLongDateString();

Stringtime=DateTime.Now.ToLongTimeString();this.lblDate.Text=date+","+time;

}

}現(xiàn)在,我們創(chuàng)建了用戶控件。下來(lái),我們需要將用戶控件與需要控制的ASPX頁(yè)面連接。要連接Sender.aspx頁(yè),需要打開(kāi)XHTML源代碼視圖,通過(guò)添加下面代碼中的第一行來(lái)注冊(cè)用戶控件:

<%@RegisterTagPrefix="myControl"TagName="SenderDateTime"

src="SenderDateTime.ascx"%>

然后,將下面一行代碼放到Sender.aspx頁(yè)面中需要顯示日期和時(shí)間的位置:<myControl:SenderDateTimeID="SenderDateTime"runat="server"/>

下面給出添加了用戶控件的Sender.aspx頁(yè)面的完整的XHTML代碼,黑體部分是添加的代碼。

<%@PageLanguage="C#"Debug="True"AutoEventWireup="true"CodeFile="

Sender.

aspx.cs"Inherits="_Default"%>

<%@RegisterTagPrefix="myControl"TagName="SenderDateTime"src="SenderDateTime.ascx"%>

<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN

"/TR/xhtml1/DTD/xhtml1transitional.dtd">

<htmlxmlns="/1999/xhtml">

<headrunat="server">

<title>EncryptionSender</title>

</head><body>

<formid="form1"runat="server">

<p>Pleasetypeyourmessageinthetextbox</p>

<div>

<asp:TextBoxID="txtInput"runat="server"Width="616px">

Pleaseentertexthere</asp:TextBox>

</div>

<asp:ButtonID="btnEncrypt"runat="server"onclick="btnEncryptClick":

Text="EncryptNow"/>

<p/>

<asp:LabelID="lblEncryptedMessage"runat="server"Text="EncryptedMessage"></asp:Label>

<p/>

<asp:ButtonID="btnSend"runat="server"onclick="btnSendClick"

Text="SendtoReceiver"/>

<p/>

<myControl:SenderDateTimeID="SenderDateTime"runat="server"/>

</form>

</body>

</html>上述例子說(shuō)明在ASPX頁(yè)面中如何創(chuàng)建和包含用戶控件。顯然,這項(xiàng)功能通過(guò)Web控件“Label”,并在Sender.aspx頁(yè)面后臺(tái)直接添加C#代碼就很容易實(shí)現(xiàn)。用戶控件的主要優(yōu)點(diǎn)是它的重用性。同一個(gè)用戶控件可被多個(gè)ASPX頁(yè)共享,而服務(wù)控件和它的后臺(tái)代碼綁定到一個(gè)ASPX頁(yè)面,不能被共享。在上面的例子中,可為Receiver.aspx頁(yè)添加相同的用戶控件。5.1.4Web應(yīng)用配置

VisualStudio開(kāi)發(fā)環(huán)境將所有文件,包括配置文件,放在一個(gè)(根)目錄下的應(yīng)用域中。如果配置文件放在應(yīng)用域外的系統(tǒng)注冊(cè)表中,則安裝程序必需把配置放在正確的地方。這樣,創(chuàng)建的.Net應(yīng)用就很容易安裝和卸載。可以通過(guò)拖曳應(yīng)用文件夾的方式將應(yīng)用安裝到文件系統(tǒng)的任何位置,卸載時(shí)只需刪除這個(gè)文件夾即可。

ASP.Net應(yīng)用的配置文件Web.config是XML文本文件,創(chuàng)建應(yīng)用時(shí)其配置文件自動(dòng)生成??梢允褂萌魏螛?biāo)準(zhǔn)的文本編輯器或XML解析器讀寫(xiě)配置文件。配置文件不會(huì)被鎖定,應(yīng)用執(zhí)行時(shí)也可以對(duì)它進(jìn)行編輯。ASP.Net可以發(fā)現(xiàn)配置文件的改變,并對(duì)被變更影響的Web資源自動(dòng)實(shí)施新的配置項(xiàng),服務(wù)器端不需要重新啟動(dòng)。任何時(shí)候,層次結(jié)構(gòu)中的配置文件一旦修改,層次配置的設(shè)置都會(huì)自動(dòng)重新計(jì)算并重新載入。ASP.NetWeb應(yīng)用服務(wù)器的多個(gè)目錄下都會(huì)有配置文件,多個(gè)配置文件都命名為Web.config。

配置文件的作用范圍是它所在的目錄以及它的子目錄。子目錄中的配置文件除了可以應(yīng)用從父目錄繼承的配置信息外,還可以覆蓋或修改父目錄中定義的設(shè)置。通過(guò)配置IIS阻止直接瀏覽訪問(wèn)配置文件,ASP.Net保護(hù)配置文件不受外來(lái)訪問(wèn)。任何瀏覽器試圖直接訪問(wèn)配置文件,都將返回HTTP訪問(wèn)錯(cuò)誤403(禁止)。下面的文件是之前討論的加密例子中的Web.config。

<?xmlversion="1.0"?>

<!

Note:Asanalternativetohandeditingthisfileyoucanusethe

Webadmintooltoconfiguresettingsforyourapplication.Use

theWebsite>Asp.Net?ConfigurationoptioninVisualStudio.

Afulllistofsettingsandcommentscanbefoundin

machine.config.commentsusuallylocatedin

/Windows/Microsoft.Net?/Framework/v2.x/Config

><configuration>

<configSections>

<sectionGroup>

</sectionGroup>

</configSections>

<appSettings>

<addkey="Encryptor.Service"value="/WSRepository/

Services/Encryption/Service.asmx"/>

</appSettings>

<system.Web>

<!

Setcompilationdebug="true"toinsertdebugging

symbolsintothecompiledpage.Becausethis

affectsperformance,setthisvaluetotrueonly

duringdevelopment.

>

<compilationdebug="true">

<assemblies>

</assemblies>

</compilation>

<!

The<authentication>sectionenablesconfiguration

ofthesecurityauthenticationmodeusedby

ASP.Net?toidentifyanincominguser.

>

<authenticationmode="Windows"/>

<!

The<customErrors>sectionenablesconfiguration

ofwhattodoif/whenanunhandlederroroccurs

duringtheexecutionofarequest.Specifically,

itenablesdeveloperstoconfigurehtmlerrorpages

tobedisplayedinplaceofanerrorstacktrace.

<customErrorsmode="RemoteOnly"defaultRedirect="GenericErrorPage.htm">

<errorstatusCode="403"redirect="NoAccess.htm"/>

<errorstatusCode="404"redirect="FileNotFound.htm"/>

</customErrors>

>

<pages>

<controls>

</controls>

</pages>

<httpHandlers>

</httpHandlers>

<httpModules>

</httpModules>

</system.Web>

<system.codedom>

<compilers>

</compilers>

</system.codedom>

<!

Thesystem.WebServersectionisrequiredforrunningASP.Net?AJAX

underInternetInformationServices7.0.Itisnotnecessary

forpreviousversionofIIS.

>

<system.WebServer>

<validationvalidateIntegratedModeConfiguration="false"/>

<handlers>

<removename="WebServiceHandlerFactoryIntegrated"/>

<removename="ScriptHandlerFactory"/>

<removename="ScriptHandlerFactoryAppServices"/>

<removename="ScriptResource"/>

<addname="ScriptHandlerFactory"verb="*"path="*.asmx"/>

<addname="ScriptHandlerFactoryAppServices"verb="*"/>

<addname="ScriptResource"preCondition="integratedMode"/>

</handlers>

</system.WebServer>

<runtime>

<assemblyBindingxmlns="urn:schemasmicrosoftcom:asm.v1">

<dependentAssembly>

</dependentAssembly>

</assemblyBinding>

</runtime>

</configuration>

下面詳細(xì)介紹一下Web.config文件。它是一個(gè)XML文件,包含許多元素。根元素是<configuration>,第一層子元素是配置文件的主要部分。

(1)<configSections>部分:包含配置文件中出現(xiàn)的各部分的聲明,類似于程序中的變量聲明,我們需要在程序的開(kāi)始部分聲明程序中使用的所有變量。

(2)<appSettings>部分:保存應(yīng)用中特定的值(字符串),它們?cè)谶\(yùn)行過(guò)程可以被讀取。

(3)<system.Web>部分:保存系統(tǒng)使用的配置(ASP.Net)。

(4)<system.codedom>部分:保存應(yīng)用中使用的每一種語(yǔ)言編譯時(shí)使用的配置。

(5)<system.WebServer>部分:保存Web服務(wù)或Web應(yīng)用所在的Web服務(wù)器使用的配置。

(6)<runtime>部分:保存運(yùn)行時(shí)系統(tǒng)相關(guān)的綁定、部署和身份驗(yàn)證的配置。

ASP.Net配置系統(tǒng)是可擴(kuò)展的,可以定義新的配置部分,編寫(xiě)程序讀取特定部分,運(yùn)用數(shù)據(jù)作決策。因此,Web.config文件可以用來(lái)支持基于策略的計(jì)算。如果你喜歡,也可以使用ASP.NetWebSite管理工具編輯Web.config文件,而不是直接使用文本工具編輯XML元素。在ASP.Net菜單中,選擇Website→ASP.NetConfigeration,就可以定義和編輯你關(guān)心的所有部分。

Web.config文件的部分和子部分在后面需要使用它們的章節(jié)中會(huì)繼續(xù)介紹。例如,在研究安全機(jī)制的開(kāi)發(fā)時(shí),會(huì)介紹<authentication>和<authorization>元素。5.1.5全局應(yīng)用類

ASP.Net提供全局應(yīng)用類Glabal.asax,它包含負(fù)責(zé)處理全局事件的處理程序。全局變量可以通過(guò)形如Application[“index”]的應(yīng)用狀態(tài)來(lái)使用,它提供了對(duì)象數(shù)組存儲(chǔ)全局信息。想要在應(yīng)用中添加全局應(yīng)用類,可右擊應(yīng)用文件夾,選擇“AddNewItem…”,然后選擇“GlobalApplicationClass”,Global.asax將會(huì)被添加到應(yīng)用的根目錄下。打開(kāi)文件,里面包含了帶有事件處理接口的模板。

下面的代碼是添加幾個(gè)簡(jiǎn)單事件處理的全局應(yīng)用類的例子。

<%@ApplicationLanguage="C#"%><scriptrunat="server">

voidApplicationStart(objectsender,EventArgse){

//Codethatrunsonapplicationstartup

Application["SessionCounter"]=0;

}

voidApplicationEnd(objectsender,EventArgse){

//Codethatrunsonapplicationshutdown

Response.Write("<hr/>TheWebsitewaslastvisitedon"

+DateTime.Now.ToString());

}

voidApplicationError(objectsender,EventArgse){

//Codethatrunswhenanunhandlederroroccurs

}

voidSessionStart(objectsender,EventArgse){

//Codethatrunswhenanewsessionisstarted

Int32count=(Int32)Application["SessionCounter"];

count++;

Application["SessionCounter"]=count;

}

voidSessionEnd(objectsender,EventArgse){

//Codethatrunswhenasessionends.

//Note:TheSessionEndeventisraisedonlywhenthesessionstate

//modeissettoInProcintheWeb.configfile.Ifsessionmodeis

//settoStateServerorSQLServer,theeventisnotraised.

Int32count=(Int32)Application["SessionCounter"];

count;

Application["SessionCounter"]=count;

}

</script>

Web應(yīng)用可以被多個(gè)用戶同時(shí)訪問(wèn)。每次訪問(wèn)都打開(kāi)新的會(huì)話。這些事件處理的作用是跟蹤有多少個(gè)會(huì)話被同時(shí)打開(kāi)。

在事件處理Application_Start()中,將應(yīng)用狀態(tài)變量Application[“SessionCounter”]初始化為0。當(dāng)啟動(dòng)應(yīng)用時(shí),這個(gè)事件處理被自動(dòng)調(diào)用。

在事件處理Session_Start()中,增加狀態(tài)變量Application[“SessionCounter”]的值,當(dāng)新的會(huì)話開(kāi)始時(shí),這個(gè)事件處理被自動(dòng)調(diào)用。在事件處理Session_End()中,減少狀態(tài)變量Application[“SessionCounter”]的值,當(dāng)會(huì)話結(jié)束時(shí),這個(gè)事件處理被自動(dòng)調(diào)用。

這個(gè)實(shí)現(xiàn)中,應(yīng)用重新啟動(dòng)時(shí),計(jì)數(shù)器初始化為0。如果想保留打開(kāi)會(huì)話的總數(shù),可以使用另外一個(gè)應(yīng)用狀態(tài)變量Application[“TotalSessions”]。將此變量的值保存在包含Application_End()事件處理的硬盤(pán)文件中,在Application_Start()事件處理中恢復(fù)該變量的值。關(guān)于應(yīng)用狀態(tài)以及在服務(wù)器文件系統(tǒng)中存儲(chǔ)應(yīng)用數(shù)據(jù)等內(nèi)容在本章后面的章節(jié)討論。5.1.6動(dòng)態(tài)鏈接庫(kù)

ASP.Net提供了多種代碼復(fù)用方式。前面討論了通過(guò)創(chuàng)建服務(wù)或用戶控件類來(lái)共享多個(gè)應(yīng)用或一個(gè)應(yīng)用的多個(gè)頁(yè)面中的代碼。創(chuàng)建DLL(動(dòng)態(tài)鏈接庫(kù))類是通過(guò)類庫(kù)進(jìn)行代碼共享的傳統(tǒng)方法。

創(chuàng)建DLL類時(shí),選擇VisualStudio菜單“文件→新建→項(xiàng)目…”創(chuàng)建新的工程。然后,在VisualStudio的安裝模板中,選擇“類庫(kù)”,將打開(kāi)一個(gè)C#名字空間頁(yè)面,在此可以寫(xiě)多個(gè)類。類創(chuàng)建和編譯完成后,就可以在需要庫(kù)功能的Web應(yīng)用中通過(guò)使用“添加引用…”選項(xiàng)來(lái)訪問(wèn)這些類。一旦找到到類庫(kù)的位置,并在應(yīng)用中添加了庫(kù)時(shí),類的執(zhí)行代碼就會(huì)被載入到應(yīng)用的bin文件夾中。下面的例子中,在名字空間模板中創(chuàng)建了兩個(gè)簡(jiǎn)單類。

namespacemyLibrary{

publicclassTemperatureConversion{

publicstaticInt32getFahrenheit(Int32c){

Doublef=c*9/5+32;

returnConvert.ToInt32(f);

}

publicstaticInt32getCelsius(Int32f){

Doublec=(f-32)*5/9;

returnConvert.ToInt32(c);

}

}

publicclassmyMath{

publicstaticlongabs(longx){

if(x>=0)return(x);elsereturn(-x);

}

}

}

在應(yīng)用中使用“添加引用…”添加名字空間“myLibrary”后,就可以在程序中使用類庫(kù)。例如,名字空間“myLibrary”定義了類“TemperatureConcersion”,就可以使用TemperatureConcersion.getFahrenheit(Ctemp)訪問(wèn)類中的函數(shù)。下面的例子是用名字空間訪問(wèn)類庫(kù)。usingmyLibrary;//YoumustusethenamespacenamedefinedinDLL

classmyApplication{

staticvoidMain(string[]args)

{

Int32Ctemp=23;

Int32Ftemp=121;

doublex=TemperatureConversion.getFahrenheit(Ctemp);//UsingDLLheredoubley=TemperatureConversion.getCelsius(Ftemp);//UsingDLLhere

System.Console.WriteLine(―Ctemp{0}isFtemp{1}",Ctemp,x);

System.Console.WriteLine(―Ftemp{0}isCtemp{1}",Ftemp,y);

}

}

Web應(yīng)用是指具有計(jì)算能力的Web頁(yè)。在第一代Web中,HTML語(yǔ)言是瀏覽器唯一支持的語(yǔ)言,而后來(lái)的瀏覽器支持更多的語(yǔ)言,包括許多腳本語(yǔ)言和其他計(jì)算方法。5.2Web應(yīng)用模型5.2.1純基于HTML的Web應(yīng)用

純粹的HTMLWeb頁(yè)不支持計(jì)算,但是,它提供了大量的方法和格式,例如GET、POST、PUT、HEAD以及DELETE,用來(lái)發(fā)送和接收來(lái)自服務(wù)器的數(shù)據(jù)。例如,下面的代碼允許用戶輸入數(shù)據(jù)、進(jìn)行操作,并且發(fā)送數(shù)據(jù)到服務(wù)器進(jìn)行計(jì)算。<html>

<body>

<form>

<inputtype="text"name="operand1"VALUE="number"/>

<inputtype="text"name="operation"VALUE="operation"/>

<inputtype="text"name="operand2"VALUE="number"/>

<inputtype="submit"value="="/>

</form>

</body>

</html>在服務(wù)器端,當(dāng)有來(lái)自Web站點(diǎn)的請(qǐng)求時(shí),一個(gè)進(jìn)程被實(shí)例化以處理數(shù)據(jù)并發(fā)送結(jié)果到頁(yè)面。通常情況下,在執(zhí)行計(jì)算之前,程序員必須提供自己的方式來(lái)收集足夠的信息、對(duì)額外的數(shù)據(jù)執(zhí)行大量的字符串處理、解釋數(shù)據(jù)。隨著Web計(jì)算技術(shù)的進(jìn)步,使用這種方式開(kāi)發(fā)Web應(yīng)用的人越來(lái)越少。5.2.2客戶端腳本編寫(xiě)

在Web瀏覽器中增加執(zhí)行腳本語(yǔ)言的能力,是從桌面計(jì)算轉(zhuǎn)移到Web計(jì)算的重要里程碑。JavaScript是最早最廣泛使用的腳本語(yǔ)言之一。

Netscape公司BrendanEich開(kāi)發(fā)的Mocha,后來(lái)改名為L(zhǎng)iveScript,是第一代JavaScript,被用在1995年12月發(fā)布的Netscape瀏覽器2.0B3中。在LiveScript發(fā)布不久后,這個(gè)流行的腳本語(yǔ)言以新的名字“JavaScript”出現(xiàn)在Netscape公司和SunMicrosystems公司的合作中;現(xiàn)在“JavaScript”是SunMicrosystems公司的注冊(cè)商標(biāo)。下列代碼說(shuō)明了一個(gè)帶有<script>元素的HTML頁(yè)面,這個(gè)<script>元素包含JavaScript函數(shù)。

<html>

<body>

<scripttype="text/JavaScript">

functionadd2Nos(){

document.sum.z.value=parseInt(document.sum.x.value)

+parseInt(document.sum.y.value)

}

</script>

<formname="sum">

<inputtype="text"name="x"size=5maxlength="5">

<inputtype="text"name="y"size=-5"maxlength="5">

<inputtype="button"value="="name="Submit"

onClick="add2Nos()"><inputtype="text"name="z"size="5"maxlength="5">

</form>

</body>

</html>可以看出,腳本程序被嵌入到HTML代碼中,并被載入到客戶端瀏覽器,腳本在瀏覽器中執(zhí)行。這一技術(shù)被稱為客戶端腳本。在這個(gè)例子中,Web頁(yè)面從輸入表格里獲?。矀€(gè)數(shù)字,通過(guò)調(diào)用JavaScript函數(shù)在頁(yè)面執(zhí)行加法,不需要和服務(wù)器進(jìn)行數(shù)據(jù)通信。

隨著腳本語(yǔ)言的流行,越來(lái)越多的腳本語(yǔ)言出現(xiàn)了,其解釋器也被嵌入到Web瀏覽器中。許多傳統(tǒng)的編程語(yǔ)言也被升級(jí)以提供腳本能力。由于規(guī)模的限制,許多腳本語(yǔ)言不被瀏覽器支持,這些腳本語(yǔ)言只能用于服務(wù)器端,而服務(wù)器幾乎支持任何腳本語(yǔ)言以及傳統(tǒng)的編程語(yǔ)言。按照功能和用途,腳本語(yǔ)言可以分為以下幾種:

(1)作業(yè)控制語(yǔ)言和Shells,包括:IBMJCL,UnixScript以及AppleScript;

(2)GUI/可視化編程語(yǔ)言,包括:OracleSOASuite支持的GraphicBPEL,ActiveBPEL,MicrosoftVPL以及NationalInstrumentLabView;

(3)具體應(yīng)用語(yǔ)言,包括:QuickC,EmacsList,用于機(jī)器人編程的ParallaxC;

(4)擴(kuò)展/嵌入式語(yǔ)言,包括:嵌入到Y(jié)ahooWidgetEngine中的SpiderMonkey,AdobeFlash(ActionScript),Silverligh,TCL,Perl以及Python;

(5)Web客戶端腳本,包括:AJAX,CSS,XSLT,JavaScript,ECMAScript以及VBScript;

(6)動(dòng)態(tài)語(yǔ)言和服務(wù)器端腳本語(yǔ)言,包括:Java,PHP,C#和Ruby。

圖5.4說(shuō)明了部分編程語(yǔ)言以及這些語(yǔ)言在傳統(tǒng)編程語(yǔ)言和腳本語(yǔ)言中所處的位置。

圖5.4傳統(tǒng)編程語(yǔ)言和腳本語(yǔ)言

客戶端腳本主要的好處是在客戶端瀏覽器完成計(jì)算,這樣降低了客戶端和服務(wù)器之間來(lái)回傳輸數(shù)據(jù)的壓力,然而也存在一些弊端,包括:

(1)腳本編碼需要解釋。解釋執(zhí)行通常比編譯執(zhí)行慢。

(2)腳本編碼無(wú)法重用。腳本不能調(diào)用另外一個(gè)網(wǎng)頁(yè)中的腳本函數(shù)。

(3)腳本編碼支持模塊化但不可擴(kuò)展。可以定義單個(gè)函數(shù),但不能動(dòng)態(tài)綁定和繼承。

(4)安全性。一方面,允許編碼在瀏覽器運(yùn)行會(huì)給客戶機(jī)帶來(lái)安全隱患;

另一方面,通過(guò)瀏覽器的“查看源代碼”功能,可以查看腳本編碼,這給黑客提供了攻擊的漏洞。例如,http:///watch?v=MJNJjh4jORY提供的視頻顯示了黑客如何通過(guò)修改腳本進(jìn)入到安全系統(tǒng)。5.2.3服務(wù)器端腳本編寫(xiě)和后臺(tái)代碼計(jì)算

Web瀏覽器的計(jì)算能力受計(jì)算速度、內(nèi)存大小以及存取其他資源的限制,因此客戶端腳本只用于簡(jiǎn)單的計(jì)算,要想具備強(qiáng)大的計(jì)算能力,只能選擇服務(wù)器端計(jì)算。

服務(wù)器端腳本看上去和客戶端腳本類似,但是它能夠解決客戶端腳本存在的許多問(wèn)題。下面的代碼是服務(wù)器端腳本的例子,其中C#函數(shù)包含在HTML文件中。

<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"

"/TR/xhtml1/DTD/xhtml1transitional.dtd">

<htmlxmlns="/1999/xhtml">

<headrunat="server">

<title>ServerScripting</title>

</head><body>

<formid="Form1"runat="Server">

<asp:TextBoxID="op1"Runat="server"/>

<asp:TextBoxID="op2"Runat="server"/>

<asp:ButtonID="Button1"Text="="OnClick="add"Runat="server"/>

<asp:LabelID="result"Runat="server"/>

</form>

</body>

</html>

<scriptlanguage="C#"runat="server">

voidadd(Objectsender,EventArgse){

Int32a=Convert.ToInt32(op1.Text);

Int32b=Convert.ToInt32(op2.Text);

result.Text=Convert.ToString(a+b);

}

</script>

然而,服務(wù)器腳本依舊有著和客戶端腳本相同的問(wèn)題,包括重用性、模塊化和擴(kuò)展性。最終解決這些問(wèn)題的方法是利用服務(wù)器端計(jì)算和后臺(tái)代碼。將代碼與用戶界面分離也支持層次化體系結(jié)構(gòu)的概念,即將表示與應(yīng)用邏輯分離。5.1節(jié)討論的例子使用了服務(wù)器端計(jì)算和后臺(tái)代碼的概念。表5.1總結(jié)了四種不同的基于Web的計(jì)算模型。本章后面的內(nèi)容主要關(guān)注服務(wù)器端后臺(tái)代碼的計(jì)算模型,因?yàn)樗浅R?jiàn)的較高級(jí)的Web計(jì)算模型。表5.1基于Web的計(jì)算模型

傳統(tǒng)的過(guò)程(方法)調(diào)用會(huì)通過(guò)內(nèi)容轉(zhuǎn)換給進(jìn)程產(chǎn)生一個(gè)私有的工作區(qū),也就是調(diào)用者會(huì)置換出來(lái),并且它的執(zhí)行環(huán)境會(huì)保存在棧里。進(jìn)程代碼會(huì)控制工作區(qū)。當(dāng)進(jìn)程執(zhí)行完之后,調(diào)用者的執(zhí)行環(huán)境被恢復(fù),然后從下一條指令開(kāi)始執(zhí)行。5.3狀態(tài)管理

Web服務(wù)和Web應(yīng)用與它們的調(diào)用者松散耦合。它們通過(guò)數(shù)據(jù)交換進(jìn)行通信。調(diào)用者的控制流不會(huì)跳轉(zhuǎn)到服務(wù),但會(huì)發(fā)生環(huán)境切換。此外,Web服務(wù)和Web應(yīng)用能同時(shí)被多個(gè)用戶訪問(wèn)。Web服務(wù)和Web應(yīng)用都是基于HTTP的,而HTTP是無(wú)狀態(tài)的,即每一個(gè)包都獨(dú)立于其他包。

因此,Web服務(wù)和Web應(yīng)用的存儲(chǔ)和狀態(tài)管理完全不同于進(jìn)程調(diào)用的模式。

默認(rèn)情況下,Web服務(wù)和Web應(yīng)用都是無(wú)狀態(tài)的:每次我們調(diào)用一個(gè)服務(wù)或訪問(wèn)一個(gè)應(yīng)用,它都會(huì)認(rèn)為我們是一個(gè)新用戶。

但是,當(dāng)我們把Web作為一個(gè)新的計(jì)算平臺(tái)時(shí),很多情況下,我們都需要有狀態(tài)的計(jì)算,例如購(gòu)物車服務(wù)、計(jì)數(shù)器、計(jì)時(shí)器等。5.3.1狀態(tài)管理技術(shù)綜述

為了提供有狀態(tài)的Web服務(wù)和應(yīng)用,有些特殊問(wèn)題需要考慮。表5.2列舉了ASP.Net中不同的Web服務(wù)和Web應(yīng)用狀態(tài)管理方法。后面的討論中,我們會(huì)用Web應(yīng)用狀態(tài)管理這一術(shù)語(yǔ)。討論的技術(shù)也適用于Web服務(wù)。表5.2ASP.Net狀態(tài)管理技術(shù)5.3.2視圖狀態(tài)

當(dāng)用戶訪問(wèn)ASPX頁(yè)面時(shí),就生成一個(gè)XHTML頁(yè)面,并被發(fā)送給客戶端正在運(yùn)行的瀏覽器。當(dāng)在同一個(gè)瀏覽器會(huì)話中多次訪問(wèn)一個(gè)頁(yè)面時(shí),開(kāi)發(fā)者會(huì)在XHTML中一個(gè)隱藏字段里保存這個(gè)頁(yè)面的信息。ASPX頁(yè)面可利用語(yǔ)法ViewState[“name”]對(duì)這個(gè)字段進(jìn)行讀寫(xiě),其中“name”是一個(gè)字符串索引。隱藏字段可以保存被不同名字索引的字符串集合。

為了說(shuō)明視圖狀態(tài)變量的使用,我們?cè)O(shè)計(jì)了一個(gè)Web計(jì)算器,如圖5.5所示。該應(yīng)用提供了一個(gè)文本框,當(dāng)輸入一個(gè)數(shù)字,并且當(dāng)按下“AddtoSum”按鈕時(shí),這個(gè)數(shù)字被添加到總和中。

圖5.5數(shù)字25連加3次后總和是75

首先,用傳統(tǒng)桌面編程技術(shù)把下面代碼放到Default.aspx網(wǎng)頁(yè)后臺(tái),看看會(huì)有什么結(jié)果,其中類變量sum是用來(lái)保存總和的。

usingSystem;

publicpartialclass_Default:System.Web.UI.Page{

protectedvoidPage_Load(objectsender,EventArgse){}

Int32sum=0;

protectedvoidButton1_Click(objectsender,EventArgse){

Int32newValue=Convert.ToInt32(this.TextBox1.Text);

sum=sum+newValue;

this.Label1.Text=Convert.ToString(sum);

}

}當(dāng)我們執(zhí)行程序并點(diǎn)擊按鈕“AddtoSum”,當(dāng)前輸入值將代替目前正在運(yùn)行的總和值顯示出來(lái)。原因是,每次訪問(wèn)Web頁(yè)面或者每次點(diǎn)擊這個(gè)按鈕都會(huì)被視為一個(gè)新的會(huì)話,并且sum變量會(huì)被初始化為0。如果我們給類變量sum加上關(guān)鍵字static會(huì)出現(xiàn)什么情況呢?

staticint32sum=0;

在這種情況下,變量sum供所有會(huì)話使用,這些會(huì)話可能來(lái)自不同的瀏覽器和不同的電腦。換句話說(shuō),來(lái)自某一用戶的數(shù)據(jù)將被另一個(gè)用戶訪問(wèn)。這顯然不是這個(gè)計(jì)算器應(yīng)用希望的。視圖狀態(tài)是這個(gè)應(yīng)用最恰當(dāng)?shù)募夹g(shù),變量ViewState[“Sum”]將被存儲(chǔ)在瀏覽器中的XHTML頁(yè)面的隱藏字段里,并且僅能被這個(gè)瀏覽器使用。下面我們將給出按鈕后臺(tái)的視圖狀態(tài)版本的代碼。

publicpartialclass_Default:System.Web.UI.Page{

protectedvoidPage_Load(objectsender,EventArgse){}

Int32FinalAmt=0;

protectedvoidButton1_Click(objectsender,EventArgse){

Int32sum=0;

if(ViewState["Sum"]==null)ViewState["Sum"]=0;

else{

Int32newValue=Convert.ToInt32(this.TextBox1.Text);

sum=(Int32)ViewState["Sum"]+newValue;

ViewState["Sum"]=sum;

this.Label1.Text=sum.ToString();

FinalAmt=sum;

}

}

}

由于數(shù)據(jù)存儲(chǔ)在客戶端,視圖狀態(tài)的好處是能最大限度的減少服務(wù)器的負(fù)擔(dān),數(shù)據(jù)存儲(chǔ)在客戶端,視圖狀態(tài)可以使服務(wù)器處理更多數(shù)量的訪問(wèn)。但視圖狀態(tài)也存在一些問(wèn)題:視圖狀態(tài)僅能存儲(chǔ)字符型數(shù)據(jù),而且一個(gè)頁(yè)面的數(shù)據(jù)在另一個(gè)頁(yè)面不可見(jiàn),即使這些頁(yè)面屬于同一會(huì)話。例如,如果我們的應(yīng)用有兩個(gè)ASPX頁(yè)面:一個(gè)是添加到購(gòu)物車頁(yè)面,用于計(jì)算所有購(gòu)物的總花費(fèi);另一個(gè)是結(jié)賬頁(yè)面,用于訪問(wèn)銀行服務(wù)以通過(guò)信用卡支付花費(fèi)。因而,我們需要將來(lái)自購(gòu)物車頁(yè)面的總花費(fèi)傳遞到結(jié)賬頁(yè)面。不幸的是,結(jié)賬頁(yè)面無(wú)法讀取購(gòu)物車頁(yè)面的數(shù)據(jù)。有幾種不同的方法來(lái)解決這個(gè)問(wèn)題,例如,通過(guò)跨頁(yè)面調(diào)用,允許一個(gè)頁(yè)面調(diào)用另外一個(gè)頁(yè)面的方法。在下節(jié),我們將創(chuàng)建一個(gè)會(huì)話范圍可見(jiàn)的變量,叫做會(huì)話狀態(tài)。5.3.3會(huì)話狀態(tài)

會(huì)話狀態(tài)(SessionState)可以創(chuàng)建存儲(chǔ)服務(wù)端結(jié)構(gòu)化對(duì)象的變量,并且變量的作用域是會(huì)話范圍。存儲(chǔ)在會(huì)話狀

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論