Спонсор: Microsoft
Опубликован: 14.11.2006 | Доступ: свободный | Студентов: 5820 / 513 | Оценка: 4.18 / 3.74 | Длительность: 16:37:00
ISBN: 978-5-9556-0085-7
Лекция 18:

Элементы управления и использование JavaScript

< Лекция 17 || Лекция 18: 12345

Callback и его отличие от Postback

Перед тем как рассмотреть примеры новой возможности обратного вызова, посмотрим на работу механизма возврата данных формы на сервер ( Postback ) типичной страницы ASP .NET.

Когда на странице инициируется событие отправки данных, запускается большой и сложный механизм.

  1. Init
  2. Load State
  3. Process Postback Data
  4. Load
  5. Postback Events
  6. Save State
  7. PreRender
  8. Render
  9. Unload

В обычной ситуации постбэка событие на странице, например, щелчок на кнопке формы, вызывает отправку запроса HTTP POST web-серверу. Сервер обрабатывает запрос обработчиком IPostbackEvent Handler и запускает весь жизненный цикл страницы заново. Она загружает состояние страницы, обрабатывает введенные данные, обрабатывает события отправки, сохраняет состояние страницы, генерирует страницу заново и отправляет ее браузеру клиента. Страница полностью перезагружается, это занимает время и использует дополнительный трафик.

В этом случае событие (например, нажатие на кнопку) вызывает выполнение скрипта-обработчика у клиента (функция JavaScript), который посылает асинхронный запрос web-серверу.

На сервере обработчик ICallbackEventHandler пропускает запрос через процесс, похожий на тот, который используется при постбэке, но некоторые крупные этапы этого процесса (например, отрисовка страницы) пропускаются. После того как информация загружена, результат возвращается к объекту, вызвавшему обратный вызов. Код скрипта вставляет эти данные в web-страницу, используя возможности JavaScript делать это без обновления страницы. Количество фаз жизненного цикла сокращается до 6:

  1. Init
  2. Load State
  3. Process Postback Data
  4. Load
  5. CallBack Event
  6. Unload

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

Простой пример использования Callback

Посмотрим на простую страницу ASP .NET, которая использует эту возможность. В этом примере на странице есть кнопка HTML и серверный элемент управления TextBox.

Идея примера в том, что когда пользователь щелкает на кнопке на форме, запускается служба обратного вызова и в текстовое поле записывается случайное число:

<%@ Page Language="C#" AutoEventWireup="true" 
CodeFile="SimpleCallback.aspx.cs" Inherits="SimpleCallback" %>

<!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>Callback Page</title>

  <script type="text/javascript">
    function GetNumber(){
      UseCallback();
    }
    function GetRandomNumberFromServer(TextBox1, context){
      document.forms[0].TextBox1.value = TextBox1;
    }
  </script>

</head>
<body>
  <form id="form1" runat="server">
    <div>
      <input id="Button1" type="button" value="Случайное число" 
onclick="GetNumber()" />
      <br />
      <br />
      <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </div>
  </form>
</body>
</html>

Суть происходящего в том, что страница посылает асинхронный запрос функции класса страницы. Получив ответ от этой функции, клиентский скрипт помещает полученное значение в строку ввода, не обновляя при этом страницы.

Запускает весь процесс функция JavaScript GetNumber — обработчик щелчка на кнопке.

Функция GetRandomNumberFromServer() находится на обратном конце процесса и записывает результат обратного вызова в Textbox1.

Класс этой страницы не только наследуется от Page, но и реализует интерфейс System.Web.UI.ICallbackEventHandler:

public partial class SimpleCallback : System.Web.UI.Page,
System.Web.UI.ICallbackEventHandler
{
  private string _callbackResult = null;
  protected void Page_Load(object sender, EventArgs e)
  {
    string cbReference = 
Page.ClientScript.GetCallbackEventReference(this,
    "arg", "GetRandomNumberFromServer", "context");
    string cbScript = "function UseCallback(arg, context)" +
    "{" + cbReference + ";" + "}";
    Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
    "UseCallback", cbScript, true);
  }
  public void RaiseCallbackEvent(string eventArg)
  {
    Random rnd = new Random();
    _callbackResult = rnd.Next().ToString();
  }
  public string GetCallbackResult()
  {
    return _callbackResult;
  }
}

В этом интерфейсе определены 2 метода, которые необходимо реализовать, — RaiseCallbackEvent и GetCallbackResult, оба работают с запросами клиентских скриптов.

RaiseCallbackEvent позволяет получить со страницы данные, правда, только строкового типа. GetCallbackResult возвращает результат клиентскому скрипту, в данном случае GetRandomNumberFromServer — именно она зарегистрирована в качестве получателя результата.

Обработчик Page_Load включает создание функции, которая будет управлять запросами и ответами на стороне клиента.

Функция, которая ставится на клиенте для возможности обратного вызова, называeтся UseCallback(). Эта строка затем помещается на web-страницу, используя функцию Page.ClientScript.RegisterClientScriptBlock. Убедитесь, что имя, которое вы применяете здесь, такое же, как и в клиентской функции JavaScript:

<script type="text/javascript">
<!--
function UseCallback(arg, context)
{
WebForm_DoCallback('__Page',arg,GetRandomNumberFromServer,con-
text,null,false);
}
// -->
</script>

В результате получается страница, которая при нажатии на кнопку обновляет содержание текстовой строки, но не отрисовывает всю страницу. Есть лишь одно ограничение — здесь используется XmlHTTP и поэтому клиентский браузер должен его поддерживать (Internet Explorer 6.0, Mozilla FireFox 1.5 и Opera 9.0 поддерживают). Так это или нет, можно узнать с помощью свойств SupportsCallBack и SupportsXmlHTTP:

if (Page.Request.Browser.SupportsXmlHTTP == true) 
{
}
< Лекция 17 || Лекция 18: 12345
Алексей Савельев
Алексей Савельев

https://technet.microsoft.com/en-us/library/ms143221(v=sql.105).aspx

Денис Прокофьев
Денис Прокофьев

Везде написано, что это самый независимый и простой в использовании навигационный элемент управления, что он работает сразу с web.sitemap и не требует определения SiteMapDataSource.

Моя карта сайта состоит из двух страниц, вложенных друг в друга. asp:Menu, asp:TreeView отбображаются как ожидалось, а вот asp:SiteMapPath - нет. Он не виден нигде. Однако на его месте формируется разметка: <span id="SiteMapPath1"><a href="#SiteMapPath1_SkipLink" style="position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden;">Проход по ссылкам навигации</a><a id="SiteMapPath1_SkipLink"></a></span> - т.е. элемент отрабатывает.

В словах xHTML это выглядит так: <asp:SiteMapPath ID="SiteMapPath1" runat="server" />. Причем не важно - внутри тега form или снаружи - всегда одинаково.

Т.к. другие нав. ЭУ работают через простой источник данных без ошибок, делаю вывод - карта составлена правильно. ИД: <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />

Карта: <?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode url="~/L11_1_simplePage.aspx" title="Страница 1"  description="Простая страница 1." >
    <siteMapNode url="~/L11_1SimplePage2.aspx" title="Страница 2"  description="Простая страница 2" />
  </siteMapNode>
</siteMap>

Почему так происходит? Вроде делаю все по примерам. VS Community 2015. NetFramework в проекте: v4.0.30319

Александр Шнайдман
Александр Шнайдман
Израиль, Тель Авив