【asp源码栏目提醒】:网学会员在asp源码频道为大家收集整理了“第4章ASPNET的网页代码模型及生命周期(ASPNET 35开发大全 共29 - 信息产业“提供大家参考,希望对大家有所帮助!
第4章
ASP.NET的网页代码模型及生命周期 从本章开始就进入了
ASP.NET应用程序开发的世界。
在了解了C的结构以及面向对象的概念后就可以从面向对象的思想开发
ASP.NET应用程序。
在
ASP.NET中能够使用面向对象的思想和软件开发中的一些思想例如封装、派生、继承以及高级的设计模式等。
本章首先介绍
ASP.NET中最重要的概念---网页代码模型。
4.1
ASP.NET的网页代码模型 在
ASP.NET应用程序开发中微软提供了大量的控件这些控件能够方便用户的开发以及维护。
这些控件具有很强的扩展能力在开发过程中无需自己手动编写。
不仅如此用户还能够创建自定义控件进行应用程序开发以扩展现有的服务器控件的功能。
4.1.1 创建
ASP.NET网站 在
ASP.NET中可以创建
ASP.NET网站和
ASP.NET应用程序
ASP.NET网站的网页元素包含可视元素和页面逻辑元素并不包含designer.cs文件。
而
ASP.NET应用程序包含designer.cs文件。
创建
ASP.NET网站首先需要创建网站单击【文件】按钮在下拉菜单中选择【新建网站】选项单击后会弹出对话框用于
ASP.NET网站的创建如图4-1所示。
图4-1 新建
ASP.NET网站 在【位置】选项中旁边的【下拉菜单】可以按照开发的需求来写一般选择文件系统地址为本机的本地地址。
语言为.NET网站中使用的语言如果选择Visual C则默认的开发语言为C否则为Visual Basic。
创建了
ASP.NET网站后系统会自动创建一个代码隐藏页模型页面Default.aspx。
ASP.NET网页一般由三部分组成这三个部分如下所示。
可视元素包括HTML标记服务器空间。
95 页面逻辑元素包括事件处理程序和代码。
designer.cs页文件用来为页面的控件做初始化工作一般只有
ASP.NET应用程序Web Application才有。
ASP.NET页面中包含两种代码模型一种是单文件页模型另一种是代码隐藏页模型。
这两个模型的功能完全一样都支持控件的拖拽以及智能的代码生成。
4.1.2 单文件页模型 单文件页模型中的所有代码包括控件代码、事物处理代码以及HTML代码全都包含在.aspx文件中。
编程代码在script标签并使用runat“server”属性标记。
创建一个单文件页模型在【文件】按钮中选择【新建文件】选项在弹出对话框中选择【Web窗体】或在右击当前项目在下拉菜单中选择【添加新建项】选项即可创建一个.aspx页面如图4-2所示。
图4-2 创建单文件页模型 在创建时去掉【将代码放在单独的文件中】复选框的选择即可创建单文件页模型的
ASP.NET文件。
创建后文件会自动创建相应的HTML代码以便页面的初始化示例代码如下所示。
lt Page Language“C” gt ltDOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”gt ltscript runat“server”gt lt/scriptgt lthtml xmlns“http://www.w3.org/1999/xhtml”gt lthead runat“server”gt lttitlegt无标题页lt/titlegt lt/headgt ltbodygt ltform id“form1” runat“server”gt ltdivgt lt/divgt lt/formgt lt/bodygt lt/htmlgt 96 编译并运行即可看到一个空白的页面被运行了。
ASP.NET单文件页模型在创建并生成时开发人员编写的类将编译成程序集并将该程序集加载到应用程序域并对该页的类进行实例化后输出到浏览器。
可以说.aspx页面的代码也即将会生成一个类并包含内部逻辑。
在浏览器浏览该页面时.aspx页面的类实例化并输出到浏览器反馈给浏览者。
ASP.NET单文件页模型运行示例图如图4-3所示。
图4-3 单文件页模型 4.1.3 代码隐藏页模型 代码隐藏页模型与单文件页模型不同的是代码隐藏页模型将事物处理代码都存放在cs文件中当
ASP.NET网页运行的时候
ASP.NET类生成时会先处理cs文件中的代码再处理.aspx页面中的代码。
这种过程被成为代码分离。
代码分离有一种好处就是在.aspx页面中开发人员可以将页面直接作为样式来设计即美工人员也可以设计.aspx页面而.cs文件由程序员来完成事务处理。
同时将
ASP.NET中的页面样式代码和逻辑处理代码分离能够让维护变得简单同时代码看上去也非常的优雅。
在.aspx页面中代码隐藏页模型的.aspx页面代码基本上和单文件页模型的代码相同不同的是在script标记中的单文件页模型的代码默认被放在了同名的.cs文件中.aspx文件示例代码如下所示。
lt Page Language“C” AutoEventWireup“true” CodeFile“Default.aspx.cs” Inherits“_Default” gt ltDOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”gt lthtml xmlns“http://www.w3.org/1999/xhtml”gt lthead runat“server”gt lttitlegt无标题页lt/titlegt lt/headgt 97 ltbodygt ltform id“form1” runat“server”gt ltdivgt lt/divgt lt/formgt lt/bodygt lt/htmlgt 从上述代码中可以看出在头部声明的时候单文件页模型只包含Language“C”而代码隐藏页模型包含了CodeFile“Default.aspx.cs”说明被分离出去处理事物的代码被定义在Default.aspx.cs中示例代码如下所示。
using System.Linq using System.Web using System.Web.Security using System.Web.UI using System.Web.UI.HtmlControls //使用HtmlControls using System.Web.UI.WebControls //使用WebControls using System.Web.UI.WebControls.WebParts //使用WebParts public partial class _Default : System.Web.UI.Page //继承自System.Web.UI.Page protected void Page_Loadobject sender EventArgs e 上述代码为Default.apx.cs页面代码。
从上述代码可以看出其格式与类库、编写类的格式相同这也说明了.aspx页面允许使用面向对象的特性如多态、继承等。
但是
ASP.NET代码隐藏页模型的运行过程比单文件页模型要复杂运行示例图如图4-4所示。
98 图4-4 代码隐藏页模型 上述描述了代码隐藏类模型的页面生成模型。
当页面被呈现之前
ASP.NET应用程序会解释并编译相应的cs文件中的代码与此同时
ASP.NET应用程序还会将.aspx页面进行编译并生成.aspx页面对应的类。
生成.aspx页面对应的类后会将该类与cs文件中的类进行协调生成新的类该类会通过IIS在用户浏览页面时呈现在用户的浏览器中。
4.1.4 创建
ASP.NET Web Application
ASP.NET网站有一种好处就是在编译后编译器将整个网站编译成一个DLL动态链接库在更新的时候只需要更新编译后的DLL动态链接库文件即可。
但是
ASP.NET网站却有一个缺点编译速度慢并且类的检查不彻底。
相比之下
ASP.NET Web Application不仅加快了速度只生成一个程序集而且可以拆分成多个项目进行管理。
创建Application首先需要新建项目用于开发Web Application单击菜单栏上的【文件】按钮在下拉菜单中选择【新建项目】选项在弹出窗口中选择【
ASP.NET应用程序】选项如图4-5所示。
图4-5 创建
ASP.NET应用程序 在创建了
ASP.NET应用程序后系统同样会默认创建一个Default.aspx页面不同的是多出了一个Default.aspx.designer.cs用来初始化页面控件一般不需要修改。
4.1.5
ASP.NET网站和
ASP.NET应用程序的区别 在
ASP.NET中可以创建
ASP.NET网站和
ASP.NET应用程序但是
ASP.NET网站和
ASP.NET应用程序开发过程和编译过程是有区别的。
ASP.NET应用程序主要有以下特点 可以将
ASP.NET应用程序拆分成多个项目以方便开发管理和维护。
可以从项目中和源代码管理中排除一个文件或项目。
支持VSTS的Team Build方便每日构建。
可以对编译前后的名称程序集等进行自定义。
对App_GlobalResources 的Resource强类支持。
99
ASP.NET WebSite编程模型具有以下特点 动态编译该页面而不用编译整个站点。
当一部分页面出现错误不会影响到其他的页面或功能。
不需要项目文件可以把一个目录当作一个Web应用来处理。
总体来说
ASP.NET网站适用于较小的网站开发因为其动态编译的特点无需整站编译。
而
ASP.NET应用程序适应大型的网站开发、维护等。
4.2 代码隐藏页模型的解释过程 在
ASP.NET的代码隐藏页模型中一个完整的.aspx页面包含两个页面分别是以.aspx和.cs文件为后缀的文件这两个文件在形成了整个Web窗体。
在编译的过程中都被编译成由项目生成的动态链接库.DLL同时.aspx页面同样也会编译。
但是与.cs页面编译过程不同的是当浏览者第一次浏览到.aspx页面时
ASP.NET自动生成该页的.NET类文件并将其编译成另一个.DLL文件。
当浏览者再一次浏览该页面的时候生成的.DLL就会在服务器上运行并响应用户在该页面上的请求或响应
ASP.NET应用程序的解释过程图如4-6所示。
图4-6 代码隐藏页模型页面的执行过程 在客户端浏览器访问该页面时浏览器会给IIS发送请求消息IIS则会开始执行
ASP.NET编译过程如果不存在编译过后的DLL文件则加载编译的类并创建对象。
当创建对象完成生成创建对象后的代码并生成一个ASPX页面代码该页面代码反馈给IISIIS再反馈成HTML页面的形式给客户端。
4.3 代码隐藏页模型的事件驱动处理 在传统的
ASP开发中
ASP的事件都是按照网页的顺序来处理的一般情况下
ASP页面的事件 100 都是从上到下处理事件可以说
ASP的开发是一个线性的处理模型。
在用户的浏览操作中每一次用户的操作都会导致页面重新被发送到服务器。
因此重复的操作必然导致客户端和服务器的往返过程服务器必须重新创建页面当创建页面后服务器再按照原来的从上到下的顺序进行事件处理。
在
ASP.NET中通过使用模拟事件驱动模型的行为代替了
ASP的线性处理模型。
ASP.NET页框架模型隐式的为用户建立了事件和事件处理程序的关联。
ASP.NET让用户可以为从浏览器传递的事件在服务器代码中设置相应的处理程序。
假设某个用户正在浏览网站并与页面之间产生了某种交互用户的操作就会引发事件事件通过HTTP被传输到服务器。
在服务器中
ASP.NET框架解释信息并触发事件与之对应的处理程序。
该程序可以是.aspx页面中的处理程序也可以是开发者自定义的类库或者COM组件等。
事件驱动处理如图4-7所示。
图4-7 页面框架的事件驱动处理模型 上图则说明了当一个浏览者通过浏览器触发ASPX页面时浏览器、服务器和服务器返回页的过程。
4.4
ASP.NET客户端状态 Web开发不像软件开发Web应用实际上是没有状态的这就说明Web应用程序不自动指示序列中的请求是否来自相同的浏览器或客户端也无法判断浏览器是否一直在浏览一个页面或者一个站点也无法判断用户执行了哪个操作并统计用户的喜好。
4.4.1 视图状态 从上面的章节中可以知道当服务器每次的往返过程都将销毁页面并重新创建新的页面。
如果一个页面中的信息超出了页面的生命周期那么这个页面中的相关信息就不存在了。
如果注销了页面的信 101 息那么用户的一些信息可能就不存在了。
在
ASP.NET中网页包含视图状态来保存用户的信息视图状态在页面发回到自身时跨页过程存储和用户自己的页面的特定值视图状态的优点如下所示。
不需要任何服务器资源。
在默认情况下对控件启用状态的数据进行维护不会被破坏。
视图状态的值经过哈希运算和压缩保护安全性更高。
视图状态同样有一些缺点缺点如下所示。
视图状态会影响性能如果页面存储较大较多的值则性能会有较大的影响。
在手机移动终端上可能无法保存视图状态中使用的值。
视图状态虽然安全性较高但是还是有风险如果直接查看页面代码可以看到相应代码。
4.4.2 控件状态
ASP.NET中还提供了控件状态属性作为在服务器往返过程中存储自定义控件中的数据的方法。
在页面控件中如果有多个自定义控件使用多个不同的控件来显示不同的数据结构为了让这些页面控件能够在在页面上协调的工作则需要使用控件状态来保护控件同时控件状态是不能被关闭的。
同样控件状态也有它的优点优点如下所示。
与视图状态相同的是不需要任何服务器资源。
控件状态是不能被关闭的提供了控件管理的更加可靠的方法。
控件状态具有通用性。
4.4.3 隐藏域 在
ASP中通常使用隐藏域保存页面的信息。
在
ASP.NET中同样具有隐藏域来保存页面的信息作为维护页面状态的一种形式但是隐藏域的安全性并不高最好不要在隐藏域保存过多的信息。
隐藏域具有以下优点。
不需要任何服务器资源。
支持广泛任何客户端都支持隐藏域。
实现简单隐藏域属于HTML控件无需像服务器控件那样有需要编程知识。
而隐藏域具有一些不足如下所示。
具有较高的安全隐患。
存储结构简单。
同样如果存储了较多的较大的值则会导致性能问题。
如果隐藏域过多则在某些客户端中被禁止。
隐藏域将数据存储在服务器上而不存储在客户端。
注意如果开发中页面的隐藏域过多这些隐藏域被存储在服务器。
当客户端浏览页面的时候会有一些防火墙扫描页面以保证操作系统的安全如果页面的隐藏域过多那么这些防火墙可能会禁止页面的某些功能。
102 4.4.4 Cookie Cookie在客户端用户保存网站的少量的用户信息服务器可以通过编程的方法获取用户信息Cookie信息和页面请求通常一起发送到服务器服务器对客户端传递过来的Cookie信息做处理。
通常Cookie保存用户的登录状态、用户名等基本信息等等在后面的章节会详细介绍使用
ASP.NET操作Cookies。
4.4.5 客户端状态维护 虽然使用某些客户端状态并不使用服务器资源但是这些状态都具有潜在的安全隐患如Cookie。
非法用户可以使用Cookie欺骗来攻击网站进行用户信息的获取不过使用客户端状态能够使用客户端的资源从而提高服务器性能。
使用客户端状态虽然有安全隐患但是具有良好的编程能力以及基本的安全知识能够较好的解决安全问题同时也能够提高服务器性能。
下面小结了一些客户端状态的优缺点。
视图状态推荐当存储少量挥发到自身的页面的信息时使用。
控件状态不需要任何服务器资源控件状态是不能被关闭的提供了控件管理的更加可靠和更通用的方法。
隐藏域实现简单但是在应用程序中会造成一些安全隐患。
Cookie实现简单同样也能够简单的获取用户的信息但是Cookie有大小的限制不适宜存储大量的代码。
4.5
ASP.NET页面生命周期
ASP.NET页面运行时也同类的对象一样有自己的生命周期。
ASP.NET页面运行时
ASP.NET页面将经历一个生命周期在生命周期内该页面将执行一系列的步骤包括控件的初始化控件的实例化还原状态和维护状态等以及通过IIS反馈给用户呈现成HTML。
ASP.NET页面生命周期是
ASP.NET中非常重要的概念了解
ASP.NET页面的生命周期就能够在合适的生命周期内编写代码执行事务。
同样熟练掌握
ASP.NET页面的生命周期可以开发高效的自定义控件。
ASP.NET生命周期通常情况下需要经历几个阶段这几个阶段如下所示。
页请求页请求发生在页生命周期开始之前。
当用户请求一个页面
ASP.NET将确定是否需要分析或者编译该页面或者是否可以在不运行页的情况下直接请求缓存响应客户端。
开始发生了请求后页面就进入了开始阶段。
在该阶段页面将确定请求是发回请求还是新的客户端请求并设置IsPostBack属性。
初始化在页面开始后进入了初始化阶段。
初始化期间页面可以使用服务器控件并为每个服务器控件进行初始化。
加载页面加载控件。
验证调用所有的验证程序控件的Vailidate方法来设置各个验证程序控件和页的属性。
回发事件如果是回发请求则调用所有事件处理的程序。
呈现在呈现期间视图状态被保存并呈现到页。
卸载完全呈现页面后将页面发送到客户端并准备丢弃时将调用卸载。
103 4.6
ASP.NET生命周期中的事件 在页面周期的每个阶段页面将引发可运行用户代码进行处理事件。
对于控件产生的事件通过声明的方式执行代码并将事件处理程序绑定到事件。
不仅如此事件还支持自动事件连接最常用的就是Page_Load事件了除了Page_Load事件以外还有Page_Init等其他事件本节将会介绍此类事件。
4.6.1 页面加载事件Page_PreInit 每当页面被发送到服务器时页面就会重新被加载启动Page_PreInit事件执行Page_PreInit事件代码块。
当需要对页面中的控件进行初始化时则需要使用此类事件示例代码如下所示。
protected void Page_PreInitobject sender EventArgs e //Page_PreInit事件 Label1.Text “OK” //标签赋值 在上述代码中当触发了Page_PreInit事件时就会执行该事件的代码上述代码将Lable1的初始文本值设置为“OK”。
Page_PreInit事件能够让用户在页面处理中能够让服务器加载时只执行一次而当网页被返回给客户端时不被执行。
在Page_PreInit中可以使用IsPostBack来实现当网页第一次加载时IsPostBack属性为false当页面再次被加载时IsPostBack属性将会被设置为true。
IsPostBack属性的使用能够影响到应用程序的性能。
4.6.2 页面加载事件Page_Init Page_Init事件与Page_PreInit事件基本相同区别在于Page_Init并不能保证完全加载各个控件。
虽然在Page_Init事件中依旧可以访问页面中的各个空间但是当页面回送时Page_Init依然执行所有的代码并且不能通过IsPostBack来执行某些代码示例代码如下所示。
protected void Page_Initobject sender EventArgs e //Page_Init事件 if IsPostBack //判断是否第一次加载 Label1.Text “OK” //将成功信息赋值给标签 else Label1.Text “IsPostBack” //将回传的值赋值给标签 4.6.3 页面载入事件Page_Load 大多数初学者会认为Page_Load事件是当页面第一次访问触发的事件其实不然在
ASP.NET页生命周期内Page_Load远远不是第一次触发的事件通常情况下
ASP.NET事件顺序如下所示。
1. Page_Init。
2. Load ViewState。
104 3. Load Postback data。
4. Page_Load。
5. Handle control events。
6. Page_PreRender。
7. Page_Render。
8. Unload event。
9. Dispose method called。
Page_Load事件是在网页加载的时候一定会被执行的事件。
在Page_Load事件中一般都需要使用IsPostBack来判断用户是否进行了操作因为IsPostBack指示该页是否正为响应客户端回发而加载或者它是否正被首次加载和访问示例代码如下所示。
protected void Page_Loadobject sender EventArgs e //Page_Load事件 if IsPostBack Label1.Text “OK” //第一次执行的代码块 else Label1.Text “IsPostBack” //如果用户提交表单等 上述代码使用了Page_Load事件在页面被创建时系统会自动在代码隐藏页模型的页面中增加此方法。
当用户执行了操作页面响应了客户端回发则IsPostBack为true于是执行else中的操作。
4.6.4 页面卸载事件Page_Unload 在页面被执行完毕后可以通过Page_Unload事件用来执行页面卸载时的清除工作当页面被卸载时执行此事件。
以下情况会触发Page_Unload事件。
页面被关闭。
数据库连接被关闭。
对象被关闭。
完成日志记录或者其他的程序请求。
4.6.5 页面指令 页面指令用来通知编译器在编译页面时做出的特殊处理。
当编译器处理
ASP.NET应用程序时可以通过这些特殊指令要求编译器做特殊处理例如缓存、使用命名空间等。
当需要执行页面指令时通常的做法是将页面指令包括在文件的头部示例代码如下所示。
lt Page Language“C” AutoEventWireup“true” CodeBehind“Default.aspx.cs” Inherits“MyWeb._Default” gt ltDOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”gt 上述代码中就使用了Page页面指令来定义
ASP.NET页面分析器和编译器使用的特定页的属.