部分页呈现概述

更新:2007 年 11 月

部分页呈现可让您无需因回发而刷新整个页面,而仅仅是更新页面上已更改的各个区域。因此,用户不会在每次回发时看到整个页面重新加载,这使得用户能够更加顺畅地与网页进行交互。ASP.NET 使您能够将部分页呈现添加到新的或现有 ASP.NET 网页,而无需编写客户端脚本。

本主题包含以下部分:

  • 方案

  • 功能

  • 背景

  • 代码示例

  • 类参考

方案

您可以扩展现有的 ASP.NET 应用程序,并开发结合 AJAX(异步 JavaScript 和 XML)功能的新的应用程序。当您要执行以下操作时,请使用 AJAX 功能:

  • 使网页的格式更为丰富,对用户操作的响应能力更强,行为更类似于传统的客户端应用程序,从而改善用户的网页体验。

  • 减少整页刷新次数,避免页面闪动。

  • 启用跨浏览器兼容功能,而无需编写脚本。

  • 执行 AJAX 样式的客户端/服务器通信,而无需编写客户端脚本。

  • 使用 ASP.NET AJAX 控件工具箱中的控件和组件。

  • 开发自定义 ASP.NET AJAX 控件。

部分页呈现功能

部分页呈现依赖于 ASP.NET 中的服务器控件和 Microsoft AJAX Library 中的客户端功能。在启用部分页呈现时,不必使用 Microsoft AJAX Library,原因是在您使用 ASP.NET AJAX 服务器控件时,会自动提供此功能。不过,可以使用在客户端库中公开的 API 来启用其他 AJAX 功能。

支持部分页呈现的主要 ASP.NET 功能有:

  • 声明性模型,其工作方式类似于 ASP.NET 服务器控件。在很多方案中,您可以仅使用声明性标记指定部分页呈现。

  • 服务器控件,用于执行部分页更新所需的基础任务。这些控件包括 ScriptManager 控件和 UpdatePanel 控件。

  • ASP.NET AJAX 服务器控件和用于常见任务的 Microsoft AJAX Library 的集成。这些任务包括使用户能够取消回发、在异步回发的过程中显示自定义进度消息,以及确定如何处理并发的异步回发。

  • 部分页呈现的错误处理选项,这些选项使您能够自定义在浏览器中显示错误的方式。

  • 跨浏览器兼容性,在 ASP.NET 的 AJAX 功能中已内置此功能。只需使用服务器控件即可自动调用正确的浏览器功能。

背景

使用 ASP.NET Web 服务器控件构建的典型网页执行由用户在页面上的操作启动的回发,例如单击按钮。在响应中,服务器将呈现新的页面。通常,这将重新呈现在回发之间未更改的控件和文本。

通过部分页呈现,您可以异步刷新页面上的各个区域,使页面对用户的响应能力更强。您可以使用 ASP.NET AJAX Web 服务器控件实现部分页呈现,还可以选择使用 Microsoft AJAX Library 中的 API 编写客户端脚本。

用于部分页更新的服务器控件

若要将 AJAX 功能添加到 ASP.NET 网页,请标识页面上要更新的各个节。然后将这些节的内容置入 UpdatePanel 控件中。UpdatePanel 控件的内容可以是 HTML 或其他 ASP.NET 控件。然后可以将 UpdatePanel 控件像任何其他控件一样添加到页面中。例如,在 Visual Studio 中,您可以将控件从工具箱拖动到网页上,还可以通过在页面中使用声明性标记来添加控件。下面的示例演示 UpdatePanel 控件的标记。

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <!-- Place updatable markup and controls here. -->
    </ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <!-- Place updatable markup and controls here. -->
    </ContentTemplate>
</asp:UpdatePanel>

默认情况下,源自更新面板内部的控件(子控件)的回发会自动启动异步回发,并导致部分页更新。您还可以指定由更新面板之外的控件导致异步回发和刷新 UpdatePanel 控件的内容。导致异步回发的控件称为“触发器”。 有关触发器的更多信息,请参见创建具有多个 UpdatePanel 控件的简单 ASP.NET 页

异步回发与同步回发的工作方式非常类似。将发生所有服务器页面生命周期事件,并保留视图状态和窗体数据。但在呈现阶段,仅将 UpdatePanel 控件的内容发送到浏览器。页面的其余部分保持不变。

若要支持部分页呈现,必须在页面上放置 ScriptManager 控件。ScriptManager 控件可跟踪页面上的所有更新面板及其触发器。它在服务器上协调部分页呈现的行为,并确定因异步回发所要呈现的页面节。

下面的示例演示一个 UpdatePanel 控件,每当从该面板内产生一个回发时都将刷新其内容。

<%@ Page Language="VB" %>

<!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>Partial-Page Rendering Server-Side Syntax</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <asp:ScriptManager ID="ScriptManager1" runat="server" />
      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
      <ContentTemplate>
        <fieldset>
        <legend>UpdatePanel</legend>
        Content to update incrementally without a full
        page refresh. 
        <br />
        Last update:  <%=DateTime.Now.ToString() %>
        <br />
        <asp:Calendar ID="Calendar" runat="server"/>
        </fieldset>
      </ContentTemplate>
      </asp:UpdatePanel>
      <script type="text/javascript" language="javascript">
      var prm = Sys.WebForms.PageRequestManager.getInstance();
      prm.add_pageLoaded(PageLoadedEventHandler);
      function PageLoadedEventHandler() {
         // custom script
      }
      </script>
    </div>
    </form>
</body>
</html>
<%@ 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>Partial-Page Rendering Server-Side Syntax</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
      <asp:ScriptManager ID="ScriptManager1" runat="server" />
      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
      <ContentTemplate>
        <fieldset>
        <legend>UpdatePanel</legend>
        Content to update incrementally without a full
        page refresh. 
        <br />
        Last update:  <%=DateTime.Now.ToString() %>
        <br />
        <asp:Calendar ID="Calendar" runat="server"/>
        </fieldset>
      </ContentTemplate>
      </asp:UpdatePanel>
      <script type="text/javascript" language="javascript">
      var prm = Sys.WebForms.PageRequestManager.getInstance();
      prm.add_pageLoaded(PageLoadedEventHandler);
      function PageLoadedEventHandler() {
         // custom script
      }
      </script>
    </div>
    </form>
</body>
</html>

有关如何使用 UpdatePanel 控件以启动部分页呈现的更多示例,请参见代码示例节中所列的主题。

使用客户端脚本进行部分页更新

Microsoft AJAX Library 中的 ECMAScript (JavaScript) PageRequestManager 类支持部分页更新。该类在浏览器中运行,可管理对异步回发的响应并更新各区域中的内容。您无需执行任何操作,即可启用此功能。当您将一个或多个 UpdatePanel 控件和一个 ScriptManager 控件添加到页面上时,此功能会自动启用。

还可以使用 JavaScript 和 PageRequestManager 类自定义页面上的部分页更新。例如,您可以编写脚本以在多个异步回发正在进行的情况下,为特定的异步回发赋予优先级。还可以使用户能够取消正在进行中的回发。

下面的示例演示提供一个事件处理程序的客户端脚本,当页面完成加载时将调用该事件处理程序。

<script type="text/javascript" language="javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(PageLoadedEventHandler);
function PageLoadedEventHandler() {
   // custom script
}
</script>
<script type="text/javascript" language="javascript">
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(PageLoadedEventHandler);
function PageLoadedEventHandler() {
   // custom script
}
</script>

有关如何使用 Microsoft AJAX Library 以进行部分页呈现的更多信息,请参见处理 PageRequestManager 事件ASP.NET PageRequestManager 类概述

启用部分页呈现支持

通过设置 ScriptManager 控件的 EnablePartialRendering 属性,可以启用或禁用某个页的部分页呈现。还可以通过设置 ScriptManager 控件的 SupportsPartialRendering 属性,指定是否对某个页支持部分页呈现。如果未设置 SupportsPartialRendering 属性并且 EnablePartialRendering 属性为 true(默认值),则将使用浏览器的功能来确定是否支持部分页呈现。

如果某个页未启用部分页呈现、已禁用部分页呈现或在浏览器中不支持部分页呈现,则该页将使用回退行为。在通常情况下将执行异步回发的操作将改为执行同步回发并更新整个页面。页上的任何 UpdatePanel 控件都将被忽略,并按照其未在 UpdatePanel 控件内的相同方式来呈现控件的内容。

Bb386573.alert_note(zh-cn,VS.90).gif说明:

配置为旧式呈现方式的 ASP.NET 网页不支持 AJAX 功能。有关更多信息,请参见 ASP.NET 和 XHTML

代码示例

下面的示例演示实际运行的部分页呈现。有两个 UpdatePanel 控件。一个控件接受用户输入,另一个控件显示输入摘要。

<%@ Page Language="VB" %>
<%@ Import Namespace="System.Collections.Generic" %>

<!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 id="Head1" runat="server">
    <title>Enter New Employees</title>
    <script runat="server">
        Private EmployeeList As List(Of Employee)

        Protected Sub Page_Load()
            If Not IsPostBack Then
                EmployeeList = New List(Of Employee)
                EmployeeList.Add(New Employee(1, "Jump", "Dan"))
                EmployeeList.Add(New Employee(2, "Kirwan", "Yvette"))
                ViewState("EmployeeList") = EmployeeList
            Else
                EmployeeList = CType(ViewState("EmployeeList"), List(Of Employee))
            End If

            EmployeesGridView.DataSource = EmployeeList
            EmployeesGridView.DataBind()
        End Sub

        Protected Sub InsertButton_Click(ByVal sender As Object, ByVal e As EventArgs)
            If String.IsNullOrEmpty(FirstNameTextBox.Text) Or _
               String.IsNullOrEmpty(LastNameTextBox.Text) Then Return

            Dim employeeID As Integer = EmployeeList(EmployeeList.Count - 1).EmployeeID + 1

            Dim lastName As String = Server.HtmlEncode(FirstNameTextBox.Text)
            Dim firstName As String = Server.HtmlEncode(LastNameTextBox.Text)

            FirstNameTextBox.Text = String.Empty
            LastNameTextBox.Text = String.Empty

            EmployeeList.Add(New Employee(employeeID, lastName, firstName))
            ViewState("EmployeeList") = EmployeeList

            EmployeesGridView.DataBind()
            EmployeesGridView.PageIndex = EmployeesGridView.PageCount
        End Sub

        Protected Sub CancelButton_Click(ByVal sender As Object, ByVal e As EventArgs)
            FirstNameTextBox.Text = String.Empty
            LastNameTextBox.Text = String.Empty
        End Sub

        <Serializable()> _
        Public Class Employee
            Private _employeeID As Integer
            Private _lastName As String
            Private _firstName As String

            Public ReadOnly Property EmployeeID() As Integer
                Get
                    Return _employeeID
                End Get
            End Property

            Public ReadOnly Property LastName() As String
                Get
                    Return _lastName
                End Get
            End Property

            Public ReadOnly Property FirstName() As String
                Get
                    Return _firstName
                End Get
            End Property

            Public Sub New(ByVal employeeID As Integer, ByVal lastName As String, ByVal firstName As String)
                _employeeID = employeeID
                _lastName = lastName
                _firstName = firstName
            End Sub
        End Class

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        &nbsp;</div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
        <table>
            <tr>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                          <table cellpadding="2" border="0" style="background-color:#7C6F57">
                            <tr>
                              <td><asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox" 
                                             Text="First Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td><asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox" 
                                             Text="Last Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="LastNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td></td>
                              <td>
                                <asp:LinkButton ID="InsertButton" runat="server" Text="Insert" OnClick="InsertButton_Click" ForeColor="White" />
                                <asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" OnClick="CancelButton_Click" ForeColor="White" />
                              </td>
                            </tr>
                          </table>
                          <asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                    </asp:UpdatePanel>
                </td>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                            <asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan"
                                BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AutoGenerateColumns="False">
                                <FooterStyle BackColor="Tan" />
                                <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
                                <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
                                <HeaderStyle BackColor="Tan" Font-Bold="True" />
                                <AlternatingRowStyle BackColor="PaleGoldenrod" />
                                <Columns>
                                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
                                    <asp:BoundField DataField="LastName" HeaderText="Last Name" />
                                    <asp:BoundField DataField="FirstName" HeaderText="First Name" />
                                </Columns>
                                <PagerSettings PageButtonCount="5" />
                            </asp:GridView>
                            <asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                        <Triggers>
                            <asp:AsyncPostBackTrigger ControlID="InsertButton" EventName="Click" />
                        </Triggers>
                    </asp:UpdatePanel>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>

<!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>Enter New Employees</title>
    <script runat="server">
        private List<Employee> EmployeeList;

        protected void Page_Load()
        {
            if (!IsPostBack)
            {
                EmployeeList = new List<Employee>();
                EmployeeList.Add(new Employee(1, "Jump", "Dan"));
                EmployeeList.Add(new Employee(2, "Kirwan", "Yvette"));
                ViewState["EmployeeList"] = EmployeeList;
            }
            else
                EmployeeList = (List<Employee>)ViewState["EmployeeList"];

            EmployeesGridView.DataSource = EmployeeList;
            EmployeesGridView.DataBind();
        }

        protected void InsertButton_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(FirstNameTextBox.Text) ||
               String.IsNullOrEmpty(LastNameTextBox.Text)) { return; }

            int employeeID = EmployeeList[EmployeeList.Count-1].EmployeeID + 1;

            string lastName = Server.HtmlEncode(FirstNameTextBox.Text);
            string firstName = Server.HtmlEncode(LastNameTextBox.Text);

            FirstNameTextBox.Text = String.Empty;
            LastNameTextBox.Text = String.Empty;

            EmployeeList.Add(new Employee(employeeID, lastName, firstName));
            ViewState["EmployeeList"] = EmployeeList;

            EmployeesGridView.DataBind();
            EmployeesGridView.PageIndex = EmployeesGridView.PageCount;
        }

        protected void CancelButton_Click(object sender, EventArgs e)
        {
            FirstNameTextBox.Text = String.Empty;
            LastNameTextBox.Text = String.Empty;
        }

        [Serializable]
        public class Employee
        {
            private int _employeeID;
            private string _lastName;
            private string _firstName;

            public int EmployeeID
            {
                get { return _employeeID; }
            }

            public string LastName
            {
                get { return _lastName; }
            }

            public string FirstName
            {
                get { return _firstName; }
            }

            public Employee(int employeeID, string lastName, string firstName)
            {
                _employeeID = employeeID;
                _lastName = lastName;
                _firstName = firstName;
            }
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        &nbsp;</div>
        <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
        <table>
            <tr>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="InsertEmployeeUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                          <table cellpadding="2" border="0" style="background-color:#7C6F57">
                            <tr>
                              <td><asp:Label ID="FirstNameLabel" runat="server" AssociatedControlID="FirstNameTextBox" 
                                             Text="First Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="FirstNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td><asp:Label ID="LastNameLabel" runat="server" AssociatedControlID="LastNameTextBox" 
                                             Text="Last Name" ForeColor="White" /></td>
                              <td><asp:TextBox runat="server" ID="LastNameTextBox" /></td>
                            </tr>
                            <tr>
                              <td></td>
                              <td>
                                <asp:LinkButton ID="InsertButton" runat="server" Text="Insert" OnClick="InsertButton_Click" ForeColor="White" />
                                <asp:LinkButton ID="Cancelbutton" runat="server" Text="Cancel" OnClick="CancelButton_Click" ForeColor="White" />
                              </td>
                            </tr>
                          </table>
                          <asp:Label runat="server" ID="InputTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                    </asp:UpdatePanel>
                </td>
                <td style="height: 206px" valign="top">
                    <asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional">
                        <ContentTemplate>
                            <asp:GridView ID="EmployeesGridView" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan"
                                BorderWidth="1px" CellPadding="2" ForeColor="Black" GridLines="None" AutoGenerateColumns="False">
                                <FooterStyle BackColor="Tan" />
                                <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
                                <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" HorizontalAlign="Center" />
                                <HeaderStyle BackColor="Tan" Font-Bold="True" />
                                <AlternatingRowStyle BackColor="PaleGoldenrod" />
                                <Columns>
                                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" />
                                    <asp:BoundField DataField="LastName" HeaderText="Last Name" />
                                    <asp:BoundField DataField="FirstName" HeaderText="First Name" />
                                </Columns>
                                <PagerSettings PageButtonCount="5" />
                            </asp:GridView>
                            <asp:Label runat="server" ID="ListTimeLabel"><%=DateTime.Now %></asp:Label>
                        </ContentTemplate>
                        <Triggers>
                            <asp:AsyncPostBackTrigger ControlID="InsertButton" EventName="Click" />
                        </Triggers>
                    </asp:UpdatePanel>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

帮助和演练主题

类参考

下表列出了用于部分页呈现的关键服务器类。

说明

UpdatePanel

指定在部分页呈现过程中将更新的页面区域。

ScriptManager

管理 ASP.NET 中的 AJAX 组件、 ASP.NET 网页上的部分页呈现、客户端请求以及服务器响应。

ScriptManagerProxy

使嵌套组件能够向已在父元素中包含 ScriptManager 控件的页中添加脚本和服务引用。

下表列出了用于部分页呈现的关键客户端类。

说明

Sys.WebForms.PageRequestManager 类

管理客户端部分页呈现,并公开用于自定义客户端脚本的成员。

请参见

概念

UpdatePanel 控件概述

ASP.NET PageRequestManager 类概述