- 浏览: 615728 次
- 性别:
- 来自: 卡哇伊
-
文章分类
- 全部博客 (299)
- C# (25)
- Java (1)
- WinForm (0)
- Asp.Net (86)
- Jsp (2)
- Php (1)
- Web Service (0)
- Desgin Patterns (19)
- Data Structure & Algorithms (1)
- SQLserver (41)
- Mysql (0)
- Oracle (2)
- Javascript (50)
- Ajax (10)
- Jquery (1)
- Flex (0)
- Regular Expression (5)
- DIV+CSS+XHTML+XML (18)
- Software Test (0)
- Linux (0)
- Utility (17)
- Net Digest (4)
- windows 2003 (10)
- Other (4)
- English (1)
- IT Term (1)
最新评论
-
w497480098h:
学习了 很好谢谢
SQL Server下无限多级别分类查询解决办法(简单查询树形结构数据库表) -
main_fun:
确实不错
iframe自适应高度 -
jveqi:
...
DBA -
mxcie:
其它版本没有确认,今天使用vs2003时,其.sln文件也需要 ...
彻底删除项目的VSS源代码管理信息 -
moneyprosper:
就只有IE支持,火狐和谷歌都不支持此种方法。正在寻找中。。。
从父页面读取和操作iframe中内容方法
asp.net夜话之五:Page类和回调技术
在今天我主要要介绍的有如下知识点:
Page类介绍
Page的生命周期
IsPostBack属性
ClientScriptManager类
回调技术(CallBack)
Page类介绍
asp.net有时候也被成为WebForm,因为开发一个asp.net页面就像开发一个WinFrom窗体一样,我们同样可以采用拖拽控件、双击产生相关处理代码的方法。在asp.net中,创建一个页面可以采用两种模型。
单页模型
用Dreamweaver创建的asp.net页面就是单页模型,当然利用Visual Studio 2005也能创建单页模型,不过在Visual Studio 2005中创建的页面默认不是单页模型,要想在Visual Studio 2005创建单页模型的网页如下:
项处于未选中状态,默认情况下这个选项是处于选中状态的。这样就创建了单页模型的网页。
此时的页面代码如下:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
注意在页面中有这样一句代码:
- <script runat="server">
- </script>
这句代码与普通javascript语句块不同的是有一个runat="server"属性,表示这里的代码是在服务器上运行的C#代码。切换到设计视图,然后双击页面,然后这部分会变成如下的样子:
- <script runat="server">
- protected void Page_Load(object sender, EventArgs e)
- {
- }
- </script>
其中Page_Load就是页面加载的时候在服务器上运行的方法。
单页模型的特点是HTML标记、控件代码及服务器端运行的C#代码全部包含在一个aspx页面中,Web服务器第一次运行该页面的时候会将这个页面生成一个类文件,对于上面的Index.aspx页面,会生成ASP.Index_aspx的类,然后再将这个ASP.Index_aspx类编译成IL代码,Web服务器通过CLR(Common Language Runtime,通用语言运行环境)运行相应的IL代码。
单页模型的缺点是页面和代码混在一起,维护起来较为麻烦。
代码页面分离模式
代码页面模式就是将页的标记(HTML代码)和服务器端元素放在.aspx页面中,而也代码在位于一个.aspx.cs中。采用默认方式创建的aspx网页就是这种方式。
下面就是一个采用代码页面分离模式创建的Home.aspx页面的代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Home.aspx.cs" Inherits="Home" %> <!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 runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
其对应的页代码是:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Home : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } }
首先要关注的aspx的头部分代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Home.aspx.cs" Inherits="Home" %>
@Page是一个页面指令,在这里Language="C#"指明了当前页面采用的后台代码是C#语言,CodeFile="Home.aspx.cs"表示这个页面对应的页代码文件是Home.aspx.cs这个文件,Inherits="Home"表示当前aspx页继承自Home这个类。
现在再关注一下页代码文件声明:
public partial class Home : System.Web.UI.Page
从这部分代码可以看出Home类是继承自System.Web.UI.Page类的。注意这里还有一个C#2.0的关键字partial,这个关键字表示当前代码是一个局部类,以表示这个类是构成整个Web页面窗体的一部分。Web服务器运行这个页面的时候最终会将aspx页面和对应的页代码编译成一个类文件,然后生成IL代码。
代码页面分离模式的好处是页面展示部分和逻辑控制部分的代码分离开来,便于管理和维护,这也是微软推荐的开发方式。
asp.net页面的声明周期
asp.net页面运行的时候将经历一个声明周期,这个生命周期中会进行一系列的操作,调用一系列的方法。了解asp.net页面的生命周期对于精确控制页面的控件呈现方式和行为非常重要。
一般说来一个常规页面要经历如下几个生命周期阶段:
阶段 | 说明 |
页请求 | 页请求发生在页生命周期开始之前。用户请求页时,ASP.NET 将确定是否需要分析和编译页(从而开始页的生命周期),或者是否可以在不运行页的情况下发送页的缓存版本以进行响应。 |
开始 | 在开始阶段,将设置页属性,如 Request 和 Response。在此阶段,页还将确定请求是回发请求还是新请求,并设置 IsPostBack 属性。此外,在开始阶段期间,还将设置页的 UICulture 属性。 |
页初始化 | 页初始化期间,可以使用页中的控件,并将设置每个控件的 UniqueID 属性。此外,任何主题都将应用于页。如果当前请求是回发请求,则回发数据尚未加载,并且控件属性值尚未还原为视图状态中的值。 |
加载 | 加载期间,如果当前请求是回发请求,则将使用从视图状态和控件状态恢复的信息加载控件属性。 |
验证 | 在验证期间,将调用所有验证程序控件的 Validate 方法,此方法将设置各个验证程序控件和页的 IsValid 属性。 |
回发事件处理 | 如果请求是回发请求,则将调用所有事件处理程序。 |
呈现 | 在呈现期间,视图状态将被保存到页,然后页将调用每个控件,以将其呈现的输出提供给页的 Response 属性的 OutputStream。 |
卸载 | 完全呈现页、将页发送至客户端并准备丢弃时,将调用卸载。此时,将卸载页属性(如 Response 和 Request)并执行清理。 |
在页的生命周期中,一般会有如下事件:
页事件
|
典型使用 |
Page_PreInit | 使用 IsPostBack 属性确定是否是第一次处理该页。 创建或重新创建动态控件。 动态设置主控页。 动态设置 Theme 属性。 读取或设置配置文件属性值。 注意:如果请求是回发请求,则控件的值尚未从视图状态还原。如果在此阶段设置控件属性,则其值可能会在下一阶段被改写。 |
Page_Init | 读取或初始化控件属性。 |
Page_Load | 读取和更新控件属性。 |
Control events | 执行特定于应用程序的处理: 如果页包含验证程序控件,请在执行任何处理之前检查页和各个验证控件的 IsValid 属性。 处理特定事件,如 Button 控件的 Click 事件 |
Page_PreRender | 对页的内容进行最后更改。 |
Page_Unload | 执行最后的清理工作,可能包括: 关闭打开的文件和数据库连接。 完成日志记录或其他特定于请求的任务。 |
需要注意的是,每个asp.net控件也有与asp.net类似的生命周期,如果aspx页面中包含有asp.net服务器控件,那么在调用页面的方法时也会调用控件的相关方法。
另外,Web应用程序是无状态的。每次请求一个新网页或者刷新页面服务器都会创建一个当前页的新实例,这就意味着无法获取页面的以前的信息,如果确实需要这么做,需要采用额外的机制。
我们将刚才新建的Index.aspx页面中添加代码,如下:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> string date; protected void Page_Load(object sender, EventArgs e) { if (date == null)//如果date为空则设置为当前时间的字符串形式 { date = DateTime.Now.ToString(); } Response.Write("当前时间:"+date); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
按照正常理解,第一次运行的时候date字符串为null,会被设置成系统当前的字符串表示形式,并且输出,再次刷新的时候date字符串不再为空,会依然输出刚才的时间字符串,但是结果却不是这样。第一次运行的结果:
刷新页面之后的结果:
这就证明了即使是刷新当前页也会重新生成一个当前页面的实例,因为只有在生成页面新实例的情况下date字符串变量才为空,才会被重新设置值。
IsPostBack属性
Page类有一个IsPostBack属性,这个属性用来指示当前页面是第一次加载还是响应了页面上某个控件的服务器事件导致回发而加载。
这次我们继续对Index.aspx页面添加代码,在页面中增加了一个Button控件,如下:
<%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> string date; protected void Page_Load(object sender, EventArgs e) { if (date == null)//如果date为空则设置为当前时间的字符串形式 { date = DateTime.Now.ToString(); } Response.Write("当前时间:"+date); if (!Page.IsPostBack) { Response.Write("第一次加载。"); } else { Response.Write("响应客户端回发而加载。"); } } protected void btnOK_Click(object sender, EventArgs e) { } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>无标题页</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="btnOK" runat="server" OnClick="btnOK_Click" Text="提交" /></div> </form> </body> </html>
页面第一次运行的结果:
按一下F5刷新页面的结果:
点击一下“提交”按钮之后的结果:
由此可见每次打开一个页面和刷新一个页面效果都是一样的,只有响应客户端回发时IsPostBack属性才是true。了解这个属性和服务器采用了一种机制来“记录”服务器控件的状态这种做法(其实利用了ViewState和ControlState机制,这部分后续文章中会讲到)对于将来数据绑定会有很大作用。
动态输出javascript脚本
对于Index.aspx页面上面的执行情况,我们看到了满意的结果。我们再来看一下这个页面在客户端生成的HTML代码,在浏览器窗口打开的页面点鼠标右键,然后选择“查看源文件”,HTML代码如下:
当前时间:2008-9-21 0:04:33响应客户端回发而加载。 <!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><title> 无标题页 </title></head> <body> <form name="form1" method="post" action="Index.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTY3NzE5MjIyMGRkD2VvJFADDdEHh4W9UfAyzIvI3ss=" /> </div> <div> <input type="submit" name="btnOK" value="提交" id="btnOK" /></div> <div> <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgL8vZamCQLdkpmPAeM33vfm1ARVNKdKAoq5+eQdFI1J" /> </div></form> </body> </html>
我们会看到“当前时间:2008-9-21 0:04:33响应客户端回发而加载。”这句话位于<html></html>标记之外。在第一夜时候就提到过,asp.net页面是满足XML标准的HTML语言,但是通过在Page_Load事件中利用Response属性会将文字输出在<html></html>标记之外,不符合XHTML标准。这对于普通页面来说也许并无大碍,但是如果在频繁输出javascript脚本的网页中,可能会对网页的客户端执行效果产生影响。因为javascript脚本块在客户端调用方法之前还是客户端调用方法之后效果可能会不一样。
下面在Home窗体的Page_Load事件中添加代码,如下:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Home : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { Response.Write("<script language='javascript'>alert('" + DateTime.Now.ToString() + "')</script>"); } } }
这样每次运行Home.aspx页面的时候都会弹出一个对话框,如下图:
这不是我们所关心的,我们关注的是生成的HTML代码,如下:
<script language='javascript'>alert('2008-9-21 0:22:52')</script> <!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><title> 无标题页 </title></head> <body> <form name="form1" method="post" action="Home.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGTB6tgIyCoS2q3pZeKmhFwC24pQzw==" /> </div> <div> </div> </form> </body> </html>
可以看见输出的javascript代码在<html></html>标记之外。
在Page类中有一个ClientScript属性,它是ClientScriptManager的实例,这个类是在asp.net2.0中新增的。ClientScriptManager有如下几个常用方法:
RegisterClientScriptBlock方法:向 Page 对象注册客户端脚本。
RegisterStartupScript方法:向 Page 对象注册启动脚本。
ClientScriptManager类通过键string和Type来唯一标识脚本。具有相同类型的键和Type的脚本识为同一脚本。
下面对Home窗体的Page_Load事件中输入如下代码:
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class Home : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!ClientScript.IsClientScriptBlockRegistered(this.GetType(), "ClientScriptBlock")) { ClientScript.RegisterClientScriptBlock(this.GetType(), "ClientScriptBlock", "<script language='javascript'>alert('ClientScriptBlock')</script>"); } if (!ClientScript.IsStartupScriptRegistered(this.GetType(), "StartupScript")) { ClientScript.RegisterStartupScript(this.GetType(), "StartupScript", "<script language='javascript'>alert('StartupScript')</script>"); } //Response.Write("<script language='javascript'>alert('" + DateTime.Now.ToString() + "')</script>"); } }
执行该页面时,会弹出两个提示窗口,生成的HTML代码如下:
<!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><title> 无标题页 </title></head> <body> <form name="form1" method="post" action="Home.aspx" id="form1"> <div> <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNzgzNDMwNTMzZGTB6tgIyCoS2q3pZeKmhFwC24pQzw==" /> </div> <script language='javascript'>alert('ClientScriptBlock')</script> <div> </div> <script language='javascript'>alert('StartupScript')</script></form> </body> </html>
可以看出上面的两个方法输出的javascript脚本都在<form></form>标记之内,不会破环文章的结构,而且RegisterClientScriptBlock方法输出的javascript脚本代码块靠近<form>标记的开始标记,而RegisterStartupScript方法输出的javascript脚本代码块靠近<form>标记的结束标记,了解这一点对于控制动态添加的客户端脚本的时间是非常有利的。
回调技术(CallBack)
在asp.net中客户端与服务器端的交互默认都是整页面提交,此时客户端将当前页面表单中的数据(包括一些自动生成的隐藏域)都提交到服务器端,服务器重新实例化一个当前页面类的实例响应这个请求,然后将整个页面的内容重新发送到客户端,这种处理方式对运行结果没什么影响,不过这种方式加重了网络的数据传输负担、加大了服务器的工作压力,并且用户还需要等待最终处理结果。假如是我们希望有这么一个功能,当用户填写完用户名之后就检查服务器数据库里是否已存在该用户名,如果存在就给出已经存在此用户名的提示,如果不存在就提示用户此用户名可用,对于这种情况其实只需要传递一个用户名作为参数即可,上面的做法却需要提交整个表单,有点小题大做。解决上面的问题的办法目前主流做法有三种:纯javascript实现、微软Ajax类库实现还有用AjaxPro实现。后两种做法在稍后的文章中会讲到,这里我讲另外一种实现:通过回调技术。
创建实现回调技术的网页与普通asp.net网页类似,只不过还需要做以下特殊工作:
(1)让当前页面实现ICallbackEventHandler接口,这个接口定义了两个方法:string GetCallbackResult ()方法和void RaiseCallbackEvent (string eventArgument)方法。其中GetCallbackResult ()方法的作用是返回以控件为目标的回调事件的结果,RaiseCallbackEvent()方法的作用是处理以控件为目标的回调事件。
(2)为当前页提供三个javascript客户端脚本函数。一个javascript函数用于执行对服务器的实际请求,在这个函数中可以提供一个字符串类型的参数发送到服务器端;另一个javascript函数用于接收服务器端方法的执行后返回的字符串类型结果,并处理这个结果;还有一个是执行对服务器请求的帮助函数,在服务器代码中通过GetCallbackEventReference()方法获取这个方法的引用时由asp.net自动生成这个函数。
下面我以一个详细的例子来讲述如何使用回调,用Dreamweaver创建一个Register. aspx页面,代码如下:
<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %> <%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %> <%@ Import Namespace="System.Text" %> <!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> <script language="javascript"> //客户端执行的方法 //下面的方法是接收并处理服务器方法执行的返回结果 function Success(args, context) { message.innerText = args; } //下面的方式是当接收服务器方法处理的结果发生异常时调用的方法 function Error(args, context) { message.innerText = '发生了异常'; } </script> <script language="c#" runat="server"> string result=""; // 定义在服务器端运行的回调方法. public void RaiseCallbackEvent(String eventArgument) { if(eventArgument.ToLower().IndexOf("admin")!=-1) { result=eventArgument+"不能作为用户名注册。"; } else { result=eventArgument+"可以注册。"; } //throw new Exception(); } //定义返回回调方法执行结果的方法 public string GetCallbackResult() { return result; } //服务器上执行的方法 public void Page_Load(Object sender,EventArgs e) { // 获取当前页的ClientScriptManager的引用 ClientScriptManager csm = Page.ClientScript; // 获取回调引用。会在客户端生成WebForm_DoCallback方法,调用它来达到异步调用。这个方式是微软写的方法,会被发送到客户端 //注意这里的"Success"和"Error"两个字符串分别客户端代码中定义的两个javascript函数 //下面的方法最后一个参数的意义:true表示执行异步回调,false表示执行同步回调 String reference = csm.GetCallbackEventReference(this, "args","Success","","Error",false); String callbackScript = "function CallServerMethod(args, context) {\n" + reference + ";\n }"; // 向当前页面注册javascript脚本代码 csm.RegisterClientScriptBlock(this.GetType(), "CallServerMethod", callbackScript, true); } </script> </head> <body> <form id="form1" runat="server"> <table border="1" cellpadding="0" cellspacing="0" width="400px"> <tr> <td width="100px">用户名</td><td><input type="text" size="10" maxlength="20" id="txtUserName" onblur="CallServerMethod(txtUserName.value,null)" /><span id="message"></span></td> </tr> <tr> <td>密码</td><td><input type="password" size="10" maxlength="20" id="txtPwd" /></td> </tr> </table> </form> </body> </html>
上面的页面中我已经添加了足够详尽的注视,不过我还是要说明几点:
(1)
<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
这句表示当前页面实现了ICallbackEventHandler接口,如果采用页面与代码分离的模式,后台cs代码则应是:
public partial class Register : System.Web.UI.Page, ICallbackEventHandler { //cs代码 }
(2)
- <input type="text" size="10" maxlength="20" id="txtUserName" onblur="CallServerMethod(txtUserName.value,null)" />
(3)
- csm.GetCallbackEventReference(this, "args","Success","","Error",false);
中的"Success"和"Error"分别代表客户端的javascript函数,可以在代码中见到,其中"Success"代表调用服务器端方法成功后要执行的客户端方法名,"Error"代表调用服务器端方法失败时调用的客户端方法名。
该页面在客户端生成的HTML代码如下:
<!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> <script language="javascript"> //客户端执行的方法 //下面的方法是接收并处理服务器方法执行的返回结果 function Success(args, context) { message.innerText = args; } //下面的方式是当接收服务器方法处理的结果发生异常时调用的方法 function Error(args, context) { message.innerText = '发生了异常'; } </script> </head> <body> <form name="form1" method="post" action="register.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="/wEPDwUKMjA0MjMxNTU1OGRkIv6UMIqGy3vfPLfPRjEbuTwUrf8=" /> </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> <script src="/WebResource.axd?d=CcZ-_AaHZnD65xnNHEUijg2&t=633578466781093750" type="text/javascript"></script> <script type="text/javascript"> <!-- function CallServerMethod(args, context) { WebForm_DoCallback('__Page',args,Success,"",Error,false); }// --> </script> <table border="1" cellpadding="0" cellspacing="0" width="400px"> <tr> <td width="100px">用户名</td><td><input type="text" size="10" maxlength="20" id="txtUserName" onblur="CallServerMethod(txtUserName.value,null)" /><span id="message"></span></td> </tr> <tr> <td>密码</td><td><input type="password" size="10" maxlength="20" id="txtPwd" /></td> </tr> </table> <script type="text/javascript"> <!-- WebForm_InitCallback();// --> </script> </form> </body> </html>
在生成的HTML代码中多了几段javascipt教本块,下面分别说明:
(1)第一部分
<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>
这部分代码是每个asp.net页面发送到客户端都会生成的,用于提交当前表单,其中eventTarget参数表示激发提交事件的控件,eventArgument参数表示发生该事件时的参数信息。
(2)第二部分
<script src="/WebResource.axd?d=CcZ-_AaHZnD65xnNHEUijg2&t=633578466781093750" type="text/javascript"></script>
这部分代码是用来生成一些用于Ajax调用的js脚本。说穿了,asp.net之所以开发起来方便,是因为微软在幕后默默地为我们做了很多工作,回调的本质其实就是Ajax调用。
我们可以将“/WebResource.axd?d=CcZ-_AaHZnD65xnNHEUijg2&t=633578466781093750”这部分拷贝到浏览器地址栏中,如下图:
回车之后会弹出一个下载文件对话框,如下图:
将这个页面保存到本地,虽然默认的保存文件的后缀为“.axd”,但它其实是一个文本文件,里面是一些javascript代码,我们可以用记事本打开,在里面我们可以看到“WebForm_DoCallback”这个方法,如下:
在这个axd文件里做了很多幕后工作,所以我们的回调才相对比较简单。
(3)第三部分
<script type="text/javascript"> <!-- function CallServerMethod(args, context) { WebForm_DoCallback('__Page',args,Success,"",Error,false); }// --> </script>
这部分代码是后台生成的,通过获取Page类的ClientScript属性,也就是ClientScriptManager的实例注册到页面的,里面定义了两个javascript函数:CallServerMethod函数和WebForm_DoCallback函数,并且是在CallServerMethod函数中调用WebForm_DoCallback函数。
(4)第四部分
<script type="text/javascript"> <!-- WebForm_InitCallback();// --> </script>
这部分代码也是幕后生成的,这个javascript函数也可以在那个axd文件中找到。如下图:
当我们在以除“admin”之外的字符串作为用户名并移开焦点之后,会得到可以注册的提示,如下图:
当我们输入“admin”作为用户名时的结果:
另外,我们将服务器端执行的方法做如下处理,也就是RaiseCallbackEvent(String eventArgument)这个方法,我们在这里抛出一个异常,代码如下:
// 定义在服务器端运行的回调方法. public void RaiseCallbackEvent(String eventArgument) { /* if(eventArgument.ToLower().IndexOf("admin")!=-1) { result=eventArgument+"不能作为用户名注册。"; } else { result=eventArgument+"可以注册。"; } */ throw new Exception(); }
再次运行,无论我们以什么作为用户名,都会得到如下结果:
之所以会出现“发生了异常”这个字符串,是因为我们定义了function Error(args, context)这个javascript函数,并且把它作为调用服务器端方法发生异常时的客户端处理函数,它的处理方式就是显示“发生了异常”这个字符串。
发表评论
-
JS操作RadioButtonList
2009-12-16 23:25 3905function IsUpPic() { ... -
asp.net跳转页面的三种方法比较
2009-10-22 14:16 25471.Response.redir ... -
ASP.NET网站中的安全问题
2009-10-20 16:57 1197在网络经常看到网站被 ... -
新闻内容页分页的简单做法
2009-10-10 10:08 1228该例子只是提供了基本思路 很简单的做法,这个是假设数 ... -
Asp.net控件开发学习笔记(二)-控件开发基础
2009-10-03 16:49 1349接上篇…….. 看System.Web.UI.Ht ... -
Asp.net控件开发学习笔记-控件开发基础(一)
2009-10-03 16:33 1253服务器控件开发基础 当开发一个服务器控件时,首 ... -
Asp.net用户退出,清空Session,重定向登陆页面
2009-09-28 16:22 4185protected void Page_Load(object ... -
frameset中的aspx无法Postback
2009-09-28 16:07 1508<frameset cols="150,*&q ... -
.net页面定时刷新的几种简单方式
2009-09-28 11:20 59321: window.setTimeout("win ... -
动态添加TextBox
2009-09-21 16:30 1692方法1: 前台代码: <f ... -
浅谈ASP.NET管道优化
2009-09-20 21:43 1019ASP.NET管道优化 位于请求管道中的很多ASP.NET默 ... -
Asp.net 页面返回到上一页面
2009-09-20 21:20 921/// <summary> / ... -
PrecompiledApp.config文件和Global.asax 文件中的事件的关联
2009-09-19 10:24 2796在用Microsoft Visual Studio 2005开 ... -
gridview列 数字、货币和日期 显示格式
2009-09-11 17:05 1543在设置gridview等数据绑定控件的模版列时,总要 ... -
ASP.NET 打开新窗口几种方法
2009-09-09 21:44 3351ASP.NET打开新窗口方法一: Response ... -
response.addHeader("Content-Disposition","attachment; filename="+filename)中的中文乱码
2009-08-31 15:10 3269两种解决方法 1.如果web.config里utf-8 直接S ... -
技巧和诀窍:如何在VS 2005 SP1中使用VS的web服务器运行一个相对于根目录“/”的网站
2009-08-31 08:29 871大家常有一个疑问,是 ... -
Request.ServerVariables详细说明及代理
2009-08-14 10:46 2153ServerVariables是环境变量的集合。允许读取HTT ... -
DataList和Repeat无数据时提示暂无数据几种方法
2009-08-11 18:45 25791.放一个label DataTable table ... -
Asp.Net中清空所有textbox的几种方法
2009-08-08 08:53 5198用反射: FieldInfo[] info ...
相关推荐
五、 ASP.NET 夜话之 5 : Page 类和回调技术 六、 ASP.NET 夜话之 6 : ASP.NET 基本控件 七、 ASP.NET 夜话之 7 : ADO.NET 介绍 八、 ASP.NET 夜话之 8 :数据绑定控件 九、 ASP.NET 夜话之 9 :验证控件 十、 ...
**Asp.net夜话之一:asp.net介绍** Asp.Net是微软公司开发的一款用于构建Web应用程序的框架,它为开发者提供了高效、强大的工具和语言支持,使得开发动态网站、Web服务以及Web应用程序变得更为便捷。在本文中,我们...
总的来说,掌握Page类的使用、理解Page生命周期、熟悉IsPostBack属性、善用ClientScriptManager以及精通回调技术,是每个ASP.NET开发者必备的技能。这些知识点的深入理解和应用,将有助于你构建更加高效、交互性更强...
本教程"ASP.NET经典教程 ASP.NET夜话"旨在帮助初学者快速入门,掌握ASP.NET的核心概念和技术。 1. **ASP.NET概述**: ASP.NET是一个服务器端的开发平台,它允许开发者使用各种编程语言(如C#、VB.NET)来创建动态...
第五章:Page类和回调技术 在这一章,作者深入剖析了Page类,这是ASP.NET Web Forms的基础。同时,章节还涵盖了回调技术,如UpdatePanel和AJAX,使得Web应用能够实现部分页面更新,提升用户体验。 第六章:ADO.NET...
第05章 — Page类和回调技术 第06章 — ASP.NET基本控件 第07章 — ADO.NET介绍 第08章 — 数据绑定控件 第09章 — 验证控件 第10章 — 复合控件和母版页 第11章 — web.config详解 第12章 — ASP.NET底层探秘 第13...
《ASP.NET夜话》是由知名IT专家周金桥先生撰写的一部关于ASP.NET技术的著作,这本书以其深入浅出的讲解方式,深受初学者和有经验的开发者的喜爱。在提供的压缩包文件中,包含的“asp.net夜话”很可能是指一系列与该...
《Asp.net夜话》是一本深度探讨ASP.NET技术的专业书籍,由资深IT从业者撰写,旨在用通俗易懂的语言解析这一强大的Web开发框架。ASP.NET是Microsoft .NET Framework的重要组成部分,用于构建动态、数据驱动的Web应用...
ASP.NET夜话
ASP.NET夜话:从.NET的基础出发,在适当的地方加以延伸和拓展,使之更贴近企业开发。书中系统地讲解了。NET企业开发的多个层面,主要知识点包括:表单知识、.NET运行机制、Visual Studio 2008技巧、ASP.NET服务器...
《Asp.net夜话》是一本专为ASP.NET初学者设计的教程,旨在提供全面而深入的ASP.NET技术解析,帮助读者快速掌握这门强大的Web应用程序开发框架。这本书以易于理解的方式介绍了ASP.NET的核心概念、架构和开发流程,是...
表单知识、.NET运行机制、Visual Studio 2008技巧、ASP.NET服务器控件的使用、SQL注入防范、单元测试、三层架构、报表、数据加密/解密、GDI+、ADO.NET、分布式开发、AJAX开发及静态页面生成技术、高性能ASP.NET应用...
《ASP.NET夜话 周公》是一本深入浅出的ASP.NET技术解析书籍,它以其详尽的实例和通俗易懂的语言深受读者喜爱。这本书主要涵盖了.NET框架下的ASP.NET开发技术,尤其针对C#编程语言的应用进行了深度探讨。通过本书,...
“ASP.NET夜话”及其配套光盘为学习ASP.NET提供了全方位的支持,从理论讲解到实践操作应有尽有。通过仔细阅读书籍内容、研究源代码、观看教学视频,学习者不仅可以系统地掌握ASP.NET开发技术,还能培养出解决实际...
"ASP.NET夜话源码 书中实例与数据库"是一个资源集合,包含了《ASP.NET夜话》这本书中的实际编程示例和相关数据库文件,旨在帮助读者深入理解和实践书中的理论知识。 首先,让我们来探讨ASP.NET的核心概念。ASP.NET...
本资源"ASP.NET开发典型模块大全"是一个全面的教程集合,旨在帮助开发者深入理解和掌握ASP.NET的各种核心概念和技术。 1. **基础概念**: - ASP.NET架构:了解ASP.NET的基础结构,包括页面生命周期、事件处理模型...
这是第六版的介绍《ASP.NET 4入门经典:涵盖C#和VB.NET(第6版)》内容简介:ASP.NET是.NET Framework的一部分,用于构建内容丰富的动态Web站点。其最新的版本ASP.NET 4对上一版进行了许多改进,包括增强了Web窗体,并...
1.asp.net介绍 2.asp.net内置对象 3.asp.net表单和控件 4.asp.net容易被忽略的技巧 5.page类和回调技术 6.基本控件 7.数据绑定控件 8.验证控件 9.复合控件和母版页