<!--[if !supportLists]-->第一章<!--[endif]-->Microsoft ASP.NET Ajax核心组件
<!--[if !supportLists]-->1. <!--[endif]-->ScriptManager脚本控制器
ScriptManager控件包括在ASP.NET 2.0 AJAX Extensions中,它用来处理页面上的所有组件以及页面局部更新,生成相关的客户端代理脚本以便能够在JavaScript中访问Web Service,所有需要支持ASP.NET AJAX的ASP.NET页面上有且只能有一个ScriptManager控件。在ScriptManager控件中我们可以指定需要的脚本库,或者指定通过JS来调用的Web Service,还可以指定页面错误处理等。
使用<asp:ScriptManager/>来定义一个ScriptManager,简单的ScriptManager定义形式:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" AllowCustomErrorsRedirect="false" AsyncPostBackErrorMessage="" AsyncPostBackTimeout="90" OnAsyncPostBackError="" ScriptPath="" ScriptMode="Auto" OnResolveScriptReference="" >
<AuthenticationService Path=""/>
<ProfileService Path="" LoadProperties=""/>
<Scripts>
<asp:ScriptReference Path=""/>
</Scripts>
<Services>
<asp:ServiceReference Path="" />
</Services>
</asp:ScriptManager>
属性/方法
描述
EnablePartialRendering
标识此页内是否允许局部刷新
AllowCustomErrorsRedirect
但Ajax错误发生后,是否导航到Web.config中的自定义错误配置区<customErrors>,如果为false,则可以使用下面两个属性实现错误提示;
AsyncPostBackErrorMessage
异步回传发生错误时的自定义提示错误信息。
OnAsyncPostBackError
异步调用发生时的事件。异步回传发生异常时的服务端处理函数,在这里可以捕获一场信息并作相应的处理。
AsyncPostBackTimeout
异步调用的有效时间,默认值为90,单位为秒
ScriptMode
指定ScriptManager发送到客户端的脚本的模式,有四种模式:Auto,Inherit,Debug,Release,默认值为Auto,后面会仔细说到。
ScriptPath
设置所有的脚本块的根目录,作为全局属性,包括自定义的脚本块或者引用第三方的脚本块。如果在Scripts中的<asp:ScriptReference/>标签中设置了Path属性,它将覆盖该属性。
OnResolveScriptReference
指定ResolveScriptReference事件的服务器端处理函数,在该函数中可以修改某一条脚本的相关信息如路径、版本等。
AuthenticationService
用来提供验证服务的路径
ProfileService
个性化服务的路径
Scripts
对脚本的调用,可以实现多个脚本文件
Services
对服务的调用,可以实现多个服务
客户端脚本模式
在前面我们提到了ScriptMode属性指定ScriptManager发送到客户端的脚本的模式,它有四种模式:Auto,Inherit,Debug,Release,默认值为Auto。
1.Auto:它会根据Web站点的Web.config配置文件来决定使用哪一种模式,只有当配置文件中retail属性设置为false:
<!--[if !vml]--><!--[endif]--><system.web>
<!--[if !vml]--><!--[endif]--> <deployment retail="false" />
<!--[if !vml]--><!--[endif]--></system.web>
或者页面中的Debug指令设为true的时候会使用Debug版本,其他的情况都会使用Release版本。
<!--[if !vml]--><!--[endif]--><%@ Page Language="C#" Debug="true"AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2.Inherit:应该是通过程序设置ScriptMode的时候,等同于Auto?(不太了解)
3.Debug:客户端脚本使用Debug版本,除非retail(零售)属性设为true。
4.Release:客户端脚本使用Release版本,除非retail属性设为false。
调用脚本
(1)
Asp.net 2.0 注册脚本的方式
<head runat="server">
<title>统计工具</title>
<script type="text/jscript" src="../../js/OperateCookie.js"></script>
</head>
在Asp.net 2.0 Ajax中的脚本注册方式
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<Scripts>
<asp:ScriptReference Path="../../js/OperateCookie.js "/>
</Scripts>
</asp:ScriptManager>
上述两种定义方式运行后生成的客户端脚本完全一致;
(2)
Asp.net 2.0 Ajax的<Scripts>子元素还可以调用Ajax类库中已存在的Javascript脚本文件
<asp:ScriptManager ID="ScriptManager1" runat="server" >
<Scripts>
<asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js"/>
<%--Assembly:为脚本库类所在的程序集(Microsoft.Web.Preview为CTP增值组件),Name引用脚本文件名 --%>
</Scripts>
</asp:ScriptManager>
关于Scripts属性,最主要的属性有Path指定脚本的路径,ScriptMode指定客户端脚本的模式,它会覆盖ScriptManager中的ScriptMode属性,还有一个属性是IgnoreScriptPath,指定是否忽略掉ScriptManager中的ScriptPath属性。
调用web Service步骤:
<!--[if !supportLists]-->(1) <!--[endif]-->首先创建web Service,
<!--[if !supportLists]-->(2) <!--[endif]-->然后给给它添加[System.Web.Script.Services.ScriptService]属性,以便ScriptManager识别这个服务
/// <summary>
/// WebService1 的摘要说明
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService {
public WebService1 () {
//如果使用设计的组件,请取消注释以下行
//InitializeComponent();
}
[WebMethod]
public string HelloWorld() {
return "Hello World";
}
}
<!--[if !supportLists]-->(3) <!--[endif]-->在ScriptManager控件内注册服务
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService1.asmx" />
</Services>
</asp:ScriptManager>
<!--[if !supportLists]-->(4) <!--[endif]-->在页面的head元素内添加JavaScript对服务的引用
<head runat="server">
<title>无标题页</title>
<script type="text/javascript">
//引用web服务
function RefService1()
{
//返回值与js处理事件挂钩
WebService1.HelloWorld(GetResult);
}
function GetResult(result)
{
//提示返回数据
alert(result);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService1.asmx" />
</Services>
</asp:ScriptManager>
<input type="button" value="不带参数的服务" onclick="RefService1()" />
</div>
</form>
</body>
</html>
通过<asp:ServiceReference>标签可以在Services中注册一个WebService,在运行时ScriptManager将为每一个ServiceReference对象生成一个客户端代理,<asp:ServiceReference>标签一个很重要的属性是Path,用来指定WebService的路径
因为ScriptManager为服务器端控件所以也可以动态加载服务
//创建一个服务引用对象
ServiceReference service = new ServiceReference("WebService2.asmx");
//将服务对象添加到脚本控制器中
ScriptManager1.Services.Add(service);
错误处理
在页面回传时如果发生了异常AsyncPostBackError事件将被触发,错误信息的处理依赖于AllowCustomErrors属性、AsyncPostBackErrorMessage属性和Web.config中的<customErrors>配置区。下面看一个简单的错误处理例子,在AsyncPostBackError事件中捕获到异常信息并设置AsyncPostBackErrorMessage属性。
注:错误是针对局部刷新而言的,所以是处理UpdatePanel控件的错误;
2、ScriptManagerProxy控件
在ASP.NET AJAX中,由于一个ASPX页面上只能有一个ScriptManager控件,所以在有母版页的情况下,如果需要在Master-Page和Content-Page中需要引入不同的脚本时如在母版页引入A脚本可是还要在内容页引入B,如果母版页把A,B都引入的话,对于不需要B脚本的内容页就会影响性能,这就需要在Content-page中使用ScriptManagerProxy,而不是ScriptManager,ScriptManager 和 ScriptManagerProxy 是两个用法非常相似的控件。
3、UpdatePanel控件
UpdatePanel可以用来创建丰富的局部更新Web应用程序,它是ASP.NET 2.0 AJAX Extensions中很重要的一个控件,其强大之处在于不用编写任何客户端脚本,只要在一个页面上添加几个UpdatePanel控件和一个ScriptManager控件就可以自动实现局部更新。通过本文来学习一下UpdatePanel工作原理和使用方法。
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="always" ChildrenAsTriggers="true" RenderMode="Block">
<ContentTemplate>
<% =DateTime.Now.ToString() %>
<asp:Button ID="Button2" runat="server" Text="ButtonIN" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="" EventName="" />
<asp:PostBackTrigger ControlID="" />
</Triggers>
</asp:UpdatePanel>
属性
说明
ChildrenAsTriggers
当UpdateMode属性为Conditional时,UpdatePanel中的子控件的异步回送是否会引发UpdatePanle的更新。
RenderMode
表示UpdatePanel最终呈现的HTML元素。Block(默认)表示<div>,Inline表示<span>
UpdateMode
表示UpdatePanel的更新模式,有两个选项:Always和Conditional。Always是不管有没有Trigger,其他控件(所有UpdatePanel中包括的控件)都将更新该UpdatePanel,Conditional表示只有当前UpdatePanel的Trigger,或ChildrenAsTriggers属性为true时当前UpdatePanel中控件引发的异步回送或者整页回送,或是服务器端调用Update()方法才会引发更新该UpdatePanel。
Triggers
局部跟新触发器,一种是异步回发AsyncPostBackTrigger,可以实现局部刷新,另一种是PostBackTrigger不管是否使用了局部刷新控件,都会引起页面的全部刷新。
UpdatePanel工作原理
UpdatePanel的工作依赖于ScriptManager服务端控件和客户端PageRequestManager类(Sys.WebForms.PageRequestManager,在后面的客户端类中会专门说到),当ScriptManager中允许页面局部更新时,它会以异步的方式回传给服务器,与传统的整页回传方式不同的是只有包含在UpdatePanel中的页面部分会被更新,在从服务端返回HTML之后,PageRequestManager会通过操作DOM对象来替换需要更新的代码片段。
ContentTemplateContainer属性
如果要使用编程的手法去设置UpdatePanel中的内容,需要创建一个UpdatePanel,并且添加控件到ContentTemplateContainer,而不能直接添加控件到ContentTemplate,如果想直接设置ContentTemplate,则需要编写一个自定义的Template,并去实现位于System.Web.UI命名空间下的接口ITemplate。
<% <!--[if !vml]--><!--[endif]-->@ Page Language="C#" %>
<!--[if !vml]--><!--[endif]--> <!--[if !vml]--><!--[endif]--><script runat="server"> <!--[if !vml]--><!--[endif]-->
<!--[if !vml]--><!--[endif]--> protected void Page_Load(object sender, EventArgs e)
<!--[if !vml]--><!--[endif]--> <!--[if !vml]--><!--[endif]--> <!--[if !vml]--><!--[endif]-->{
<!--[if !vml]--><!--[endif]--> UpdatePanel up1 = new UpdatePanel();
<!--[if !vml]--><!--[endif]--> up1.ID = "UpdatePanel1";
<!--[if !vml]--><!--[endif]--> up1.UpdateMode = UpdatePanelUpdateMode.Conditional;
<!--[if !vml]--><!--[endif]--> Button button1 = new Button();
<!--[if !vml]--><!--[endif]--> button1.ID = "Button1";
<!--[if !vml]--><!--[endif]--> button1.Text = "Submit";
<!--[if !vml]--><!--[endif]--> button1.Click += new EventHandler(Button_Click);
<!--[if !vml]--><!--[endif]--> Label label1 = new Label();
<!--[if !vml]--><!--[endif]--> label1.ID = "Label1";
<!--[if !vml]--><!--[endif]--> label1.Text = "A full page postback occurred.";
<!--[if !vml]--><!--[endif]--> up1.ContentTemplateContainer.Controls.Add(button1)
<!--[if !vml]--><!--[endif]--> up1.ContentTemplateContainer.Controls.Add(label1);
<!--[if !vml]--><!--[endif]--> Page.Form.Controls.Add(up1);
<!--[if !vml]--><!--[endif]--> }
<!--[if !vml]--><!--[endif]--> protected void Button_Click(object sender, EventArgs e)
<!--[if !vml]--><!--[endif]--> <!--[if !vml]--><!--[endif]--> <!--[if !vml]--><!--[endif]-->{
<!--[if !vml]--><!--[endif]--> ((Label)Page.FindControl("Label1")).Text = "Panel refreshed at " +
<!--[if !vml]--><!--[endif]--> DateTime.Now.ToString();
<!--[if !vml]--><!--[endif]--> }
<!--[if !vml]--><!--[endif]--></script>
<!--[if !vml]--><!--[endif]--><html xmlns="http://www.w3.org/1999/xhtml"
<!--[if !vml]--><!--[endif]--><head id="Head1" runat="server">
<!--[if !vml]--><!--[endif]--> <title>UpdatePanel Added Programmatically Example</title>
<!--[if !vml]--><!--[endif]--></head>
<!--[if !vml]--><!--[endif]--><body>
<!--[if !vml]--><!--[endif]--> <form id="form1" runat="server">
<!--[if !vml]--><!--[endif]--> <div>
<!--[if !vml]--><!--[endif]--> <asp:ScriptManager ID="TheScriptManager"
<!--[if !vml]--><!--[endif]--> runat="server" />
<!--[if !vml]--><!--[endif]--> </div>
<!--[if !vml]--><!--[endif]--> </form>
<!--[if !vml]--><!--[endif]--></body>
<!--[if !vml]--><!--[endif]--></html>
4、UpdateProgress控件简单介绍
默认情况下,UpdageProgress控件将显示页面上所有的UpdatePanel控件更新的进度信息,在以前版本的UpdateProgress中,我们无法设置UpdateProgress只显示某一个UpdatePanel的更新,最新版本的UpdateProgress控件提供了AssociatedUpdatePanelID属性,可以指定UpdateProgress控件显示哪一个UpdatePanel控件。下面的这个例子中UpdateProgrss控件将只显示它所在的UpdatePanel更新信息。注:UpdateProgress实际是一个DIV,通过代码控制显示还是隐藏,并且放在<ContentTemplate>元素中;
<asp:UpdatePanel ID="UpdatePanel1" runat="server" RenderMode="Inline">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label" Width="228px"></asp:Label><br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="更新第一个" />
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="1000" >
<ProgressTemplate>
第一个正在更新......
</ProgressTemplate>
</asp:UpdateProgress>
</ContentTemplate>
</asp:UpdatePanel>
属性/方法
描述
AssociatedUpdatePanelID
表示关联的UpdatePanel
DisplayAfter
多长时间后显示进度条,默认为500单位毫秒
ProgressTemplate
用来设计显示的界面
客户端操作UpdateProgress(来自TerryLee AJAX入门
在本篇文章中,我们将通过编写JavaScript来使用客户端行为扩展UpdateProgress控件,客户端代码将使用ASP.NET AJAX Library中的PageRequestManager,在UpdateProgress控件中,将添加一个Button,来允许用户取消异步更新,并且使用客户端脚本来显示或者隐藏进度信息。
主要内容
1.通过客户端脚本取消异步更新
2.通过客户端脚本显示或者隐藏进度信息
一.通过客户端脚本取消异步更新
1.创建一个Web页面并切换到设计视图。
2.在工具箱中双击ScriptManager、UpdatePanel、UpdateProgress控件添加到页面中。添加后页面如下:
3.在UpdatePanel控件中添加一个Label控件并设置它的Text属性值为“Panel Rendered”。
4.添加一个Button控件并设置它的Text属性值为“refresh”。
5.在UpdateProgress控件中添加文本text Processing…,并添加一个HtmlButton控件并设置它的Text属性为cancle。
6.双击refresh控件添加Click事件。
7.在Buttond的Click事件处理中添加如下代码,人为的创建一个3秒钟的延迟并显示当前服务器的时间。
protected void Button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
Label1.Text = DateTime.Now.ToString();
}
8.添加如下脚本,获取一个当前PageRequestManager类的实例,并创建一个函数调用abortPostBack方法来停止异步更新。
<script language="javascript" type="text/javascript">
<!--
var prm = Sys.WebForms.PageRequestManager.getInstance();
function CancelAsyncPostBack() {
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
// -->
</script>
9.设置HtmlButton的click特性为CancelAsyncPostBack。
10.添加如下的样式块到<head>元素之间。
<style type="text/css">
#UpdatePanel1 {}{
width:200px; height:100px;
border: 1px solid gray;
}
#UpdateProgress1 {}{
width:200px; background-color: #FFC080;
bottom: 0%; left: 0px; position: absolute;
}
</style>
11.保存并按Ctrl + F5运行。
12.单击refresh按钮,经过短暂的延时之后显示进度信息,完成异步更新之后UpdatePanel中的信息显示为当前的服务器时间。
13.单击refresh按钮并立即单击Cancle按钮结束异步更新,注意到UpdatePanel中的时间信息并没有更新。
二.通过客户端脚本显示或者隐藏进度信息
在下列情况下,UpdateProgress控件将不会自动显示:
由UpdateProgress控件关联的UpdatePanel之外的控件引发的异步更新。
UpdateProgress控件没有关联任何UpdatePanel,不在UpdatePanel中的控件引发的异步更新(例如用代码实现的更新)。
下面的例子将展示一个不在UpdateProgress所关联的UpdatePanel中的控件所引发的异步更新时,如何显示UpdateProgress控件。
1.在我们前面所创建的页面中,切换到设计视图。
2.选中UpdateProgress控件,在属性窗口中,设置AssociatedUpdatePanelID属性为UpdatePanel1。
3.在UpdatePanel和UpdateProgress控件之外添加一个Button控件。
4.设置Button的Text属性值为Trigger,并设置ID属性为Panel1Trigger。
5.选择UpdatePanel控件,在属性窗口中Triggers属性行单击ellipsis (…)。
6.创建一个异步更新触发器,并设置控件ID为Panel1Trigger。
7.双击Trigger按钮添加Click事件。
8.在Buttond的Click事件处理中添加如下代码,人为的创建一个3秒钟的延迟并显示当前服务器的时间,并附加上一条信息表示是由触发器引发的异步更新。
protected void Panel1Trigger_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
Label1.Text = DateTime.Now.ToString() + " - trigger";
}
9.在代码窗口,在已有的<Script>脚本块中添加如下代码:
<script language="javascript" type="text/javascript"><!--
var prm = Sys.WebForms.PageRequestManager.getInstance();
function CancelAsyncPostBack() {
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var postBackElement;
function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id = 'Panel1Trigger') {
$get('UpdateProgress1').style.display = 'block';
}
}
function EndRequest(sender, args) {
if (postBackElement.id = 'Panel1Trigger') {
$get('UpdateProgress1').style.display = 'none';
}
}
</script>
10.保存并按Ctrl + F5运行。
11.单击Trigger按钮,如下所示:
5、 Timer控件的简单使用
<asp:Timer ID="Timer1" runat="server" Interval="3000" OnTick="Timer1_Tick">
</asp:Timer>
一个页面只有一个Timer控件实例,每隔Interval时间(毫秒),就执行一次OnTick事件
在服务器端跟新完UpdatePanel的ContentTemplate元素的内容后,自动的进行异步局部刷新;
Timer也可以作为UpdatePanel的触发器,触发事件为Tick;
Ajax 中的Web服务
<!--[if !supportLists]-->一、 <!--[endif]-->身份验证服务
<!--[if !supportLists]-->二、 <!--[endif]-->个性化配置服务
Ajax 的调试和跟踪
由于Ajax的内容进行了封装,如何查找错误的根源,就需要用Ajax的提供的调试类库。Ajax的调试类库位于Sys命令空间下,类库名为Debug主要用来跟踪和调试Ajax运行过程中出现的错误。要启用调试前要引用AJAX脚本类库,但ScriptManager控件会完成对AJAX脚本类库的引用;
方法
语法
描述
assert
Sys.Debug.assert(condition,message,diplayCaller)
有问题设置了断点
//断言
function btnAssert_onclick() {
txtv = form1.txtname.value;
Sys.Debug.assert(
(txtv !== ""),"必须输入姓名");
alert("你好 " + txtv + ".");
}
clearTrace
Sys.Debug.clearTrace(text)
//清空跟踪信息
function btnClear_onclick() {
Sys.Debug.clearTrace()
alert("跟踪信息清除完毕");
}
traceDump
Sys.Debug.traceDump(object,name)
跟踪对象信息,显示简单的摘要
//跟踪信息摘要
function btnDump_onclick() {
Sys.Debug.traceDump(form1.txtname,"TextBox控件");
alert("你好 " + form1.txtname.value + ".");
}
fail
Sys.Debug.fail(message)
错误调试,添加断点,有问题设置了端点
//错误
function btnFail_onclick() {
txtv = form1.txtname.value;
if (txtv == "") {
Sys.Debug.fail("必须输入姓名");
}
alert("你好 " + txtv + ".");
}
trace
Sys.Debug.trace(text )
写入跟踪信息到Trace输出流
//跟踪
function btnTrace_onclick() {
txtv = form1.txtname.value;
Sys.Debug.trace("您的名字是 " + "/"" + txtv + "/".");
alert("你好 " + txtv + ".");
}
调试这些方法时,首先要在IE浏览器为可调试脚本状态
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhang_xiao_qing_c_s_/archive/2009/02/10/3874114.aspx