在今天我主要要介绍的有如下知识点:
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页面,代码如下:
     1. <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
     2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3. <html xmlns="http://www.w3.org/1999/xhtml">
     4. <head>
     5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
     6. <title>Request例子</title>
     7. </head>
     8. <body>
     9. <table border="1" width="600px" bordercolordark="#2B72A2" bordercolorlight="#993333">
    10. <tr><td colspan="2" bgcolor="#80ffff">Request</td></tr>
    11. <tr><td>ApplicationPath(网站路径)</td><td><%=Request.ApplicationPath%></td></tr>
    12. <tr><td>ContentEncoding(网页编码)</td><td><%=Request.ContentEncoding%></td></tr>
    13. <tr><td>Cookies个数</td><td><%=Request.Cookies.Count%></td></tr>
    14. <tr><td>QueryString个数</td><td><%=Request.QueryString.Count%></td></tr>
    15. <tr><td>UrlReferrer(上一请求页面)</td><td> <%=Request.UrlReferrer%></td></tr>
    16. <tr><td colspan="2" bgcolor="#80ffff">Response</td></tr>
    17. <tr><td>Charset</td><td><%=Response.Charset%></td></tr>
    18. <tr><td>ContentEncoding(网页编码)</td><td><%=Response.ContentEncoding%></td></tr>
    19. <tr><td>Cookies个数</td><td><%=Response.Cookies.Count%></td></tr>
    20. <tr><td>ContentType</td><td><%=Response.ContentType%></td></tr>
    21. </table>
    22. </body>
    23. </html>
        将新建的页面保存为RequestAndResponse.aspx并保存到C:\Inetpub\wwwroot下,然后打开浏览器在地址栏中输入:http://localhost/RequestAndResponse.aspx,实际上url地址不区分大小写,以上地址全部小写也没有关系,运行结果如下:

        从上面的结果我们可以看出利用Dreamweaver创建的网页,如果采用默认编码,请求对象的字符编码是UTF-8,而响应对象的编码为gb2312。这样极有可能可能产生乱码问题。所谓乱码,就是用一种编码的字符串却用了另一种编码来显示,造成不能正常显示的现象。就像我用普通话说“请给我来一杯茶“,结果是一个只懂德育的人听了,他自然听不懂我说什么,不能正常交流。另外,需要说明的是常见的服务器响应的ContentType是 “text/html”,代表响应是以HTML文件形式传输的。还有一些其它形式的ContentType,如下:
p_w_picpath/jpeg:响应对象是jpeg图片
text/xml:响应对象是xml文件
text/javascript:响应对象是javascript脚本文件
        Response 的ContentType属性默认是“text/html”,表示服务器以HTML文件响应客户端请求,如果需要用其它方式响应客户端请求,则需要设置 ContentType属性。假如我们需要用jpeg图片的格式响应客户端请求,则需要设置ContentType属性为“p_w_picpath/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页面,代码如下:
     1. <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
     2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3. <html xmlns="http://www.w3.org/1999/xhtml">
     4. <head>
     5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
     6. <title>Server对象的常见方法实例</title>
     7. </head>
     8. <body>
     9. <ul>
    10. <li>Server.MapPath(".")=<%=Server.MapPath(".")%></li>
    11. <li><%=Server.HtmlEncode("<h1>Asp.net夜话之二:asp.net内置对象</h1>")%></li>
    12. <li><h1>Asp.net夜话之二:asp.net内置对象</h1></li>
    13. <li><%=Server.UrlEncode("<a href=\"http://blog.csdn.net/zhoufoxcn\">周公的专栏</a>")%></li>
    14. <li><a href="http://blog.csdn.net/zhoufoxcn">周公的专栏</a></li>
    15. </ul>
    16. </body>
    17. </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”,代码如下:
        1. Session[“UserName”]=”zhoufoxcn”;
一个网站里用到Session的地方肯定不止一个,所以在设置和获取Session的时候通过Session的名在来操作,并且Session被设置成能存储任意类型的对象(即Object类型),所以获取Session的时候要根据设置的时候的实际类型进行响应的强制类型转换(当然如果在 Session中存放像int/byte/short这样的数据类型,获取Session的值算是一种拆箱操作而不是强制类型转换),对于上面的 Session,获取Session的值的代码如下:
   1. string username=(string)Session[“UserName”];

        对于上面的代码,有个问题需要注意:当没有设置相应的Session或者Session因为超过生命周期而被销毁时,上面的代码有可能抛出异常。我们可以先判断是否存在指定名称的Session,如果不存在就不用获取了,仅当存在的情况下才获取Session的值,上面的代码可以改进如下:
   1. string userName;
   2. if(Session["UserName"]!=null)
   3. {
   4. //当指定名称的Session存在时,获取指定Session的值
   5. userName=(string)Session["UserName"];
   6. }
 
Cookie

        Cookie对象和Session对象一样也是用来保存特定的用户相关的数据,不过Session不同的是Cookie保存在客户端而不是服务器上,每次客户端发出请求的时候都会把Cookie一起发送到服务器,服务器每次响应客户端请求的时候会重新把Cookie发送到客户端保存。
Cookie保存数据有以下特点:
Cookie中的数据保存在客户端;
Cookie中只能保存字符串类型的数据,如果需要在Cookie中保存其它类型数据,需要将其转换成字符串类型后保存;
Cookie也有其默认生命周期,也可以手动设置,最大可设置成50年之后过期。
        同Session的情况一样,有可能在一个网站中使用到的Cookie不止一个,我们仍通过Cookie的名称来区分不同的Cookie。
        设置Cookie的过程就是在服务器的响应对象Response的Cookie集合中增加一个Cookie的实际,Response对象会把这个Cookie集合中的所有Cookie都发送客户端。代码如下(仍以保存用户名为例):
   1. HttpCookie cookie = new HttpCookie("UserName", "zhoufoxcn");
   2. Response.Cookies.Add(cookie);

    获取Cookie就是从客户端的请求对象中找到对应名称的Cookie,当然也有可能出现Cookie不存在的情况,所以在获取之前也需要检查指定名称的Cookie是否存在,大妈如下:
   1. string userName;
   2. if (Request.Cookies["UserName"] != null)
   3. {
   4.      userName = Request.Cookies["UserName"].Value;
   5. }

        细心的朋友可能会留意到前面讲到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目录下,它们的代码都是一样的,如下:
     1. <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
     2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3. <html xmlns="http://www.w3.org/1999/xhtml">
     4. <head>
     5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
     6. <title>Application和Session的例子</title>
     7. </head>
     8. <body>
     9. <%
    10. //如果没有设置名为"ApplicationCount"的Application
    11. int applicationCount=1;
    12. int sessionCount=1;
    13. if(Application["ApplicationCount"]==null)
    14. {
    15. Application["ApplicationCount"]=1;
    16. }
    17. else//否则取出该Session,并且在当前值上加1
    18. {
    19. applicationCount=(int)Application["ApplicationCount"]+1;
    20. Application["ApplicationCount"]=applicationCount;
    21. }
    22. //如果Session["SessionCount"]为空,即没有设置该名字的Session
    23. if(Session["SessionCount"]==null)
    24. {
    25. Session["SessionCount"]=1;
    26. }
    27. else
    28. {
    29. sessionCount=(int)Session["SessionCount"]+1;
    30. Session["SessionCount"]=sessionCount;
    31. }
    32. Response.Write("当前页面由Application记录到的被访问了"+applicationCount+"次<br/>");
    33. Response.Write("当前页面由Session记录到的被访问了"+sessionCount+"次<br/>");
    34. %>
    35. </body>
    36. </html>

 
        这时我们在浏览器地址栏里输入:http://localhost/sessiontest.aspx,会看如下结果Session和Application中的值是一样的,即使我们按F5刷新页面,结果也是一样,如下图:

 
        然后我们重新打开一个浏览器应用程序(注意不要在当前窗口中输入),会看到如下情况:
 
        为什么特地强调要在新浏览器窗口中打开另一个页面呢?因为有些浏览器会视同为同一个Session,导致出现不了预期的效果。通过上面的例子证明了 Application确实是属于所有网站用户的,它适合保存全局的数据信息,如网站从Web服务器启动以来接受的请求个数或者当前在线总人数;而 Session只与特定用户有关,只适合保存特定用户的信息,比如用户的用户名。
<%%>表达式

<%%>用来编写程序的代码部分。在其中可以声明变量和方法。如下:

 
     1. <%
     2.         string name = Request.Form["userName"].Trim();
     3.         string userName;
     4.         if (Request.Cookies["UserName"] != null)
     5.         {
     6.                 userName = Request.Cookies["UserName"].Value;
     7.         }
     8.            %>
        在<%%>就是符合C#要求的代码。
<%=%>表达式
<%=%>是用来向输出流中输出变量的值。其用法如下:
<% int i = 6; %>
<%=i %>
        九九乘法表是大家相当熟悉的了,下面我们分别用Response对象的Write方法和上面的<%%>及<%=%>来输出九九乘法表。如下图
 
        用Response对象输出九九乘法表的代码如下:

 
     1. <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
     2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3. <html xmlns="http://www.w3.org/1999/xhtml">
     4. <head>
     5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
     6. <title>Server对象的常见方法实例</title>
     7. </head>
     8. <body>
     9. <table border="1" width="600px">
    10. <tr><th colspan="9">九九乘法表</th></tr>
    11. <%
    12. for(int i=1;i<10;i++)
    13. {
    14. Response.Write("<tr>");
    15. for(int j=1;j<10;j++)//输出一行中的每列
    16. {
    17. if(j<=i){//如果有内容
    18. Response.Write(String.Format("<td>{0}×{1}={2}</td>",j,i,j*i));
    19. }
    20. else{//否则输出空单元格
    21. Response.Write("<td> </td>");
    22. }
    23. }
    24. Response.Write("</tr>");
    25. }
    26. %>
    27. </body>
    28. </html>
        用<%%>及<%=%>输出九九乘法表的代码如下:
     1. <%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>
     2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3. <html xmlns="http://www.w3.org/1999/xhtml">
     4. <head>
     5. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
     6. <title>九九乘法表</title>
     7. </head>
     8. <body>
     9. <table border="1" width="600px">
    10. <tr><th colspan="9">九九乘法表</th></tr>
    11. <%
    12. for(int i=1;i<10;i++)
    13. {
    14. %>
    15. <tr>
    16. <%
    17. for(int j=1;j<10;j++)//输出一行中的每列
    18. {
    19. if(j<=i){//如果有内容
    20. %>
    21. <td><%=j%>×<%=i%>=<%=i*j%></td>
    22. <%
    23. }
    24. else{//否则输出空单元格
    25. %>
    26. <td> </td>
    27. <%}
    28. }
    29. %>
    30. </tr>
    31. <%}
    32. %>
    33. </body>
    34. </html>

        可以看出用Response.Write()输出和<%=%>输出最后的效果是一样的。