Глава 10. Использование механизма обратных вызовов в ASP.Net 2.0
Новым в ASP.NET 2.0 является использование клиентского диспетчера обратных вызовов. Это позволяет выполнить частичное обновление страницы (в ASP.NET 1 для любого обновления требовался повторный вызов формы). Обратные вызовы асинхронны и выполняются с использованием XML-HTTP (браузер должен поддерживать протокол XML-HTTP - Internet Explorer версии 5.0 или выше). Суть выполнения обратных вызовов заключается в том, что на серверной стороне, до события PreRender, страница обрабатывается как обычно, затем обработка прекращается, и страница клиенту не возвращаются. Вместо возврата страницы, клиет получает строковую переменную. Обработку строковой переменной выполняет скрипт, имя которого становится известным на серверной стороне. Обработчик события обратного вызова на серверной стороне, также принимает от клиента некоторую информацию и, таким образом, выполняется взаимообмен информацией между клиентом и сервером без повторного вызова страниц. Кроме того, серверу от клиента могут быть переданы две строковые переменные, одна из которых context. С помощью context можно, например, определять, какой из нескольких контролов, использующих одну и ту же callback-функциональность, вызвал callback. Таким образом, для реализации механизма обновления данных без перезагрузки страницы необходимо создать функцию реализации обратного вызова на стороне клиента, принимающую переданные с сервера параметры, серверную функцию, принимающую параметры от клиента и возвращающую клиенту значения на основании полученных параметров и связать эти две функции. Для этого интерфейс ICallbackEventHandler имеет два метода: RaiseCallbackEvent, для получения параметров на сервере и GetCallbackResult для возвращения результата клиенту. Возможные способы использования обратных вызовов зависят только от методов связывания функций клиента и сервера. Причем, все они связаны с вызовом встроенной функции JavaScript интерфейса ICallbackEventHandler - WebForm_DoCallback. Функция WebForm_DoCallback имеет следующие аргументы: WebForm_DoCallback( pageID, //ID страницы, выполняющей вызов argumrnt, //строка, передаваемая серверу returnCollback, //код JavaScript, инициализируемый до завершения //обратного вызова context, //данные, передаваемые вызову ReturnCallback errorCalback); //код JavaScript, инициализируемый при сбоях Рассмотрим некоторые возможные способы организации обратных вызовов: Параграф 1. Использование прямого вызова функции WebForm_DoCallbackСоздадим новый проект и помести на форму два контрола button (не серверный) и Label(Серверный). И напишем JavaScripp с двумя методами - запроса за информацией на сервер - GetServerInformation и получения информации - TikeInformation. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!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> <title>Пример 1</title> <script language="javascript"> function GetServerInformation() { var message = 'X'; var context = ''; //вызываем WebForm_DoCallback <%=sCallBack %> } function TikeInformation(infstring, context) { alert('Последовательность шагов после нажатия кнопки:\n' + infstring); } </script> </head> <body> <form id="MainForm" runat="server"> <asp:Label ID="Label1" runat="server" Text="При загрузки страницы"></asp:Label> <br> <input type="button" value="Последовательность шагов при обратном вызове:" onclick="GetServerInformation();" /> </form> </body> </html> Серверный код содержит страницу, реализующую интерфейс ICallbackEventHandler, и два метода: RaiseCallbackEvent и GetCallbackResult. Кроме того, при загрузке страницы подготавливается организация связи Сallback путем формирования кода для вызова функции WebForm_DoCallback. Вызов этой функции активизирует вызов методов RaiseCallbackEvent и GetCallbackResult и определяет связь GetCallbackResult с функцией TikeInformation скрипта, выполняемого на стороне клиента. Активизация связи выполнена на стороне клиента (обращение к строке sCallBack из HTML кода). using System; using System.Web.UI; public partial class _Default : Page, ICallbackEventHandler { public string sCallBack = string.Empty; public string sCallBack1 = string.Empty; void Page_Load(object sender, System.EventArgs e) { //Организуем связь Сallback со скриптом TikeInformation, но не активизируем //при первоначальной загрузке страницы. sCallBack будет иметь значение //WebForm_DoCallback('__Page',message,TikeInformation,context,null,false) sCallBack = Page.ClientScript.GetCallbackEventReference(this, "message", "TikeInformation", "context"); if(!IsPostBack) { //Просмотрим Label1.Text += "<br><br>Шаг 1: "+sCallBack+"<br>"; sCallBack1 += " 1 \n"; } else { Label1.Text +=""+sCallBack; sCallBack1 += " 2Page_Load()\n"; } } // Обработчик события обратного вызова на серверной стороне void ICallbackEventHandler.RaiseCallbackEvent(string e) { sCallBack1 += " 3 RaiseCallbackEvent и извлечение переданной информации, которая сейчас = " + e + "\n"; } //Выдача результата string ICallbackEventHandler.GetCallbackResult() { sCallBack1 += " 4 GetCallbackResult() Выдача результата"; return sCallBack1; } } Метод GetCallbackEventReference определен как: public string GetCallbackEventReference ( string target, //страница, вызова string argument, //строковая переменная, для передачи серверу string clientCallback, //код JavaScript, инициализируемый по завершении //и принимающий строковую переменную с серверавызова string context, //данные, передаваемые вызову ReturnCallback string clientErrorCallback //код JavaScript, инициализируемый при сбоях ) Результат работы кода показан на Рис.1.
Рис.1 Прямой вызов события WebForm_DoCallback Отображенная последовательность шагов, показывает, что метод Page_Load вызывается и при обратном вызове, но отображение результатов на странице клиента не выполняется (мы уже говорили, что до события PreRender, страница обрабатывается как обычно, затем обработка прекращается, и страница клиенту не возвращаются). Параграф 2. Использование вызова WebForm_DoCallback функцией скрипта, зарегистрированной на сервереВ данном примере рассматривается вызов все той же функции WebForm_DoCallback, но только через скрипт CallDataServer, который при загрузке страницы, регистрируется на сервере как клиентский скрипт. Создадим новый проект, и помести на форму два контрола select (не серверный) и Label(Серверный), и поле для вывода HTML кода span. И напишем JavaScripp с двумя методами - запроса за информацией на сервер - GetServerInformation и получения информации - TikeInformation. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <html> <head> <title>Пример 2</title> <script type="text/javascript"> function GetServerInformation() { var element = document.getElementById("Select1"); var opt = element.options[element.selectedIndex].text; //Вызываем зарегистрованный скрипт CallDataServer(opt,''); } function TikeInformation(infstring) { output.innerHTML = infstring; } </script> </head> <body> <form id="form1" runat="server"> <asp:Label ID="Label1" runat="server" Text="Label" ></asp:Label><br /> <br> <div> <select id="Select1"> <option value=1 selected="selected">Опция_ 1</option> <option value=2>Опция_ 2</option> </select> <br /> <br /> <input onclick="GetServerInformation()" value="Получить" type=button> <br /> <span ID="output"></span> <br /> </div> </form> </body> </html> Серверный код содержит страницу, реализующую интерфейс ICallbackEventHandler и два метода: RaiseCallbackEvent и GetCallbackResult. Кроме того, при загрузке страницы, организуем связь Сallback через регистрацию на стороне сервера функции CallDataServer клиенсткого скрипта. В данной функции выполняется обращение к функции WebForm_DoCallback. Вызов функции, в свою очередь, активизирует RaiseCallbackEvent и GetCallbackResult и определяет связь GetCallbackResult с функцией TikeInformation скрипта, выполняемого на стороне клиента. using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler { string sCallBack1 = string.Empty; protected void Page_Load(object sender, EventArgs e) { Label1.Text = ""; string callbackScript = string.Empty; if (!IsPostBack) { callbackScript = "function CallDataServer(message,context)" + "{ " + Page.ClientScript.GetCallbackEventReference(this, "message", "TikeInformation", "context") + "} ;"; Label1.Text += "<br>Шаг 1: " + callbackScript + "<br>"; //Label1.Text += "<br>Шаг 1: " + callbackScript + "<br>"; //Регистрируем клиентский скрипт на сервере Page.ClientScript.RegisterStartupScript(this.GetType(), "aaaaaa", callbackScript, true); sCallBack1 += "Шаг 1 \n"; } else { Label1.Text += "" + callbackScript; sCallBack1 += " Шаг 2 Page_Load()\n"; } } void ICallbackEventHandler.RaiseCallbackEvent(string e) { sCallBack1 += " Шаг 3 RaiseCallbackEvent() и получение информации клиента: <font color=red>"+e.ToString(); } //Выдача результата string ICallbackEventHandler.GetCallbackResult() { sCallBack1 += "</font> Шаг 4 GetCallbackResult() Выдача результата"; return sCallBack1; } } Результат работы кода показан на Рис.2.
Рис.2 Вызов функции WebForm_DoCallback через зарегистрированный на сервере скрипт Параграф 3. Вызов функции WebForm_DoCallback через переопределения событий серверного контролаДанный пример использует уже серверные элементы. Скрипт вызова функции WebForm_DoCallback непосредственно связывается с событием серверного элемента управления. Для того, чтобы серверные контролы не вызывали перегрузку страницы, после вызова функции добавлен код return false. В остальном, логика и последовательность шагов, соответствует вышеописанным примерам. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <script type="text/javascript"> function TikeInformation(infstring) { document.getElementById("div1").innerHTML = infstring; } function TikeInformation1(infstring) { document.getElementById("div2").innerHTML = infstring; } </script> <html> <head> <title>Пример 3</title> </head> <body> <form id="form1" runat="server"> <br> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> <br> <div> <select id="Select1"> <option selected="selected" value=1>Опция 1</option> <option value=2>Опция 2</option> </select> <asp:Button ID="Button1" runat="server" Text="Получить" /><br> <asp:TextBox ID="TextBox1" runat="server" Height="28px" Width="164px"></asp:TextBox> </div> <br> <div id="div1" ></div> <br> <div id="div2" ></div> </form> </body> </html> В серверном коде отличие лишь в связывании события WebForm_DoCallback с событием элемента управления. using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page,System.Web.UI.ICallbackEventHandler { string sCallBack1 = string.Empty; string sS= string.Empty; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { sS = Page.ClientScript.GetCallbackEventReference(this, "document.getElementById('Select1'). options[document.getElementById('Select1').selectedIndex].text", "TikeInformation", null); Label1.Text = sS; Button1.Attributes.Add("onclick", sS + ";return false;"); sS = Page.ClientScript.GetCallbackEventReference(this, "document.getElementById('TextBox1').value", "TikeInformation1", null); TextBox1.Attributes.Add("onkeyup", sS + ";return false;"); Label1.Text += " " + sS; } } void ICallbackEventHandler.RaiseCallbackEvent(string e) { sCallBack1 += e.ToString(); } //Выдача результата string ICallbackEventHandler.GetCallbackResult() { return sCallBack1; } } Результат работы кода показан на Рис.3.
Рис.3 Вызов функции WebForm_DoCallback через переопределения событий серверного контрола
Молчанов Владислав 17.3.2006г.
Еcли Вы пришли с поискового сервера - посетите мою главную страничкуНа главной странице Вы найдете программы комплекса Veles - для тех кто готовится
к экзаменам на право управления автомобилем или мотоциклом,
программу NumberPhoto, созданную для работы с фото, сделанными цифровым фотоаппаратом,
программу Bricks - игрушку для детей и взрослых, программу записную книжку,
теоретический материал по программированию в среде Borland C++ builder, C# (C .Net).
|