《征服ASP.NET2.0AJAX》一书的读后总结(第十五章Microsoft ASP.NET Ajax核心组件章)


<!--[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

你可能感兴趣的:(Microsoft)