二篇 Web Form 第二篇WEB页面 第一章WEB页面简介 2.1.1 WEB FORM 表单,英文单词是Form,学习过VB的朋友一定不会陌生。在 MS NET架构里,Form 是一个经常使用到的词汇。比如:编写 Windows应用时会提到 Windows for,编写Web应 用时会提到 Web form windows form可以看作一个 Windows窗体,这和在VB里面一样。 而 Web Form则代表了一个一个的web页面。总的看来,Fom就像是一个容纳各种控件的 容器,各种控件都必须直接或者间接的和它有依存关系。Form在这里译作“WEB表单”似 乎有些不妥。“表单”这个词,在WEB程序员看来,总是和HIML里面的“Form”相混淆 “WEB表单”似乎翻译成“WEB页面”更加妥当一些 大家还记得ⅤB里面的Form实际上就是一个对象吧,它可以有自己的属性、方法、事 件等等。WEB表单,或者说WEB页面,实际上是一个“对象”( Object)。 MS NET架构里 面一个比较重要的概念就是“对象”:所有的控件都是对象,甚至数据类型都成了对象; 种数据类型都有自己特有的属性和方法。我们在后面的编程中将可以体会到 WEB FORM的后缀名是ASPX。当一个浏览器第一次请求一个ASPX文件时,WEB FORM页面将被CLR( common language runtime)编译器编译。此后,当再有用户访问此页 面的时候,由于ASPX页面己经被编译过,所以,CLR会直接执行编译过的代码。这和ASP 的情况完全不同。ASP只支持 VBScript和 JavaScript这样的解释性的脚本语言。所以ASP 页面是解释执行的。当用户发出请求后,无论是第一次,还是第一千次,ASP的页面都将 被动态解释执行。而 asp. net支持可编译的语言,包括ⅤBNET、C#、 Jscript. NET等。所以, asp. net是一次编译多次执行 为了简化程序员的工作,ASPX页面不需要手工编译,而是在页面被调用的时候, CLR自行决定是否编译。一般来说,下面两种情况下,ASPX会被重新编译 1.ASPX页面第一次被浏览器请求 2.ASPX被改写 由于ASPX页面可以被编译,所以ASPX页面具有组件一样的性能。这就使得ASPX 页面至少比同样功能的ASP页面快250%! 下面我们来看一下简单的WEB页面 22我的第一个Page 把下面的代码拷贝到 myfirstpage aspx文件中,然后从浏览器访问这个文件 <!-源文件: formlweb页面简介 \myfirstpage aspx-> <form action="myfirstpage aspx"method="post"> 第1页共132页
第二篇 Web Form 第 1 页 共 132 页 第二篇 WEB 页面 第一章 WEB 页面简介 2.1.1 WEB FORM 表单,英文单词是 Form,学习过 VB 的朋友一定不会陌生。在 MS.NET 架构里,Form 是一个经常使用到的词汇。比如:编写 Windows 应用时会提到 Windows Form,编写 Web 应 用时会提到 Web Form。Windows Form 可以看作一个 Windows 窗体,这和在 VB 里面一样。 而 Web Form 则代表了一个一个的 Web 页面。总的看来,Form 就像是一个容纳各种控件的 容器,各种控件都必须直接或者间接的和它有依存关系。Form 在这里译作“WEB 表单”似 乎有些不妥。“表单”这个词,在 WEB 程序员看来,总是和 HTML 里面的“Form”相混淆。 “WEB 表单”似乎翻译成“WEB 页面”更加妥当一些。 大家还记得 VB 里面的 Form 实际上就是一个对象吧,它可以有自己的属性、方法、事 件等等。WEB 表单,或者说 WEB 页面,实际上是一个“对象” (Object)。MS.NET 架构里 面一个比较重要的概念就是“对象”:所有的控件都是对象,甚至数据类型都成了对象;每 种数据类型都有自己特有的属性和方法。我们在后面的编程中将可以体会到。 WEB FORM 的后缀名是 ASPX。当一个浏览器第一次请求一个 ASPX 文件时,WEB FORM 页面将被 CLR(common language runtime)编译器编译。此后,当再有用户访问此页 面的时候,由于 ASPX 页面已经被编译过,所以,CLR 会直接执行编译过的代码。这和 ASP 的情况完全不同。ASP 只支持 VBScript 和 JavaScript 这样的解释性的脚本语言。所以 ASP 页面是解释执行的。当用户发出请求后,无论是第一次,还是第一千次,ASP 的页面都将 被动态解释执行。而 asp.net 支持可编译的语言,包括 VB.NET、C#、Jscript.NET 等。所以, asp.net 是一次编译多次执行。 为了简化程序员的工作,ASPX 页面不需要手工编译,而是在页面被调用的时候,由 CLR 自行决定是否编译。一般来说,下面两种情况下,ASPX 会被重新编译: 1.ASPX 页面第一次被浏览器请求; 2.ASPX 被改写 由于 ASPX 页面可以被编译,所以 ASPX 页面具有组件一样的性能。这就使得 ASPX 页面至少比同样功能的 ASP 页面快 250%! 下面我们来看一下简单的 WEB 页面。 2.1.2 我的第一个 Page 把下面的代码拷贝到 myfirstpage.aspx 文件中,然后从浏览器访问这个文件: <!--源文件:form\web 页面简介\myfirstpage.aspx--> <form action="myfirstpage.aspx" method="post">
二篇 Web Form <h3>姓名:< cinput id="name"type=text> 所在城市:< select id="city"size=1> < option>北京< option> < option>上海< /option < option>重庆< option> </select> < input type= submit value="查询"> </form> 你可能觉得这个页面太简单了,用HIML就可以完成。是的!微软建议你将所有的文 件哪怕是纯HIML文件都保存为ASPX文件后缀,这样可以加快页面的访问效率!不仅仅 是在 asp. net环境中,在IS50以后的ASP3.0就已经支持这个特性了 由于我们没有对表单提交做任何响应,所以,当你按下“查询”按钮,页面的内容没有 什么改变 下面我们将逐步使用 asp. net的思考方式,来完成我们的页面 213WEB页面处理过程 这一节我们将深入到 asp. net内部,看看页面是怎样被处理的a 和所有的服务器端进程一样,当ASPX页面被客户端请求时,页面的服务器端代码被 执行,执行结果被送回到浏览器端。这一点和ASP并没有太大的不同 但是, asp. net的架构为我们做了许多别的事情。比如,它会自动处理浏览器的表单提 交,把各个表单域的输入值变成对象的属性,使得我们可以像访问对象属性那样来访问客户 的输入。它还把客户的点击映射到不同的服务器端事件 了解WEB页面的处理过程很重要。这样你可以仔细地优化你的代码,提高代码的效率 2131页面的一次往返处理 用户对 Server control的一次操作,就可能引起页面的一次往返处理:页面被提交到服 务器端,执行响应的事件处理代码,重建页面,然后返回到客户端。 正因为每个 Control都可能引发一次页面的服务器端事件,所以, asp. net尽量减少了控 件的事件类型。很多组件都只有 On Click事件。特别的, asp. net不支持服务器端 OnMouseOver事件。因为 OnMouseOver事件发生得非常频繁。所以,支持服务器端的 On MouseOver事件是非常不现实的 21.32页面重建 每一次页面被请求,或者页面事件被提交到服务器, asp. net运行环境将执行必要的代 码,重建整个页面,把结果页面送到浏览器,然后抛弃页面的变量、控件的状态和属性等等 页面信息。当下一次页面被处理时, asp. net运行环境是不知道它的上一次执行情况的。在 第2页共132页
第二篇 Web Form 第 2 页 共 132 页 <h3> 姓名: <input id="name" type=text> 所在城市: <select id="city" size=1> <option>北京</option> <option>上海</option> <option>重庆</option> </select> <input type=submit value="查询"> </form> 你可能觉得这个页面太简单了,用 HTML 就可以完成。是的!微软建议你将所有的文 件哪怕是纯 HTML 文件都保存为 ASPX 文件后缀,这样可以加快页面的访问效率!不仅仅 是在 asp.net 环境中,在 IIS5.0 以后的 ASP3.0 就已经支持这个特性了。 由于我们没有对表单提交做任何响应,所以,当你按下“查询”按钮,页面的内容没有 什么改变。 下面我们将逐步使用 asp.net 的思考方式,来完成我们的页面。 2.1.3 WEB 页面处理过程 这一节我们将深入到 asp.net 内部,看看页面是怎样被处理的。 和所有的服务器端进程一样,当 ASPX 页面被客户端请求时,页面的服务器端代码被 执行,执行结果被送回到浏览器端。这一点和 ASP 并没有太大的不同。 但是,asp.net 的架构为我们做了许多别的事情。比如,它会自动处理浏览器的表单提 交,把各个表单域的输入值变成对象的属性,使得我们可以像访问对象属性那样来访问客户 的输入。它还把客户的点击映射到不同的服务器端事件。 了解 WEB 页面的处理过程很重要。这样你可以仔细地优化你的代码,提高代码的效率。 2.1.3.1 页面的一次往返处理 用户对 Server Control 的一次操作,就可能引起页面的一次往返处理:页面被提交到服 务器端,执行响应的事件处理代码,重建页面,然后返回到客户端。 正因为每个 Control 都可能引发一次页面的服务器端事件,所以,asp.net 尽量减少了控 件的事件类型。很多组件都只有 OnClick 事件。特别的,asp.net 不支持服务器端的 OnMouseOver 事件。因为 OnMouseOver 事件发生得非常频繁。所以,支持服务器端的 OnMouseOver 事件是非常不现实的。 2.1.3.2 页面重建 每一次页面被请求,或者页面事件被提交到服务器,asp.net 运行环境将执行必要的代 码,重建整个页面,把结果页面送到浏览器,然后抛弃页面的变量、控件的状态和属性等等 页面信息。当下一次页面被处理时,asp.net 运行环境是不知道它的上一次执行情况的。在
二篇 Web Form 这个意义上,ASPX页面是没有状态的。这也是HTTP协议的特点(为了加速页面的访问, 在 asp. net页面里面可以使用缓存机制,也就是保存页面的执行结果,下一次页面被请求时 直接送回上一次的执行结果。)。 在ASP中,当页面被提交到服务器端时,只有那些用户输入的值被传递到服务器。其 他的比如组件的属性、变量的值,是不会传递的。所以服务器无法了解组件的进一步的信息。 在 asp. net中,页面对象的属性、页面控件的属性被称为“ view state”(页面状态)。页 面状态在 asp. net中被受到特别关照。请看服务器端( pagel,aspx)的代码: <!-源文件: formlweb页面简介 pagel. aspx-> <HTML> <BODY> <SCRIPt languages"VB" runat=server"> Sub Show Values( Sender As Object, Args As EventArgs) divResult inner Text "You selected txtName value End Sub <SCRIPT> <DIv id="div Result" runat=server"> DIV> <FORM runat=server"> 机器名 <INPUT type="text"id="txtName" runat="server"> <P> 操作系统: select id="selOp Sys" size="1"runat="server"> <OPTION>Windows 95</OPTION> <OPtION>Windows 98</oPTION> <OPtION>Windows NT4</OPTION> <OPTION>Windows 2000</OPTION> <SELECT> <INPUT type="submit" value="Submit"runat="server" onserverclick="Show Values"> </FORM> HTML> 运行后将自动被解释成客户端代码,如下 <HTML> <BODY> You selected ' Windows 98 for machine 'iceber <FORM name="ctrl"method="post" action="pageone. aspx"id="ctrl0"> <INPUT type="hidden"na VIEWSTATE value=a0z1741688109 x> 机器名 <INPUT type="text"id="txtName" name="txt Name" value="tizzy"> 第3页共132页
第二篇 Web Form 第 3 页 共 132 页 这个意义上,ASPX 页面是没有状态的。这也是 HTTP 协议的特点(为了加速页面的访问, 在 asp.net 页面里面可以使用缓存机制,也就是保存页面的执行结果,下一次页面被请求时, 直接送回上一次的执行结果。)。 在 ASP 中,当页面被提交到服务器端时,只有那些用户输入的值被传递到服务器。其 他的比如组件的属性、变量的值,是不会传递的。所以服务器无法了解组件的进一步的信息。 在 asp.net 中,页面对象的属性、页面控件的属性被称为“view state”(页面状态)。页 面状态在 asp.net 中被受到特别关照。请看服务器端(page1.aspx)的代码: <!--源文件:form\web 页面简介\page1.aspx--> <HTML> <BODY> <SCRIPT language="VB" runat="server"> Sub ShowValues(Sender As Object, Args As EventArgs) divResult.innerText = "You selected '" _ & selOpSys.value & "' for machine '" _ & txtName.value & "'." End Sub </SCRIPT> <DIV id="divResult" runat="server"> </DIV> <FORM runat="server"> 机器名: <INPUT type="text" id="txtName" runat="server"> <P /> 操作系统: <select id="selOpSys" size="1" runat="server"> <OPTION>Windows 95</OPTION> <OPTION>Windows 98</OPTION> <OPTION>Windows NT4</OPTION> <OPTION>Windows 2000</OPTION> </SELECT> <P /> <INPUT type="submit" value="Submit" runat="server" onserverclick="ShowValues"> </FORM> </BODY> </HTML> 运行后将自动被解释成客户端代码,如下: <HTML> <BODY> You selected 'Windows 98' for machine 'iceberg'. <FORM name="ctrl0" method="post" action="pageone.aspx" id="ctrl0"> <INPUT type="hidden" name="__VIEWSTATE" value="a0z1741688109__x"> 机器名: <INPUT type="text" id="txtName" name="txtName" value="tizzy">
二篇 Web Form 操作系统 <SELECT id="selOpSys" size="1"name="selOpSys"> <OPtion value="Windows 95">windows 95</OPTION> <OPtion selected value="Windows 98">Windows 98</OPTION> <OPtion value="Windows nT4">Windows NT4</OPTION> <OPtion value="Windows 2000">Windows 2000</OPTION> <SELECT> <INPUT type="submit" val ue="Submit"> </BODY> <HTML> 对于上面的代码,服务器端控件能在服务器端脚本中被自由运用。如果我们用传统的 ASP代码实现上述的功能的话 If Len( request Form("selOp Sys"))>0 The StrOp Sys Request Form("selOp Sys") StrName Request Form("txtName") Response. Write("You selected "& strOpSys for machine str name " End if 如果我们用 asp. net的话,程序代码如下 If Len(selOp Sys value)>0 Then Response. Write("You selected selOp Sys value for machine txtName value "l") End If 通过上面例子不难看出: asp. net页面具有组件方式的方便性和灵活性 请注意: asp. net通过把页面的状态封装到一个隐藏的输入域,从而可以在不同的页面 之间实现传递页面的状态 另外, asp. net也支持应用程序一级的状态管理。这个特性在ASP中就已经实现 2133页面处理内部过程 我们来看看页面处理的内部过程。下面的过程是依次进行的: 2.1.3.3.1 Page load 首先,页面的状态被恢复,然后触发 Page OnLoad事件。在这个过程中,你可以读取 或者重置页面的属性和控件的属性,根据 IsPost Back属性判定页面是否为第一次被请求,执 行数据绑定,等等。 现在我们通过一个具体的例子,来详细讲述 Page load事件: 我们所做的这个例子关于用户登录的 第4页共132页
第二篇 Web Form 第 4 页 共 132 页 <P /> 操作系统: <SELECT id="selOpSys" size="1" name="selOpSys"> <OPTION value="Windows 95">Windows 95</OPTION> <OPTION selected value="Windows 98">Windows 98</OPTION> <OPTION value="Windows NT4">Windows NT4</OPTION> <OPTION value="Windows 2000">Windows 2000</OPTION> </SELECT> <P /> <INPUT type="submit" value="Submit"> </FORM> </BODY> </HTML> 对于上面的代码,服务器端控件能在服务器端脚本中被自由运用。如果我们用传统的 ASP 代码实现上述的功能的话: If Len(Request.Form("selOpSys")) > 0 Then StrOpSys = Request.Form("selOpSys") StrName = Request.Form("txtName") Response.Write("You selected '" & strOpSys _ & "' for machine '" & strName & "'.") End If 如果我们用 asp.net 的话,程序代码如下: If Len(selOpSys.value) > 0 Then Response.Write("You selected '" & selOpSys.value _ & "' for machine '" & txtName.value & "'.") End If 通过上面例子不难看出:asp.net 页面具有组件方式的方便性和灵活性。 请注意:asp.net 通过把页面的状态封装到一个隐藏的输入域,从而可以在不同的页面 之间实现传递页面的状态。 另外,asp.net 也支持应用程序一级的状态管理。这个特性在 ASP 中就已经实现。 2.1.3.3 页面处理内部过程 我们来看看页面处理的内部过程。下面的过程是依次进行的: 2.1.3.3.1 Page_load 首先,页面的状态被恢复,然后触发 Page_OnLoad 事件。在这个过程中,你可以读取 或者重置页面的属性和控件的属性,根据 IsPostBack 属性判定页面是否为第一次被请求,执 行数据绑定,等等。 现在我们通过一个具体的例子,来详细讲述 Page_load 事件: 我们所做的这个例子关于用户登录的
我们先来看 page. aspx的代码: <!-源文件: formlweb页面简介 Apage. aspx-> <% Register Tag Prefix= <htm> 登录演示< title> script language="VB"runat="server Sub Page Load(Sender As Object, E As EventArgs) If( Page. IsPost Back) MyLabe.Text&="用户名:"& MyLogin Userid&"<br> MyLabel Text &="219: " MyLogin Password &"<br>" End lf End Sub < center><h3>登录</h3></ center. <form runat"server>> Acme: Login id="MyLogin"Userld=t"Password=" Back Color="beige"runat="server"A </form> <asp: Label id="MyLabel" runat="server"/> <html> 在这个文件中,我们使用了 Page Onload事件的 IsPostBack属性,用来显示用户登录 时的用户名和密码 在来看一下 page. ascx文件 <!-源文件: formlweb页面简介 Apage.ascx-> <script language="VB"runat="server"> Public Back Color As String="white" Public Property Userld As String Return User Name. Text End get User Name. Text value End set End Property Public Property Password As String Return Pass Text End get Pass Text= value End set End Property 第5页共132页
第二篇 Web Form 第 5 页 共 132 页 我们先来看 page.aspx 的代码: <!--源文件:form\web 页面简介\page.aspx--> <%@ Register TagPrefix="Acme" TagName="Login" Src="page.ascx" %> <html> <title>登录演示</title> <script language="VB" runat="server"> Sub Page_Load(Sender As Object, E As EventArgs) If (Page.IsPostBack) MyLabel.Text &= "用户名:" & MyLogin.UserId & "<br>" MyLabel.Text &= "密码: " & MyLogin.Password & "<br>" End If End Sub </script> <body style="font: 10pt verdana"> <center> <h3>登录</h3></center> <form runat="server"> <Acme:Login id="MyLogin" UserId="" Password="" BackColor="beige" runat="server"/> </form> <asp:Label id="MyLabel" runat="server"/> </body> </html> 在这个文件中,我们使用了 Page_OnLoad 事件的 IsPostBack 属性,用来显示用户登录 时的用户名和密码。 在来看一下 page.ascx 文件: <!--源文件:form\web 页面简介\page.ascx--> <script language="VB" runat="server"> Public BackColor As String = "white" Public Property UserId As String Get Return UserName.Text End Get Set UserName.Text = Value End Set End Property Public Property Password As String Get Return Pass.Text End Get Set Pass.Text = Value End Set End Property </script>