Общие сведения о частичной отрисовке страниц

Обновлен: Ноябрь 2007

Технология частичной отрисовки страниц избавляет от необходимости обновления всей страницы в ответ на обратную передачу. Вместо этого изменяются и обновляются лишь отдельные части страницы. В результате пользователь не наблюдает процесс перезагрузки всей страницы при каждой обратной передаче, что делает пользовательский интерфейс страницы более естественным. ASP.NET позволяет реализовывать частичная отрисовка новых или существующих веб-страниц ASP.NET без написания клиентского сценария.

В этом разделе содержатся следующие подразделы:

  • Сценарии

  • Функциональные возможности

  • Базовые сведения

  • Примеры кода

  • Ссылка на классы

Сценарии

Существует возможность расширять существующие приложения ASP.NET и разрабатывать новые, используя технологию AJAX (Asynchronous JavaScript and XML — асинхронные JavaScript и XML). Применение технологии AJAX позволяет реализовать следующие возможности:

  • улучшение пользовательского интерфейса веб-страниц — он обогащается, быстрее реагирует на действия пользователя и становится более похожим на интерфейс традиционных клиентских приложений;

  • сокращение количества операций полного обновления страницы и устранение мерцания страницы;

  • обеспечение совместимости с различными обозревателями без написания клиентского сценария;

  • осуществление взаимодействия клиент-сервер по технологии AJAX без написания клиентского сценария;

  • использование элементов управления и компонентов из набора элементов управления AJAX для ASP.NET;

  • разработка пользовательских элементов управления AJAX ASP.NET.

Компоненты частичной отрисовки страниц

Частичная отрисовка страниц основан на использовании серверных элементов управления ASP.NET и клиентских функций из Microsoft AJAX (библиотека). Для обеспечения частичной отрисовки нет необходимости использовать Microsoft AJAX (библиотека), поскольку при использовании серверных элементов управления ASP.NET AJAX данная функциональность реализуется автоматически. Однако можно использовать API клиентской библиотеки для реализации дополнительной функциональности, которую поддерживает AJAX.

Важнейшими компонентами ASP.NET, обеспечивающими поддержку частичной отрисовки страниц, являются следующие.

  • Декларативная модель, которая действует подобно серверным элементам управления ASP.NET. Во многих случаях можно организовать частичную отрисовку, используя только декларативную разметку.

  • Серверные элементы управления, выполняющие базовые задачи, необходимые для частичного обновления страниц. К ним относятся элементы управления ScriptManager и UpdatePanel.

  • Интеграция серверных элементов управления ASP.NET AJAX с Microsoft AJAX (библиотека) для выполнения общих задач. В частности, речь идет о предоставлении пользователям возможности отменять обратную передачу, отображении пользовательских сообщений о ходе выполнения операции при асинхронной обратной передаче, а также об определении способа обработки асинхронных обратных передач.

  • Параметры обработки ошибок для частичной отрисовки страниц, позволяющие настраивать способ отображения сообщений об ошибках в обозревателе.

  • Совместимость с разными обозревателями, встроенная в AJAX-функциональность ASP.NET. Использование серверных элементов управления автоматически обеспечивает реализацию нужной функциональности в обозревателе.

Базовые сведения

Обычные веб-страницы, построенные с использованием серверных веб-элементов управления ASP.NET, выполняют обратную передачу в ответ на действие пользователя, например нажатие кнопки. В ответ сервер выполняет отрисовку новой страницы. При этом, как правило, осуществляется повторную отрисовку элементов управления и текста, которые не меняются между обратными передачами.

При частичной отрисовке страницы можно асинхронно обновлять отдельные области и тем самым сократить время ее отклика на действия пользователя. Можно реализовать частичную отрисовку страницы с использованием серверных веб-элементов управления ASP.NET AJAX, а при желании еще и написать клиентский сценарий с использованием API из Microsoft AJAX (библиотека).

Серверные элементы управления для частичного обновления страницы

Чтобы дополнить веб-страницу ASP.NET функциональностью AJAX, первым делом нужно идентифицировать те области страницы, которые нуждаются в обновлении. Затем содержимое этих областей следует поместить в элементы управления 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.

Асинхронная обратная передача происходит во многом подобно синхронной. Во время ее обработки происходят все события жизненного цикла страницы и сохраняются состояние представления и данные формы. Однако на этапе отрисовки обозревателю отправляется только содержимое элемента управления 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 для реализации частичной отрисовки страницы см. в параграфах, перечисленных в разделе Примеры кода.

Использование клиентского сценария для частичного обновления страницы

Класс PageRequestManager ECMAScript (JavaScript) в Microsoft AJAX (библиотека) поддерживает частичное обновление страницы. Он выполняется в обозревателе, где обрабатывает ответ на асинхронную обратную передачу и обновляет содержимое отдельных областей страницы. Для поддержки этой функциональности ничего делать не требуется. Она реализуется автоматически при добавлении на страницу одного или более элементов управления 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 (библиотека) для частичной отрисовки страниц см. в разделах Работа с событиями класса PageRequestManager и Общие сведения о классе PageRequestManager ASP.NET.

Включение поддержки частичной отрисовки страниц

Включение и отключение частичной отрисовки страниц выполняется путем установки свойства EnablePartialRendering элемента управления ScriptManager. Кроме того, с помощью свойства SupportsPartialRendering элемента управления ScriptManager можно указать, поддерживается ли для страницы частичная отрисовка. Если не задать свойство SupportsPartialRendering, а в свойстве EnablePartialRendering оставить значение по умолчанию true, поддержка частичной отрисовки страниц будет определяться на основе возможностей обозревателя.

Если для страницы частичная отрисовка не включена, отключен либо он не поддерживается обозревателем, задействуется альтернативное поведение страницы. В ответ на действия, которые обычно приводят к асинхронной обратной передаче, выполняется синхронная обратная передача и обновление всей страницы. Имеющиеся в составе страницы элементы управления UpdatePanel игнорируются, а их содержимое обрабатывается так, как если бы оно не находилось внутри элемента управления UpdatePanel.

Bb386573.alert_note(ru-ru,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

Управляет компонентами AJAX в ASP.NET, частичной отрисовкой, клиентскими запросами и серверными ответами на веб-страницах ASP.NET.

ScriptManagerProxy

Позволяет вложенным компонентам добавлять сценарии и ссылки на службы в состав страниц, которые уже содержат элемент управления ScriptManager в родительском элементе.

В следующей таблице перечислены ключевые клиентские классы, используемые для частичной отрисовки.

Класс

Описание

Класс Sys.WebForms.PageRequestManager

Управляет частичной отрисовкой страницы клиента и предоставляет члены для создания пользовательских клиентских сценариев.

См. также

Основные понятия

Общие сведения об элементе управления UpdatePanel

Общие сведения о классе PageRequestManager ASP.NET