您的位置:首页 > 编程语言 > ASP

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

2009-02-10 14:47 513 查看

第一章Microsoft ASP.NET Ajax核心组件

1.
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:


<system.web>


<deployment retail="false" />


</system.web>
或者页面中的Debug指令设为true的时候会使用Debug版本,其他的情况都会使用Release版本。


<%@ 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步骤:
(1) 首先创建web Service,
(2) 然后给给它添加[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";

}
}
(3)
ScriptManager控件内注册服务
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="WebService1.asmx"
/>
</Services>

</asp:ScriptManager>
(4)
在页面的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、[b]ScriptManagerProxy[/b]控件
在ASP.NET AJAX中,由于一个ASPX页面上只能有一个ScriptManager控件,所以在有母版页的情况下,如果需要在Master-Page和Content-Page中需要引入不同的脚本时如在母版页引入A脚本可是还要在内容页引入B,如果母版页把A,B都引入的话,对于不需要B脚本的内容页就会影响性能,这就需要在Content-page中使用ScriptManagerProxy,而不是ScriptManager,ScriptManager 和 ScriptManagerProxy 是两个用法非常相似的控件。

3、[b]UpdatePanel[/b]控件
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。
<%

@ Page Language="C#" %>




<script runat="server">



protected void Page_Load(object sender, EventArgs e)






{


UpdatePanel up1 = new UpdatePanel();


up1.ID = "UpdatePanel1";


up1.UpdateMode = UpdatePanelUpdateMode.Conditional;


Button button1 = new Button();


button1.ID = "Button1";


button1.Text = "Submit";


button1.Click += new EventHandler(Button_Click);


Label label1 = new Label();


label1.ID = "Label1";


label1.Text = "A full page postback occurred.";


up1.ContentTemplateContainer.Controls.Add(button1)


up1.ContentTemplateContainer.Controls.Add(label1);


Page.Form.Controls.Add(up1);


}


protected void Button_Click(object sender, EventArgs e)






{


((Label)Page.FindControl("Label1")).Text = "Panel refreshed at " +


DateTime.Now.ToString();


}


</script>


<html xmlns="http://www.w3.org/1999/xhtml"


<head id="Head1" runat="server">


<title>UpdatePanel Added Programmatically Example</title>


</head>


<body>


<form id="form1" runat="server">


<div>


<asp:ScriptManager ID="TheScriptManager"


runat="server" />


</div>


</form>


</body>


</html>
4UpdateProgress控件简单介绍
默认情况下,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服务
一、 身份验证服务
二、 个性化配置服务

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浏览器为可调试脚本状态
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: