本文介绍了 ASP.NET 页的客户端代码的组成,如何呈现,回发机制的一些基本信息.
一. 分析 ASPX 代码
a. page标记
<%@ Page Language="C#"
AutoEventWireup="true"
CodeFile="Test.aspx.cs"
Inherits="Test"
%>
主要是影响隐藏代码的生成.
Language 属性指定在 Visual Studio 中创作代码隐藏类所使用的语言。系统将使用相同语言生成动态页类,以处理浏览器对 .aspx 资源的请求。CodeFile 属性指示存储代码隐藏类的源文件。Inherits 属性指示在代码文件中应当作为动态生成的页类的父类的代码隐藏类的名称。最后,AutoEventWireup 属性指示是否应当使用默认命名约定将处理代码映射到 Page 事件。如果将 AutoEventWireup 设置为 True,则可以在代码文件中添加 Page_Load 方法,以处理页面的 Load 事件,并且它将自动注册到 Page 的 Load 事件。隐式命名约定指示事件处理程序将采用 Page_XXX 格式,其中,XXX 可以是在 Page 类中定义的任何公共事件的名称。如果将 AutoEventWireup 设置为 false,则必须将 Page 类事件与它的处理程序进行显式绑定(this.Load += new EventHandler(Page_Load);)。
b.处理HTTP请求
当发生HTTP请求时,IIS会将请求转发给ASP.NET工作进程,该工作进程会创建一个运行时环境来处理HTTP请求.ASP.NET运行时环境的目标就是处理HTTP请求.负责处理HTTP请求并返回HTML标记的组件是HTTP处理程序.HTTP 处理程序是实现了 IHttpHandler 接口的类的实例。System.Web.UI.Page 类是 ASP.NET 中的一个最复杂的内置 HTTP 处理程序。每个 ASP.NET 请求都会映射到一个 HTTP 处理程序。如果在 AppDomain 中尚未提供正确的处理程序,则会动态地创建该处理程序,并将其存储在 Web 服务器计算机的 ASP.NET 临时文件夹中。对于名为 test.aspx 的页,将以类的形式创建一个名为 ASP.text_aspx 的 HTTP 处理程序。
二. 分析客户端代码
包含 runat="server" 的标记都将映射到一个服务器控件实例,会根据服务器的呈现方式生成HTML呈现到客户端.任何其他文本则映射到文字控件,并按原样一字不差地发出并呈现。Register 指令(如果有)帮助解析指向非标准控件的标记。通过分析可以得1.每个HTML都会有一个ID属性,保证了控件在客户端和服务器端名称的一致;
2.两个隐藏字段填充了HTML标记: __VIEWSTATE和__EVENTVALIDATION(后面内容将介绍 __VIEWSTATE和__EVENTVALIDATION).
三. 视图状态字段
__VIEWSTATE字段的内容代表了页最后在服务器上处理时的状态.视图状态是 ASP.NET 的最重要功能之一,因为它可以基于诸如 HTTP 这样的无状态协议实现状态编程。为了安全起见,应当基于每个请求而不是基于每个页来维护视图状态(即不把视图状态字段内容留在服务器上,或其他存储介质;防止多步处理时用户单击"后退"时带来的安全问题;页可以通过编程方式把__VIEWSTATE放入SESSION中,可以使用SessionPageStatePersister对象,重写Page类的PageStatePersister属性return new SessionPageStatePersister(this))。
特点:1.会使用 Base64 公式对视图状态编码并进行散列处理;2.可以禁止使用;3.无法保证数据的机密性,但可以保证不能被修改.
2.0下的特点:1.__VIEWSTATE字段包含了两部分内容:视图状态和控件状态;因为视图状态可以禁止使用,所以对一些控件的呈现产生影响,为了缓解这一问题,ASP.NET 2.0 引入了控件状态的概念。每个服务器控件都可以将任何关键属性打包到集合,并将它存储到页面的控件状态中。控件状态保存到 __VIEWSTATE 字段,但与传统的视图状态不同,它不能被禁用,并且始终可用。开发人员通过 Page 类的一对新的可重写方法 LoadControlState 和 SaveControlState 来管理控件状态。2.隐藏字段的总体大小是1.x中的相应字段大小的一半.
工作方式:页面发送时视图状态的内容外+服务器密钥进行散列计算,回发时页类中的代码会将视图状态的内容和散列值分离;下一步,它将基于检索到的视图状态内容和服务器密钥重新计算散列值;如果两个散列值不匹配;则引发安全异常.
_EVENTVALIDATION 隐藏字段是 ASP.NET 2.0 的新增安全措施。该功能可以阻止由潜在的恶意用户从客户端发送的未经授权的请求。
四. 回发机制(页面如何触发回发)
a.button回发的情况
页面触发HTML客户端事件onsubmit后,发送HTTP请求(其中页面ID信息),HTTP处理程序中扫描HTTP请求正文,确定按钮字段以运行它的Click事件关联代码.更准确地说,页类将检查并确定所匹配的按钮控件是否实现了 IPostBackEventHandler 接口。如果是,它将调用该接口的 RaisePostbackEvent 方法。对于按钮控件,该方法将引发服务器端的 Click 事件。
b.linkbutton回发的情况
使用linkbutton时页面会包括两个隐藏字段(__EVENTTARGET 和 __EVENTARGUMENT)和一些 JavaScript代码,linkbutton的href会绑定到__doPostBack教本函数.在linkbutton调用__doPostBack时会使用__EVENTTARGET 和 __EVENTARGUMENT填充适当的信息,然后通过脚本触发回发.如果在请求正文中引用的所有控件都未实现 IPostBackEventHandler 接口,则页类将查找 __EVENTTARGET 隐藏字段(如果有)。字段的内容假定为导致回发的控件的 ID。如果此控件实现了 IPostBackEventHandler 接口,则调用 RaisePostbackEvent 方法。对于 LinkButton 控件,这将导致调用 Click 服务器事件。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html >
<head><title>Test page</title></head>
<body>
<form name="form1" method="post" action="LinkBtn.aspx" id="form1">
<div>
<input type="hidden" name="__EVENTTARGET"
id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT"
id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEP ... Eag==" />
</div>
<script type="text/javascript">
<!--
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
// -->
</script>
<div>
<input name="TextBox1" type="text" value="" id="TextBox1" />
<a id="LinkButton1"
href="http://javascript:__doPostBack('LinkButton1','')">Click me</a>
<hr />
<h1></h1>
</div>
<div>
<input type="hidden" name="__EVENTVALIDATION" id=
"__EVENTVALIDATION"
value="/wEW ... JbJ" />
</div>
</form>
</body>
</html>