Asp net夜話之二 asp net內建物件
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
在今天我主要要介紹的有如下知識點:
Request
Response
Server
Session
Cookie
Application
<%%>及<%=%>表示式
準確地說,asp.net並沒有內建物件這一說,jsp裡確實把request、response這些當作jsp的內建物件,這裡只不過是借用了一下jsp的說法而已。上面提到的很多都是在做asp.net開發時無需new就能使用的物件(類似的還有很多,在asp.net中所有的網頁都是繼承自System.Web.UI.Page這個類,上面的提到多是Page類的屬性)。
在Web中處於中心的是Web伺服器,用來處理客戶端的HTTP請求。由於HTTP是一種無狀態的協議,也就是它並不記得上一次誰請求過它,不會主動去詢問客戶端,只有當客戶端主動請求之後,伺服器才會響應。
Request
Request封裝了客戶端請求資訊。Request的常見屬性如下:
屬性名 |
值型別 |
說明 |
ApplicationPath |
String |
獲取請求的資源在網站上的根路徑 |
ContentEncoding |
Encoding |
設定請求物件的編碼 |
Cookies |
HttpCookieCollection |
客戶端傳送到伺服器的Cookie集合 |
QueryString |
NameValueCollection |
當前請求的查詢字串集合 |
UrlReferrer |
Uri |
獲取使用者由哪個url跳轉到當前頁面 |
Response
Response代表了伺服器響應物件。每次客戶端發出一個請求的時候,伺服器就會用一個響應物件來處理這個請求,處理完這個請求之後,伺服器就會銷燬這個相應物件,以便繼續接受其它客服端請求。
Response常用屬性如下:
屬性名 |
值型別 |
說明 |
Charset |
string |
表示輸出流的所使用的字符集 |
ContentEncoding |
Encoding |
設定輸出流的編碼 |
ContentLength |
Int |
輸出流的位元組大小 |
ContentType |
string |
輸出流的HTTP MIME型別 |
Cookies |
HttpCookieCollection |
伺服器傳送到客戶端的Cookie集合 |
Output |
TextWriter |
伺服器響應物件的字元輸出流 |
RedirectLocation |
string |
將當前請求重定向 |
Response常用方法
屬性名 |
返回值型別 |
說明 |
AppendCookie |
void |
向響應物件的Cookie集合中增加一個Cookie |
Clear |
void |
清空緩衝區中的所有內容輸出 |
Close |
void |
關閉當前伺服器到客戶端的連線 |
End |
void |
終止響應,並且將緩衝區中的輸出傳送到客戶端 |
Redirect |
void |
重定向當前請求 |
下面距離說明,用Dreamweaver8建立一個aspx頁面,程式碼如下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>Request例子</title>
- </head>
- <body>
- <table border="1" width="600px" bordercolordark="#2B72A2" bordercolorlight="#993333">
- <tr><td colspan="2" bgcolor="#80ffff">Request</td></tr>
- <tr><td>ApplicationPath(網站路徑)</td><td><%=Request.ApplicationPath%></td></tr>
- <tr><td>ContentEncoding(網頁編碼)</td><td><%=Request.ContentEncoding%></td></tr>
- <tr><td>Cookies個數</td><td><%=Request.Cookies.Count%></td></tr>
- <tr><td>QueryString個數</td><td><%=Request.QueryString.Count%></td></tr>
- <tr><td>UrlReferrer(上一請求頁面)</td><td> <%=Request.UrlReferrer%></td></tr>
- <tr><td colspan="2" bgcolor="#80ffff">Response</td></tr>
- <tr><td>Charset</td><td><%=Response.Charset%></td></tr>
- <tr><td>ContentEncoding(網頁編碼)</td><td><%=Response.ContentEncoding%></td></tr>
- <tr><td>Cookies個數</td><td><%=Response.Cookies.Count%></td></tr>
- <tr><td>ContentType</td><td><%=Response.ContentType%></td></tr>
- </table>
- </body>
- </html>
將新建的頁面儲存為RequestAndResponse.aspx並儲存到C:/Inetpub/wwwroot下,然後開啟瀏覽器在位址列中輸入:http://localhost/RequestAndResponse.aspx,實際上url地址不區分大小寫,以上地址全部小寫也沒有關係,執行結果如下:
從上面的結果我們可以看出利用Dreamweaver建立的網頁,如果採用預設編碼,請求物件的字元編碼是UTF-8,而響應物件的編碼為gb2312。這樣極有可能可能產生亂碼問題。所謂亂碼,就是用一種編碼的字串卻用了另一種編碼來顯示,造成不能正常顯示的現象。就像我用普通話說“請給我來一杯茶“,結果是一個只懂德育的人聽了,他自然聽不懂我說什麼,不能正常交流。另外,需要說明的是常見的伺服器響應的ContentType是“text/html”,代表響應是以HTML檔案形式傳輸的。還有一些其它形式的ContentType,如下:
image/jpeg:響應物件是jpeg圖片
text/xml:響應物件是xml檔案
text/javascript:響應物件是javascript指令碼檔案
Response的ContentType屬性預設是“text/html”,表示伺服器以HTML檔案響應客戶端請求,如果需要用其它方式響應客戶端請求,則需要設定ContentType屬性。假如我們需要用jpeg圖片的格式響應客戶端請求,則需要設定ContentType屬性為“image/jpeg”,然後將圖片內容輸出到客戶端,這樣客戶端就會看到jpeg格式的圖片而不是HTML檔案。
Server
Server物件是用於獲取伺服器的相關資訊的物件。它常用方法如下:
屬性名 |
返回值型別 |
說明 |
Execute |
void |
執行指定的資源,並且在執行完之後再執行本頁的程式碼 |
HtmlDecode |
string |
消除對特殊字串編碼的影響 |
HtmlEncode |
string |
對特殊字串進行編碼 |
MapPath |
string |
獲取指定相對路徑在伺服器上的無力路徑 |
Transfer |
void |
停止執行當前程式,執行指定的資源 |
UrlDecode |
string |
對路徑字串進行解碼 |
UrlEncode |
string |
對路徑字串進行編碼 |
上面的方法光從概念上來說,似乎還是讓人不能分清他們到底有什麼作用,特別Excure/ Transfer、HtmlEncode(HtmlDecode)/ UrlEncode(UrlDecode)這兩組。在講述他們分別之前先講述MapPath這個方法的作用,在我們上傳檔案的時候要以物理路徑儲存上傳檔案到伺服器,而我們使用得最多的是相對URL地址,這個方法就起到了將相對URL地址轉換成伺服器物理路徑的作用。
為了說明Excure/ Transfer及HtmlEncode(HtmlDecode)/ UrlEncode(UrlDecode)的區別,我們還是用例項程式碼來展示,用Dreamweaver8建立一個aspx頁面,程式碼如下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>Server物件的常見方法例項</title>
- </head>
- <body>
- <ul>
- <li>Server.MapPath(".")=<%=Server.MapPath(".")%></li>
- <li><%=Server.HtmlEncode("<h1>Asp.net夜話之二:asp.net內建物件</h1>")%></li>
- <li><h1>Asp.net夜話之二:asp.net內建物件</h1></li>
- <li><%=Server.UrlEncode("<a href=/"http://blog.csdn.net/zhoufoxcn/">周公的專欄</a>")%></li>
- <li><a href="http://blog.csdn.net/zhoufoxcn">周公的專欄</a></li>
- </ul>
- </body>
- </html>
將新建的頁面儲存為ServerDemo.aspx並儲存到C:/Inetpub/wwwroot下,然後開啟瀏覽器在位址列中輸入:http://localhost/Request/serverdemo.aspx,執行結果如下:
從Server.MathPath(“.”)輸出“C:/Inetpub/wwwroot”,證明確實能獲取到相對路徑的在伺服器上的實際實體地址。
在上面的例子中我們想在網頁中輸出HTML程式碼,如果直接輸出往往得不到想要的效果,這時可以藉助HtmlEncode方法對要輸出的HTML程式碼進行編碼,這樣輸出到瀏覽器上的時候就能看到HTML程式碼,而不是HTML形式的效果。HtmlDecode方法則是用來消除這種影響。
如果我們直接輸出“<a href="http://blog.csdn.net/zhoufoxcn">周公的專欄</a>”這個字串的話,在網頁上會顯示一個超級連結,但是有時候我們希望把這個超級連結作為QueryString的一個引數,由於url地址的特殊性,比如“:”、“/”等字串在URL地址中有特殊的含義,要想輸出這些字元,直接輸出是不行的,需要進行某種轉換,並且將來還能轉換回來。經過UrlEncode方法轉換之後,“:”、“/”分別轉換成了“%3a”和“%2f”這樣的字元,並且漢字也進行了轉換。UrlDecode方法則是將“%3a”和“%2f”等這樣的字元轉換成我們原本要表示的字元。
前面我們提到,在HTTP中,伺服器與客戶端並不是時時保持連線狀態,而是伺服器被動地等待客戶傳送請求,伺服器才進行響應。因此,在大部分情況下,伺服器並不會管客戶端是否還依然存在。
在這種情況下,假如使用者通過訪問一些需要許可權的頁面,在他輸入正確的使用者名稱和密碼之後第一次他訪問a頁面,隔幾分鐘之後再訪問同樣需要許可權才能訪問的b頁面,這是他還需要輸入使用者名稱和密碼嗎?按照清理來說如果這個時間間隔比較短,我們不應該要求頻繁使用者輸入這些資訊,可是伺服器又不記錄這些資訊,我們有沒有辦法解決這個問題呢?
答案是有的,就是利用Session或者Cookie。
Session
Session物件用來儲存與特定使用者相關的資訊,Session中的資料儲存在伺服器端,在客戶端需要的時候建立Session,在客戶端不需要的時候銷燬Session,使它不再佔用伺服器記憶體。前面說了伺服器並不管客戶端是否依然存在,因而它也無法確定客戶端什麼時間不再使用它,但是如果在客戶端不再用的時候不及時銷燬Session的話,伺服器很快就會記憶體不足。為了解決這個問題,給Session加了一個生命週期,當伺服器發現Session超過了它的生命週期,就會釋放該Session所佔用的記憶體空間。在asp.net中Session的預設生命週期是20分鐘,也就是當我們在9:00的時候設定了一個Session,如果在9:20之前客戶端沒有任何請求,那麼它的生命週期就到9:20分鐘結束。但是一旦使用者在9:19又向伺服器傳送了一個請求,那麼這個Session現在的生命週期就是在當前時間的基礎上再加上20分鐘,也就是此時這個Session的生命週期是到9:39結束。
Session具有以下特點:
Session中的資料儲存在伺服器端;
Session中可以儲存任意型別的資料;
Session預設的生命週期是20分鐘,可以手動設定更長或更短的時間。
假設我們要設定一個Session用來儲存使用者名稱,這個Session的名字是“UserName”,值是“zhoufoxcn”,程式碼如下:
- Session[“UserName”]=”zhoufoxcn”;
一個網站裡用到Session的地方肯定不止一個,所以在設定和獲取Session的時候通過Session的名在來操作,並且Session被設定成能儲存任意型別的物件(即Object型別),所以獲取Session的時候要根據設定的時候的實際型別進行響應的強制型別轉換(當然如果在Session中存放像int/byte/short這樣的資料型別,獲取Session的值算是一種拆箱操作而不是強制型別轉換),對於上面的Session,獲取Session的值的程式碼如下:
- string username=(string)Session[“UserName”];
對於上面的程式碼,有個問題需要注意:當沒有設定相應的Session或者Session因為超過生命週期而被銷燬時,上面的程式碼有可能丟擲異常。我們可以先判斷是否存在指定名稱的Session,如果不存在就不用獲取了,僅當存在的情況下才獲取Session的值,上面的程式碼可以改進如下:
- string userName;
- if(Session["UserName"]!=null)
- {
- //當指定名稱的Session存在時,獲取指定Session的值
- userName=(string)Session["UserName"];
- }
Cookie
Cookie物件和Session物件一樣也是用來儲存特定的使用者相關的資料,不過Session不同的是Cookie儲存在客戶端而不是伺服器上,每次客戶端發出請求的時候都會把Cookie一起傳送到伺服器,伺服器每次響應客戶端請求的時候會重新把Cookie傳送到客戶端儲存。
Cookie儲存資料有以下特點:
Cookie中的資料儲存在客戶端;
Cookie中只能儲存字串型別的資料,如果需要在Cookie中儲存其它型別資料,需要將其轉換成字串型別後儲存;
Cookie也有其預設生命週期,也可以手動設定,最大可設定成50年之後過期。
同Session的情況一樣,有可能在一個網站中使用到的Cookie不止一個,我們仍通過Cookie的名稱來區分不同的Cookie。
設定Cookie的過程就是在伺服器的響應物件Response的Cookie集合中增加一個Cookie的實際,Response物件會把這個Cookie集合中的所有Cookie都發送客戶端。程式碼如下(仍以儲存使用者名稱為例):
- HttpCookie cookie = new HttpCookie("UserName", "zhoufoxcn");
- Response.Cookies.Add(cookie);
獲取Cookie就是從客戶端的請求物件中找到對應名稱的Cookie,當然也有可能出現Cookie不存在的情況,所以在獲取之前也需要檢查指定名稱的Cookie是否存在,大媽如下:
- string userName;
- if (Request.Cookies["UserName"] != null)
- {
- userName = Request.Cookies["UserName"].Value;
- }
細心的朋友可能會留意到前面講到Session和Cookie的時候,我都說他們是針對特定使用者儲存的資料,也就是那些資料並不是每個人都能用到。Session和Cookie一般用來一些針對特定使用者的資訊,比如用於儲存使用者名稱等,因為是針對特定使用者的,所以不會針對張三設定使用者名稱儲存在Session或者Cookie中之後再去或者這個值的時候得到的是李四的使用者名稱。但是在某些情況下,我們又希望儲存一些共有資訊,這樣大家都能設定或者獲取,比如自從伺服器啟動以來某個頁面被開啟的次數,這時用Session或者Cookie就不合適了。這就需要用Application了。
Application
Application和Session儲存的資料型別和儲存位置一樣,都是存放Object型別的資料(也就是任意型別),並且存放在伺服器上,不同的Application中的資料可以由網站中所有的使用者來設定或者獲取。並且Application中存放的資料沒有時間限制,除非我們手動刪除或者伺服器重新啟動,否則存放的資料都會丟失。
下面是Session、Cookie和Application的區別:
名稱 |
使用範圍 |
儲存位置 |
存放資料型別 |
生命週期 |
Session |
特定使用者 |
伺服器 |
Object,也就是任意型別 |
有,可以自行設定 |
Cookie |
特定使用者 |
客戶端 |
String,也就值字串 |
可以自行設定 |
Application |
所有使用者 |
伺服器 |
Object,也就是任意型別 |
無 |
下面我們以一個小例子來說明Session和Application的區別。
我們用Dreamweaver8建立兩個頁面,分別為SessionTest.aspx和ApplicationTest.aspx,儲存到C:/Inetpub/wwwroot目錄下,它們的程式碼都是一樣的,如下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>Application和Session的例子</title>
- </head>
- <body>
- <%
- //如果沒有設定名為"ApplicationCount"的Application
- int applicationCount=1;
- int sessionCount=1;
- if(Application["ApplicationCount"]==null)
- {
- Application["ApplicationCount"]=1;
- }
- else//否則取出該Session,並且在當前值上加1
- {
- applicationCount=(int)Application["ApplicationCount"]+1;
- Application["ApplicationCount"]=applicationCount;
- }
- //如果Session["SessionCount"]為空,即沒有設定該名字的Session
- if(Session["SessionCount"]==null)
- {
- Session["SessionCount"]=1;
- }
- else
- {
- sessionCount=(int)Session["SessionCount"]+1;
- Session["SessionCount"]=sessionCount;
- }
- Response.Write("當前頁面由Application記錄到的被訪問了"+applicationCount+"次<br/>");
- Response.Write("當前頁面由Session記錄到的被訪問了"+sessionCount+"次<br/>");
- %>
- </body>
- </html>
這時我們在瀏覽器位址列裡輸入:http://localhost/sessiontest.aspx,會看如下結果Session和Application中的值是一樣的,即使我們按F5重新整理頁面,結果也是一樣,如下圖:
然後我們重新開啟一個瀏覽器應用程式(注意不要在當前視窗中輸入),會看到如下情況:
為什麼特地強調要在新瀏覽器視窗中開啟另一個頁面呢?因為有些瀏覽器會視同為同一個Session,導致出現不了預期的效果。通過上面的例子證明了Application確實是屬於所有網站使用者的,它適合儲存全域性的資料資訊,如網站從Web伺服器啟動以來接受的請求個數或者當前線上總人數;而Session只與特定使用者有關,只適合儲存特定使用者的資訊,比如使用者的使用者名稱。
<%%>表示式
<%%>用來編寫程式的程式碼部分。在其中可以宣告變數和方法。如下:
- <%
- string name = Request.Form["userName"].Trim();
- string userName;
- if (Request.Cookies["UserName"] != null)
- {
- userName = Request.Cookies["UserName"].Value;
- }
- %>
在<%%>就是符合C#要求的程式碼。
<%=%>表示式
<%=%>是用來向輸出流中輸出變數的值。其用法如下:
<% int i = 6; %>
<%=i %>
九九乘法表是大家相當熟悉的了,下面我們分別用Response物件的Write方法和上面的<%%>及<%=%>來輸出九九乘法表。如下圖
用Response物件輸出九九乘法表的程式碼如下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>Server物件的常見方法例項</title>
- </head>
- <body>
- <table border="1" width="600px">
- <tr><th colspan="9">九九乘法表</th></tr>
- <%
- for(int i=1;i<10;i++)
- {
- Response.Write("<tr>");
- for(int j=1;j<10;j++)//輸出一行中的每列
- {
- if(j<=i){//如果有內容
- Response.Write(String.Format("<td>{0}×{1}={2}</td>",j,i,j*i));
- }
- else{//否則輸出空單元格
- Response.Write("<td> </td>");
- }
- }
- Response.Write("</tr>");
- }
- %>
- </body>
- </html>
用<%%>及<%=%>輸出九九乘法表的程式碼如下:
- <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
- <title>九九乘法表</title>
- </head>
- <body>
- <table border="1" width="600px">
- <tr><th colspan="9">九九乘法表</th></tr>
- <%
- for(int i=1;i<10;i++)
- {
- %>
- <tr>
- <%
- for(int j=1;j<10;j++)//輸出一行中的每列
- {
- if(j<=i){//如果有內容
- %>
- <td><%=j%>×<%=i%>=<%=i*j%></td>
- <%
- }
- else{//否則輸出空單元格
- %>
- <td> </td>
- <%}
- }
- %>
- </tr>
- <%}
- %>
- </body>
- </html>
可以看出用Response.Write()輸出和<%=%>輸出最後的效果是一樣的。
說明:本文由周公原創,原文發表地址是:http://blog.csdn.net/zhoufoxcn/archive/2008/09/15/2930049.aspx
注意,因為個人空間大小和下載速度受限,所以以後不再提供從本人主機上的下載地址,可以到www.verycd.com下載《ASP.NET夜話》的測試版視訊教程。地址是:http://www.verycd.com/topics/2730883/
Asp.net夜話系列文章:
- Asp.net夜話之一 :asp.net介紹
- Asp.net夜話之二 :asp.net內建物件
- asp.net夜話之三 :表單和控制元件
- Asp.net夜話之四 :Visual Studio 2005中容易被忽略的技巧
- asp.net夜話之五 :Page類和回撥技術
- asp.net夜話之六 :asp.net基本控制元件
- asp.net夜話之七 :ADO.NET介紹
- asp.net夜話之八 :資料繫結控制元件
- asp.net夜話之 九:驗證控制元件
- asp.net夜話之 十:複合控制元件和母板頁
- asp.net夜話之十 一:web.config詳解