https://technet.microsoft.com/en-us/library/ms143221(v=sql.105).aspx |
Элементы управления и использование JavaScript
Callback и его отличие от Postback
Перед тем как рассмотреть примеры новой возможности обратного вызова, посмотрим на работу механизма возврата данных формы на сервер ( Postback ) типичной страницы ASP .NET.
Когда на странице инициируется событие отправки данных, запускается большой и сложный механизм.
- Init
- Load State
- Process Postback Data
- Load
- Postback Events
- Save State
- PreRender
- Render
- Unload
В обычной ситуации постбэка событие на странице, например, щелчок на кнопке формы, вызывает отправку запроса HTTP POST web-серверу. Сервер обрабатывает запрос обработчиком IPostbackEvent Handler и запускает весь жизненный цикл страницы заново. Она загружает состояние страницы, обрабатывает введенные данные, обрабатывает события отправки, сохраняет состояние страницы, генерирует страницу заново и отправляет ее браузеру клиента. Страница полностью перезагружается, это занимает время и использует дополнительный трафик.
В этом случае событие (например, нажатие на кнопку) вызывает выполнение скрипта-обработчика у клиента (функция JavaScript), который посылает асинхронный запрос web-серверу.
На сервере обработчик ICallbackEventHandler пропускает запрос через процесс, похожий на тот, который используется при постбэке, но некоторые крупные этапы этого процесса (например, отрисовка страницы) пропускаются. После того как информация загружена, результат возвращается к объекту, вызвавшему обратный вызов. Код скрипта вставляет эти данные в web-страницу, используя возможности JavaScript делать это без обновления страницы. Количество фаз жизненного цикла сокращается до 6:
- Init
- Load State
- Process Postback Data
- Load
- CallBack Event
- 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) { }