16.2 ASP.NET 3.5AJAX控件

  在ASP.NET 3.5当中,系统提供了AJAX控件以便开发人员能够在ASP.NET 3.5中进行AJAX应用程序开发,通过使用AJAX控件能够减少大量的代码开发,为开发人员提供了AJAX应用程序搭建和应用的绝佳环境。

16.2.1 脚本管理控件(ScriptManger)
  脚本管理控件(ScriptManger)是ASP.NET AJAX中非常重要的控件,通过使用ScriptManger能够进行整个页面的局部更新的管理。ScriptManger用来处理页面上局部更新,同时生成相关的代理脚本以便能够通过JavaScript访问Web Service。
  ScriptManger只能在页面中被使用一次,这也就是说每个页面只能使用一个ScriptManger控件,ScriptManger控件用来进行该页面的全局管理。创建一个ScriptManger控件后系统自动生成HTML代码,示例代码如下所示。
+展开
-HTML
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>

  ScriptManger控件用户整个页面的局部更新管理,ScriptManger控件的常用属性如下所示:
1)AllowCustomErrorRedirect:指明在异步回发过程中是否进行自定义错误重定向。
2)AsyncPostBackTimeout:指定异步回发的超时事件,默认为90秒。
3)EnablePageMethods:是否启用页面方法,默认值为false。
4)EnablePartialRendering:在支持的浏览器上为UpdatePanel控件启用异步回发。默认值为True。
5)LoadScriptsBeforeUI:指定在浏览器中呈现UI之前是否应加载脚本引用。
6)ScriptMode:指定要在多个类型时可加载的脚本类型,默认为Auto。
  在AJAX应用中,ScriptManger控件基本不需要配置就能够使用。因为ScriptManger控件通常需要同其他AJAX控件搭配使用,在AJAX应用程序中,ScriptManger控件就相当于一个总指挥官,这个总指挥官只是进行指挥,而不进行实际的操作。
1.使用ScriptManger
  ScriptManger控件在页面中相当于指挥的功能,如果需要使用AJAX的其他控件,就必须使用ScriptManger控件并且页面中只能包含一个ScriptManger控件。示例代码如下所示。
+展开
-HTML
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text="这是一串字符" Font-Size="12px"></asp:Label>
                <br ><br >
                <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True" 
                ontextchanged="TextBox1_TextChanged">
</asp:TextBox>
                字符的大小(px)
            </ContentTemplate>
        </asp:UpdatePanel>   
    </div>
    </form>
</body>

  上述代码创建了一个ScriptManger控件和一个UpdatePanel控件用于AJAX应用开发。在UpdatePanel控件中,包含一个Label标签控件和一个TextBox文本框控件,当文本框控件的内容被更改时,则会触发TextBox1_TextChanged事件。TextChanged事件相应的CS代码如下所示。
+展开
-C#
       protected void TextBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
                Label1.Font.Size = FontUnit.Point(Convert.ToInt32(TextBox1.Text));//改变字体
            }
            catch
            {
                Response.Write("错误"); //抛出异常
            }
        }

  上述代码通过文本框中的输入进行字体控制,当输入一个数字字符串并失去焦点时,则会触发改事件并执行相应的代码,运行后如图16-10和图16-11所示。
输入字符大小
图16-10 输入字符大小
调整字体大小
图16-11 调整字体大小
2.捕获异常
  当页面回传发生异常时,则会触发AsyncPostBackError事件,示例代码如下所示。
+展开
-C#
        protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
        {
            ScriptManager1.AsyncPostBackErrorMessage = "回传发生异常:" + e.Exception.Message;
        }

  AsyncPostBackError事件的触发依赖于AllowCustomErrorsRedirct属性、AsyncPostBackErrorMessage属性和Web.config中的<customErrors>配置节。其中,AllowCustomErrorsRedirct属性指明在异步回发过程中是否进行自定义错误重定向,而AsyncPostBackErrorMessage属性指明当服务器上发生未处理异常时要发送到客户端的错误消息。示例代码如下所示。
+展开
-C#
        protected void Button1_Click(object sender, EventArgs e)
        {
            throw new ArgumentException();//抛出异常
        }

  上述代码当单击按钮控件时,则会抛出一个异常,ScriptManger控件能够捕获异常并输出异常,运行代码后系统会提示异常“回传发生异常:值不在预期范围内”。

16.2.2 脚本管理控件(ScriptMangerProxy)
  ScriptManger控件作为整个页面的管理者,ScriptManger控件能够提供强大的功能以致开发人员无需关心ScriptManger控件是如何实现AJAX功能的,但是一个页面只能使用一个ScriptManger控件,如果在一个页面中使用多个ScriptManger控件则会出现异常。
  在Web应用的开发过程中,常常需要使用到母版页。在前面的章节中提到,母版页和内容窗体一同组合成为一个新页面呈现在客户端浏览器,那么如果在母版页中使用了ScriptManger控件,而在内容窗体中也使用ScriptManger控件的话,整合在一起的页面就会出现错误。为了解决这个问题,就可以使用另一个脚本管理控件,ScriptMangerProxy控件。ScriptMangerProxy控件和ScriptManger控件十分相似,首先创建母版页,示例代码如下所示。
+展开
-HTML
<body>
    <form id="form1" runat="server">
    <div style="width:300px; float:left; background:#f0f0f0; height:300px">
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
        </asp:ContentPlaceHolder>
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
                <asp:ScriptManager ID="ScriptManager1" runat="server">
                </asp:ScriptManager>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="获取当前时间" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    <div style="width:300px; float:left; background:gray;color:White;height:300px">
        <asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>

  上述代码创建了母版页,并且母版页中使用了ScriptMangerProxy控件为母版页中的控件进行AJAX应用支持,母版页中按钮控件的事件代码如下所示。
+展开
-C#
        protected void Button1_Click(object sender, EventArgs e)
        {
            TextBox1.Text = "母版页中的时间为" + DateTime.Now.ToString(); //获取母版页时间
        }

  在内容窗体中可以使用母版页进行样式控制和布局,内容窗体页面代码如下所示。
+展开
-HTML
<%@ Page Language="C#" 
MasterPageFile="~/Site1.Master" 
AutoEventWireup="true" 
CodeBehind="MyScriptMangerProxy.aspx.cs" Inherits="_16_2.MyScriptMangerProxy" Title="无标题页" %>

    <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    </asp:Content>
    <asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolder2" runat="server">
        <asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server">
        </asp:ScriptManagerProxy>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="内容窗体时间" />
    </ContentTemplate>
    </asp:UpdatePanel>
        <br >
    </asp:Content>

  上述代码为内容窗体代码,在内容窗体中,使用了Site1.Master母版页作为样式控制,并且通过使用ScriptMangerProxy控件进行内容窗体AJAX应用的支持。运行后如图16-12所示。
ScriptMangerProxy控件
图16-12 ScriptMangerProxy控件
  ScriptMangerProxy控件与ScriptManger控件非常的相似,但是ScriptManger控件只允许在一个页面中使用一次。当Web应用需要使用母版页进行样式控制时,母版页和内容页都需要进行局部更新时ScriptManger控件就不能完成需求,使用ScriptMangerProxy控件就能够在母版页和内容页中都实现AJAX应用。

16.2.3 时间控件(Timer)
  在C/S应用程序开发中,Timer控件是最常用的控件,使用Timer控件能够进行时间控制。Timer控件被广泛的应用在Windows WinForm应用程序开发中,Timer控件能够在一定的时间内间隔的触发某个事件,例如每隔5秒就执行某个事件。
  但是在Web应用中,由于Web应用是无状态的,开发人员很难通过编程方法实现Timer控件,虽然Timer控件还是可以通过JavaScript实现,但是这样也是以复杂的编程的大量的性能要求为代价的,这样就造成了Timer控件的使用困难。在ASP.NET AJAX中,AJAX提供了一个Timer控件,用于执行局部更新,使用Timer控件能够控制应用程序在一段时间内进行事件刷新。Timer控件初始代码如下所示。
+展开
-HTML
        <asp:Timer ID="Timer1" runat="server">
        </asp:Timer>

  开发人员能够配置Timer控件的属性进行相应事件的触发,Timer的属性如下所示。
1)Enabled:是否启用Tick时间引发。
2)Interval:设置Tick事件之间的连续时间,单位为毫秒。
  通过配置Timer控件的Interval属性,能够指定Time控件在一定时间内进行事件刷新操作,示例代码如下所示。
+展开
-HTML
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
                <asp:Timer ID="Timer1" runat="server" Interval="1000" ontick="Timer1_Tick">
                </asp:Timer>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
    </form>
</body>

  上述代码使用了一个ScriptManage控件进行页面全局管理,ScriptManage控件是必须的。两外,在页面中使用了UpdatePanel控件,该控件用于控制页面的局部更新,而不会引发整个页面刷新。在UpdatePanel控件中,包括一个Label控件和一个Timer控件,Label控件用于显示时间,Timer控件用于每1000毫秒执行一次Timer1_Tick事件,Label1和Timer控件的事件代码如下所示。
+展开
-C#
        protected void Page_Load(object sender, EventArgs e)//页面打开时执行
        {
            Label1.Text = DateTime.Now.ToString();//获取当前时间
        }
        protected void Timer1_Tick(object sender, EventArgs e)//Timer控件计数
        {
            Label1.Text = DateTime.Now.ToString();//遍历获取时间
        }

  上述代码在页面被呈现时,将当前时间传递并呈现到Label控件中,Timer控件用于每隔一秒进行一次刷新并将当前时间传递并呈现在Label控件中,这样就形成了一个可以计数的时间。
Timer控件能够通过简单的方法让开发人员无需通过复杂的JavaScript实现Timer控制。但是从另一方面来讲,Timer控件会占用大量的服务器资源,如果不停的进行客户端服务器的信息通信操作,很容易造成服务器当机。

16.2.4 更新区域控件(UpdatePanel)
  更新区域控件(UpdatePanel)在ASP.NET AJAX是最常用的控件,在上面几节控件的讲解中,已经使用到UpdatePanel控件,这已经说明UpdatePanel控件是非常重要的AJAX控件。
  UpdatePanel控件使用的方法同Panel控件类似,只需要在UpdatePanel控件中放入需要刷新的控件就能够实现局部刷新。使用UpdatePanel控件,整个页面中只有UpdatePanel控件中的服务器控件或事件会进行刷新操作,而页面的其他地方都不会被刷新。UpdatePanel控件HTML代码如下所示。
+展开
-HTML
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        </asp:UpdatePanel>

  UpdatePanel控件可以用来创建局部更新,开发人员无需编写任何客户端脚本,直接使用UpdatePanel控件就能够进行局部更新,UpdatePanel控件的属性如下所示。
1)RenderMode:该属性指明UpdatePanel控件内呈现的标记应为<div>或<span>。
2)ChildrenAsTriggers:该属性指明来在UpdatePanel控件的子控件的回发是否导致UpdatePanel控件的更新,其默认值为True。
3)EnableViewState::指明控件是否自动保存其往返过程。
4)Triggers:指明可以导致UpdatePanel控件更新的触发器的集合。
5)UpdateMode:指明UpdatePanel控件回发的属性,是在每次进行事件时进行更新还是使用UpdatePanel控件的Update方法再进行更新。
6)Visible:UpdatePanel控件的可见性。
  UpdatePanel控件要进行动态更新,必须依赖于ScriptManage控件。当ScriptManage控件允许局部更新时,它会以异步的方式发送到服务器,服务器接受请求后,执行操作并通过DOM对象来替换局部代码,其原理如图16-15所示。
UpdatePanel控件异步请求示意图
图16-15 UpdatePanel控件异步请求示意图
  UpdatePanel控件包括ContentTemplate标签。在UpdatePanel控件的ContentTemplate标签中,开发人员能够放置任何ASP.NET控件这些控件到ContentTemplate标签中,这些控件就能够实现页面无刷新的更新操作,示例代码如下所示。
+展开
-HTML
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                <asp:Button ID="Button1" runat="server" Text="Button" />
        </ContentTemplate>
    </asp:UpdatePanel>

  上述代码在ContentTemplate标签加入了TextBox1控件和Button1控件,当这两个控件产生回发事件,并不会对页面中的其他元素进行更新,只会对UpdatePanel控件中的内容进行更新。UpdatePanel控件还包括Triggers标签,Triggers标签包括两个属性,这两个属性分别为AsyncPostBackTrigger和PostBackTrigger。
  AsyncPostBackTrigger用来指定某个服务器端控件,以及将其触发的服务器事件作为UpdatePanel异步更新的一种触发器,AsyncPostBackTrigger属性需要配置控件的ID和控件产生的事件名,示例代码如下所示。
+展开
-HTML
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <asp:Button ID="Button1" runat="server" Text="Button" />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="TextBox1" EventName="TextChanged" />
        </Triggers>
    </asp:UpdatePanel>

  而PostBackTrigger用来指定在UpdatePanel中的某个控件,并指定其控件产生的事件将使用传统的回发方式进行回发。当使用PostBackTrigger标签进行控件描述时,当该控件产生了一个事件,页面并不会异步更新,而会使用传统的方法进行页面刷新,示例代码如下所示。
+展开
-HTML
    <asp:PostBackTrigger ControlID="TextBox1" />

  UpdatePanel控件在ASP.NET AJAX中是非常重要的,UpdatePanel控件用于进行局部更新,当UpdatePanel控件中的服务器控件产生事件并需要动态更新时,服务器端返回请求只会更新UpdatePanel控件中的事件而不会影响到其他的事件。

16.2.5 更新进度控件(UpdateProgress)
  使用ASP.NET AJAX常常会给用户造成疑惑。例如当用户进行评论或留言时,页面并没有刷新,而是进行了局部刷新,这个时候用户很可能不清楚到底发生了什么,以至于用户很有可能会产生重复操作,甚至会产生非法操作。
更新进度控件(UpdateProgress)就用于解决这个问题,当服务器端与客户端进行异步通信时,需要使用UpdateProgress控件告诉用户现在正在执行中。例如当用户进行评论时,当用户单击按钮提交表单,系统应该提示“正在提交中,请稍后”,这样就提供了便利从而让用户知道应用程序正在运行中。这种方法不仅能够让用户操作更少的出现错误,也能够提升用户体验的友好度。UpdateProgress控件的HTML代码如下所示:
+展开
-HTML
    <asp:UpdateProgress ID="UpdateProgress1" runat="server">
        <ProgressTemplate>
            正在操作中,请稍后 ...<br >
        </ProgressTemplate> 
    </asp:UpdateProgress>

  上述代码定义了一个UpdateProgress控件,并通过使用ProgressTemplate标记进行等待中的样式控制。
  ProgressTemplate标记用于标记等待中的样式。当用户单击按钮进行相应的操作后,如果服务器和客户端之间需要时间等待,则ProgressTemplate标记就会呈现在用户面前,以提示用户应用程序正在运行。完整的UpdateProgress控件和UpdatePanel控件代码如下所示。
+展开
-HTML
    <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server">
            <ProgressTemplate>
                正在操作中,请稍后 ...<br >
                </ProgressTemplate>
            </asp:UpdateProgress>
                <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
                <asp:Button ID="Button1" runat="server" Text="Button" 
                onclick="Button1_Click" />

        </ContentTemplate>     
    </asp:UpdatePanel>

  上述代码使用了UpdateProgress控件用户进度更新提示,同时创建了一个Label控件和一个Button控件,当用户单击Button控件时则会提示用户正在更新,Button更新事件代码如下所示。
+展开
-C#
        protected void Button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(3000);//挂起3秒
            Label1.Text = DateTime.Now.ToString();//获取时间
        }

  上述代码使用了System.Threading.Thread.Sleep方法指定系统线程挂起的时间,这里设置3000毫秒,这也就是说当用户进行操作后,在这3秒的时间内会呈现“正在操作中,请稍后…”几个字样,当3000毫秒过后,就会执行下面的方法,运行后如图16-16和图16-17所示。
正在操作中
图16-16 正在操作中
操作完毕后
图16-17 操作完毕后
  在用户单击后,如果服务器和客户端之间的通信需要较长时间的更新,则等待提示语会出现正在操作中。如果服务器和客户端之间交互的时间很短,基本上看不到UpdateProgress控件的显示。虽然如此,UpdateProgress控件在大量的数据访问和数据操作中能够提高用户友好度,并避免错误的发生。

加支付宝好友偷能量挖...


评论(0)网络
阅读(141)喜欢(0)Asp.Net/C#/WCF