周廣清,劉建平
ASP.NET頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞
周廣清,劉建平
目的:探討ASP.NET頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞的方法及特點(diǎn)。方法:依靠Microsoft Visual Studio開(kāi)發(fā)平臺(tái),以具體實(shí)例演示頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞,并對(duì)其進(jìn)行分析。結(jié)果:機(jī)制不同的頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞,其外觀效果不同,對(duì)系統(tǒng)的影響也不同。結(jié)論:頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞方案的選擇對(duì)網(wǎng)站或Web應(yīng)用程序的安全性、穩(wěn)定性、速度有重大影響,應(yīng)根據(jù)自身需要選擇合適的方法。
.NET Framework;ASP.NET;C#;Visual Studio;頁(yè)面跳轉(zhuǎn);參數(shù)傳遞
ASP.NET[1]是微軟.NET Framework[2]類(lèi)庫(kù)核心技術(shù)之一,廣泛應(yīng)用于網(wǎng)站建設(shè)和Web應(yīng)用程序開(kāi)發(fā)。ASP.NET不但功能豐富,而且大大減少了代碼編寫(xiě)工作量,易于掌握,深受IT程序員的歡迎,是微軟公司對(duì)于世界信息產(chǎn)業(yè)的重大貢獻(xiàn)。C#[3-4]也稱(chēng)C Sharp,是ASP.NET的一種腳本語(yǔ)言。Microsoft Visual Studio是ASP.NET的調(diào)試、編譯、部署平臺(tái),支持C#、F#、VB。
ASP.NET代碼在具有.NET Framework環(huán)境的服務(wù)器端執(zhí)行??蛻?hù)端通過(guò)瀏覽器將請(qǐng)求發(fā)送到服務(wù)器,服務(wù)器執(zhí)行程序代碼并將執(zhí)行結(jié)果發(fā)還到客戶(hù)端,客戶(hù)端瀏覽器顯示執(zhí)行結(jié)果。從一個(gè)網(wǎng)頁(yè)跳轉(zhuǎn)到另一個(gè)網(wǎng)頁(yè)(也稱(chēng)重定)時(shí),經(jīng)常需要將源頁(yè)面的重要信息(參數(shù))傳遞到目標(biāo)頁(yè)面,這就是頁(yè)面間的參數(shù)傳遞。頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞是網(wǎng)站或Web應(yīng)用程序開(kāi)發(fā)的重要組成部分。
在下文中,指令的語(yǔ)法是C#。d1是目標(biāo)頁(yè)面的名稱(chēng),p1、p2為參數(shù)名稱(chēng),v1、v2、v3、v4為參數(shù)的值,s1、s2為字符串變量。
(1)將傳遞的參數(shù)寫(xiě)入到打開(kāi)頁(yè)面的指令中。Response.Redirect"d1.aspx?p1=v1&p2=v2");
或:Response.Write"<script>window.open'd1.aspx?p1=v1&p2=v2','_blank')</script>");
或:Server.Transfer"d1.aspx?p1=v1&p2=v2");
或:Server.Execute"d1.aspx?p1=v1&p2=v2");
或:在導(dǎo)航控件如HyperLink、TreeView等,設(shè)置屬性NavigateUrl="~/d1.aspx?p1=v1&p2=v2"
或:在瀏覽器URL輸入http://d1.aspx?p1=v1& p2=v2"
以上C#指令的語(yǔ)法是:目標(biāo)頁(yè)面文件名和傳遞的參數(shù)之間以?隔開(kāi);參數(shù)與參數(shù)之間以&隔開(kāi),等號(hào)左邊是參數(shù)名稱(chēng),右邊是參數(shù)的值,類(lèi)型是字符串,可以傳遞多個(gè)參數(shù)。
瀏覽器URL、導(dǎo)航控件、Response.Redirect()、Response.Write()頁(yè)面跳轉(zhuǎn)或重定向發(fā)生在客戶(hù)端瀏覽器,傳遞的參數(shù)在URL是可見(jiàn)的,能被修改甚至被SQL注入[5],會(huì)帶來(lái)潛在的安全風(fēng)險(xiǎn);Server.Transfer()、Server.Execute()[6]頁(yè)面跳轉(zhuǎn)或重定向發(fā)生在Web服務(wù)器,傳遞的參數(shù)在URL是隱藏的,而且也能減少客戶(hù)端和服務(wù)器之間的應(yīng)答次數(shù),降低網(wǎng)絡(luò)負(fù)載,使程序運(yùn)行更加流暢,但源頁(yè)面和目標(biāo)頁(yè)面必須屬于同一個(gè)網(wǎng)站或Web應(yīng)用程序。Server.Transfer()關(guān)閉源頁(yè)面,跳轉(zhuǎn)到目標(biāo)頁(yè)面;Server.Execute()不關(guān)閉源頁(yè)面,將目標(biāo)頁(yè)面的執(zhí)行結(jié)果返回到源頁(yè)面。
在目標(biāo)頁(yè)面d1.aspx中,用Request.QueryString將參數(shù)p1和p2取出:
Request.QueryString["p1"];
Request.QueryString["p2"];
或:Request.QueryString[0];
Request.QueryString[1];
方括號(hào)內(nèi)的數(shù)值是參數(shù)名稱(chēng)或參數(shù)在查詢(xún)字符串中的索引位置,0表示第1個(gè)參數(shù),1表示第2個(gè)參數(shù)。
(2)Session[7](會(huì)話(huà))傳遞參數(shù)。
網(wǎng)站和Web應(yīng)用程序是由多用戶(hù)同時(shí)從客戶(hù)端訪問(wèn)或操作的。當(dāng)用戶(hù)打開(kāi)網(wǎng)站或登錄Web應(yīng)用程序時(shí),用戶(hù)就和Web服務(wù)器建立一個(gè)會(huì)話(huà),直到用戶(hù)主動(dòng)退出(關(guān)閉網(wǎng)站或應(yīng)用程序)或在20 min內(nèi)(Web.Config文件設(shè)定)不進(jìn)行任何操作,此次會(huì)話(huà)才告結(jié)束。Web服務(wù)器同時(shí)存在多個(gè)(大型網(wǎng)站在高峰時(shí)段多達(dá)千萬(wàn))會(huì)話(huà),為每個(gè)會(huì)話(huà)分配一個(gè)SessionID,作為這次會(huì)話(huà)的唯一標(biāo)志。當(dāng)用戶(hù)向服務(wù)器發(fā)出請(qǐng)求時(shí),瀏覽器會(huì)將用戶(hù)的SessionID自動(dòng)附加在HTTP頭信息中;當(dāng)服務(wù)器處理完成后,根據(jù)SessionID將結(jié)果返回給用戶(hù),有了會(huì)話(huà)及其SessionID機(jī)制,Web服務(wù)器才能知道是誰(shuí)提交的請(qǐng)求,將結(jié)果返回給誰(shuí)。會(huì)話(huà)除了SessionID,還包含很多其他信息,頁(yè)面間傳遞的參數(shù)就是其一。
頁(yè)面跳轉(zhuǎn)的方法在上面已經(jīng)介紹,用會(huì)話(huà)傳遞參數(shù)時(shí),將頁(yè)面跳轉(zhuǎn)指令中目標(biāo)頁(yè)面后面的查詢(xún)字符串去掉即可,如:Response.Redirect("d1.aspx");
會(huì)話(huà)內(nèi)傳遞參數(shù)只在本次會(huì)話(huà)有效,其他會(huì)話(huà)不能讀取。在源頁(yè)面將參數(shù)p1和p2的字符串值存入Session:
Session["p1"]=v1;
Session["p2"]=v2;
Session信息一旦定義,隨后打開(kāi)的其他頁(yè)面都能將Session中存儲(chǔ)的參數(shù)值讀取到字符串變量:
S1=(string)(Session["p1"]);
S2=(string)(Session["p2"]);
或修改在Session中存儲(chǔ)的參數(shù)值:
Session["p1"]=v3; Session["p2"]=v4;
Session的信息存儲(chǔ)在服務(wù)器內(nèi)存中,當(dāng)Web服務(wù)器同時(shí)存在大量Session時(shí),Session的信息會(huì)消耗掉大量?jī)?nèi)存,導(dǎo)致網(wǎng)站或Web應(yīng)用程序運(yùn)行速度下降甚至癱瘓。因此,在編寫(xiě)ASP.NET網(wǎng)站或程序時(shí),在合適的時(shí)機(jī),將無(wú)用的Session信息清除。清除p1:Session.Remove("p1"); 清 除 p2:Session.Remove("p2");清除所有:Session.RemoveAll()[8]或Session.Clear()[7];當(dāng)會(huì)話(huà)結(jié)束時(shí),其Session信息會(huì)自動(dòng)全部清除,釋放內(nèi)存。用戶(hù)在設(shè)定的時(shí)間內(nèi)沒(méi)有任何操作,Session自動(dòng)結(jié)束,就是為了釋放閑置會(huì)話(huà)占用的資源。
(3)Application[8]傳遞參數(shù)。
Application存儲(chǔ)和傳遞參數(shù)類(lèi)似于Session,不同之處是Session只在本次會(huì)話(huà)有效,其他會(huì)話(huà)不能讀取,而Application為所有的會(huì)話(huà)共享,能讀取或修改。將參數(shù)p1和p2的字符串值存入Application:
Application["p1"]=v1;
Application["p2"]=v2;
Application信息一旦定義,隨后打開(kāi)的其他頁(yè)面都能將Application中存儲(chǔ)的參數(shù)值讀取到字符串變量:
S1=Application["p1"].ToString();
S2=Application["p2"].ToString();
由于網(wǎng)站存在大量并發(fā)用戶(hù),為了數(shù)據(jù)的一致性,最好在修改前鎖定,修改后解鎖:
Application.Lock();
Application["p1"]=v3;
Application["p2"]=v4;
Application.UnLock();
Application一般用來(lái)定義重要公用信息,如數(shù)據(jù)庫(kù)連接信息或用戶(hù)訪問(wèn)計(jì)數(shù)器等,很少用于一般的參數(shù)傳遞。只要應(yīng)用程序不停止,Application中的內(nèi)容就不會(huì)消失。
(4)Cookie[9]傳遞參數(shù)。
在客戶(hù)端C盤(pán)操作系統(tǒng)用戶(hù)文件夾內(nèi)有一個(gè)隱藏的文件夾cookies,其中cookie文件以較小的文本信息存在,它記錄了用戶(hù)訪問(wèn)網(wǎng)站的歷史記錄、用戶(hù)首選項(xiàng)甚至用戶(hù)名和密碼,也用于存儲(chǔ)頁(yè)面交換信息。用戶(hù)在訪問(wèn)網(wǎng)站或使用Web應(yīng)用程序時(shí),Cookie在客戶(hù)端和服務(wù)器之間傳遞。Cookie文件通常限制為4 096 B,以節(jié)約網(wǎng)絡(luò)帶寬,并且一個(gè)客戶(hù)端最多可使用20個(gè)Cookie,如果不指定Cookie的有效期,會(huì)話(huà)結(jié)束時(shí)Cookie即被丟棄。通過(guò)瀏覽器的“internet選項(xiàng)”可以清除Cookie,避免敏感數(shù)據(jù)泄露。Cookie僅能存儲(chǔ)String類(lèi)型的值,在將其他類(lèi)型存儲(chǔ)到Cookie之前,須將它們轉(zhuǎn)換為字符串。不要在Cookie中存放不應(yīng)由用戶(hù)掌握的內(nèi)容,如數(shù)據(jù)庫(kù)的用戶(hù)名和密碼,也不要存放能控制網(wǎng)站的內(nèi)容。每個(gè)Cookie必須有一個(gè)唯一的名稱(chēng),以便瀏覽器識(shí)別,名稱(chēng)相同會(huì)導(dǎo)致前一個(gè)Cookie被覆蓋。
在源頁(yè)面創(chuàng)建Cookie名稱(chēng)為dataSend,有效期1 d。
HttpCookie myCookie=new HttpCookie("data Send");
myCookie.Expires=DateTime.Now.AddDays(1);
設(shè)置子鍵p1和p2的值,并存入到dataSend:
myCookie.Values.Add("p1",v1);
myCookie.Values.Add("p2",v2);
Response.AppendCookie(myCookie);
在隨后打開(kāi)的其他頁(yè)面將dataSend中存儲(chǔ)的鍵值讀取到字符串變量,在讀取Cookie之前,應(yīng)確保該Cookie存在,否則會(huì)收到NullReferenceException報(bào)錯(cuò):
if(Request.Cookies["dataSend"]!=null)
{S1=Request.Cookies["dataSend"]["p1"];
S2=Request.Cookies["dataSend"]["p2"];}
(5)獲取源頁(yè)面公共屬性[10]。
如果源頁(yè)面和目標(biāo)頁(yè)面位于同一個(gè)ASP.NET應(yīng)用程序中,在源頁(yè)面將要傳遞的參數(shù)定義為公共屬性,目標(biāo)頁(yè)面就可以獲取此公共屬性的值。重要私密信息不要作為公共屬性公開(kāi),以免被惡意用戶(hù)獲取。
在源頁(yè)面sp1.aspx將要傳遞的參數(shù)p1、p2定義為公共屬性:
public String p1{get{return v1;}}
public String p2{get{return v2;}}
在目標(biāo)頁(yè)面d1.aspx首先對(duì)源頁(yè)面進(jìn)行強(qiáng)類(lèi)型引用,即可讀取源頁(yè)面的公共屬性:
<%@PreviousPageType VirtualPath="~/sp1.aspx" %>
S1=PreviousPage.p1;
S2=PreviousPage.p2;
(6)獲取源頁(yè)面控件的值[10]。
如果源頁(yè)面和目標(biāo)頁(yè)面位于同一個(gè)ASP.NET應(yīng)用程序中,目標(biāo)頁(yè)面可以獲取源頁(yè)面控件的值。此方法也不宜傳遞重要的私密信息。
在源頁(yè)面將要傳遞參數(shù)p1、p2的值賦予一些控件,例如TextBox1、TextBox2,在目標(biāo)頁(yè)面即可獲取源頁(yè)面控件的值:
if(Page.PreviousPage!=null)
{
TextBox SourceTextBox1=(TextBox)Page.PreviousPage.FindControl("TextBox1");
if(SourceTextBox1!=null)
{s1=SourceTextBox1.Text;}
TextBox SourceTextBox2=(TextBox)Page.PreviousPage.FindControl("TextBox2");
if(SourceTextBox2!=null)
{s2=SourceTextBox2.Text;}
}
通過(guò)ASP.NET技術(shù)開(kāi)發(fā)的應(yīng)用程序是3層結(jié)構(gòu):數(shù)據(jù)庫(kù)服務(wù)器、Web服務(wù)器、客戶(hù)端??蛻?hù)端通過(guò)Web服務(wù)器與數(shù)據(jù)庫(kù)服務(wù)器交換數(shù)據(jù),不但加強(qiáng)了數(shù)據(jù)庫(kù)服務(wù)器的安全,而且使應(yīng)用程序在網(wǎng)絡(luò)中的部署和更新更加簡(jiǎn)單,客戶(hù)端只需通過(guò)瀏覽器網(wǎng)址訪問(wèn)Web服務(wù)器,應(yīng)用程序更新或升級(jí)時(shí)只需要更新Web服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器。目前,ASP.NET在醫(yī)院信息系統(tǒng)研發(fā)中得到了大量應(yīng)用,“軍衛(wèi)一號(hào)”醫(yī)院信息系統(tǒng)的新版電子病歷系統(tǒng)(electronic medical record system,EMRS)醫(yī)護(hù)工作站就是通過(guò)ASP. NET技術(shù)開(kāi)發(fā)的。
我們通過(guò)ASP.NET技術(shù)開(kāi)發(fā)了在院患者及其住院費(fèi)用查詢(xún)軟件,其中就使用了Session傳遞參數(shù)。關(guān)鍵步驟如下:
(1)軟件運(yùn)行時(shí)打開(kāi)頁(yè)面deptTree.aspx,在樹(shù)狀視圖TreeView1中顯示臨床科室及其患者列表?;颊吡斜戆颊咝彰⒋蔡?hào)、住院號(hào)、住院次。當(dāng)單擊某一患者時(shí),在樹(shù)狀視圖單擊事件的方法中將該患者的住院號(hào)、住院次寫(xiě)入Session參數(shù)pid、vid,并打開(kāi)目標(biāo)頁(yè)面CRPbill.aspx:
Session["pid"]=TreeView1.SelectedValue.Substring(0,TreeView1.SelectedValue.IndexOf("_"));
Session["vid"]=TreeView1.SelectedValue.Substring(TreeView1.SelectedValue.IndexOf("_")+1);
Response.Write("<script>window.open('CRPbill. aspx','_blank')</script>");
(2)在目標(biāo)頁(yè)面CRPbill.aspx中,將患者的住院號(hào)和住院次取出并賦值給字符串變量s1、s2:
s1=(string)(Session["pid"]);
s2=((string)(Session["vid"]);
利用s1、s2構(gòu)造數(shù)據(jù)庫(kù)查詢(xún)SQL命令,查詢(xún)此患者的住院費(fèi)用明細(xì),通過(guò)報(bào)表控件CrystalReport Viewer1顯示。
上文介紹的是常用的頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞方法,每一種都有其適用范圍和特點(diǎn)。就頁(yè)面跳轉(zhuǎn)來(lái)說(shuō),推薦使用Server.Transfer(),它使頁(yè)面跳轉(zhuǎn)或重定向發(fā)生在服務(wù)器,減少了客戶(hù)端和服務(wù)器之間的應(yīng)答次數(shù),降低了網(wǎng)絡(luò)負(fù)載,而且跳轉(zhuǎn)的頁(yè)面和傳遞的參數(shù)在URL是不可見(jiàn)的,對(duì)外隱藏了系統(tǒng)的內(nèi)部結(jié)構(gòu),提高了系統(tǒng)的安全性。Cookie文件傳遞參數(shù)雖然增加了少許網(wǎng)絡(luò)負(fù)載,但對(duì)于百兆以上的局域網(wǎng),Cookie負(fù)載可以忽略,但需要注意的是:不要用Cookie傳遞秘密數(shù)據(jù)。使用Session傳遞參數(shù)時(shí),應(yīng)及時(shí)清除Session信息,釋放服務(wù)器內(nèi)存。
.NET Framework是微軟公司開(kāi)發(fā)的豐富的類(lèi)庫(kù)平臺(tái),還有很多頁(yè)面跳轉(zhuǎn)和參數(shù)傳遞的方法,需要我們?cè)谲浖_(kāi)發(fā)過(guò)程中不斷地發(fā)現(xiàn)、探討和總結(jié),以便找到更多、更適合自己的方法。
(????)(????)
[1]奚江華.圣殿祭司的ASP.NET2.0開(kāi)發(fā)詳解——使用C#最佳應(yīng)用與實(shí)踐指南[M].2版.北京:電子工業(yè)出版社,2008.
[2]王毅.Net.Framework3.5開(kāi)發(fā)技術(shù)詳解[M].北京:人民郵電出版社,2009.
[3]Sharp J.Visual C#2008從入門(mén)到精通[M].周靖,譯.北京:清華大學(xué)出版社,2009.
[4]MacDonald M.ASP.NET 3.5從入門(mén)到精通(C#2008版)[M].施宏斌,馬煜,譯.2版.北京:清華大學(xué)出版社,2010.
[5]祝種谷,張晟.ASP.NET防范SQL注入攻擊的研究與實(shí)踐[J].電腦知識(shí)與技術(shù),2010,6(27):7 724-7 725.
[6]邱曉榮.ASP.NET頁(yè)面間數(shù)據(jù)傳遞方法的研究與實(shí)現(xiàn)[J].福建電腦,2008(4):155-156.
[7]徐少華,張華偉,李浩.在ASP.NET中實(shí)現(xiàn)Web頁(yè)面值傳遞方法的比較[J].武漢理工大學(xué)學(xué)報(bào),2006,28(6):37-40.
[8]陳啟祥,左強(qiáng).ASP.NET頁(yè)面間傳值方法研究[J].計(jì)算機(jī)工程,2006,32(8):113-114,117.
[9]唐晏.ASP.NET頁(yè)面之間數(shù)據(jù)傳遞的實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用研究,2006(5):228-229,235.
[10]Onion F.ASP.NET基礎(chǔ)教程——C#案例版[M].施諾,譯.北京:清華大學(xué)出版社,2003.
(收稿:2014-02-28 修回:2014-06-15)
(欄目責(zé)任編校:李惠萍 傅 靂)
·醫(yī)械臨床·
ASP.NET page redirecting and parameter transmitting
ZHOU Guang-qing,LIU Jian-ping
(Information Center,the 401st Hospital of the PLA,Qingdao 266071,Shandong Province,China)
ObjectiveTo analyze the natures and methods of ASP.NET page redirecting and parameter transmitting. MethodsWith Microsoft Visual Studio platform,some example was used to demonstrate and analyze page redirecting and parameter transmitting.ResultsPage redirecting and parameter transmitting had different appearances and influences on the system while the mechanism varied.ConclusionThe scheme of page redirecting and parameter transmitting may affect greatly the safety,stability and velocity of the website and web application programs,so has to be chosen properly.[Chinese Medical Equipment Journal,2015,36(3):73-75,102]
.NET Framework;ASP.NET;C#;Visual Studio;page redirecting;parameter transmitting
R318;TP311.52
A
1003-8868(2015)03-0073-04
10.7687/J.ISSN1003-8868.2015.03.073
周廣清(1969—),男,副主任,副主任技師,主要從事醫(yī)院網(wǎng)絡(luò)信息方面的研究工作,E-mail:zhougq401@sina.com。
266071山東青島,解放軍401醫(yī)院信息科(周廣清,劉建平)
劉建平,E-mail:liujp401@sina.com