版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電工電子技術(shù)(第3版) 課件 3.6 三相異步電機(jī)結(jié)構(gòu)
- 2024年無(wú)紡布及其制品項(xiàng)目資金申請(qǐng)報(bào)告
- 銀行內(nèi)部控制審計(jì)辦法制度
- 采購(gòu)部門內(nèi)部管理與溝通協(xié)作制度
- 議論散文《門》課件
- 銷售工作總結(jié)大全(15篇)
- 《設(shè)備的維修與養(yǎng)護(hù)》課件
- 論壇推廣高級(jí)解決方案-案例(倩碧)
- 《供配電線路》課件
- 廣東省東莞市第七中學(xué)2025屆高三下學(xué)期聯(lián)合考試英語(yǔ)試題含解析
- 《中小企業(yè)生存之道》課件
- 前程無(wú)憂招聘測(cè)評(píng)題庫(kù)及答案
- 人教版-六年級(jí)上冊(cè)數(shù)學(xué)-百分?jǐn)?shù)(一)單元測(cè)試(含答案)
- 盆腔膿腫護(hù)理病例討論
- 2024年決戰(zhàn)行測(cè)5000題言語(yǔ)理解與表達(dá)(培優(yōu)b卷)
- 正確看待苦與樂(lè)課件
- 【培訓(xùn)課件】建設(shè)工程施工工地消防安全管理
- 廣東省深圳市2023-2024學(xué)年高一上學(xué)期期末考試物理試題(含答案)
- 《LED照明知識(shí)》課件
- 綠色建筑概論學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- GB/T 44481-2024建筑消防設(shè)施檢測(cè)技術(shù)規(guī)范
評(píng)論
0/150
提交評(píng)論