Донецкий техникум промышленной автоматики

AJAX способи виклику ASP.NET C # методу серверного контрола управління з .js скрипта клієнтської сторони з передачею параметрів

сайт https://anteh.ru

1. [System.Web.Services.WebMethod]

2. Інтерфейс IHttpHandler

3. Інтерфейс System.Web.UI.IcallbackEventHandler

4. Інтерфейс System.Web.UI.IcallbackEventHandler для контрола успадкованого від GridView

Знайшовся тільки один спосіб обміну даними між клієнтською стороною (web сторінкою) і контролом розташованим на серверній стороні сторінки. Тобто обмін даними здійснюється не зі сторінкою, а з серверним контролом, розташованому на сторінці.
Під контролом тут мається на увазі серверний елемент управління.

Наведено 3 випадки виклику методів серверної сторони:
1. [System.Web.Services.WebMethod] -виклик методів серверної сторони з клієнтської сторінки. Простий в реалізації. Через POST можна передати будь-які дані в будь-якому обсязі.
2.IHttpHandler -виклик методів серверної сторони з клієнтської сторінки. Працює швидше 1го методу. Через POST дозволяє передавати будь-які дані в будь-якому обсязі.
3.IcallbackEventHandler дозволяє здійснювати обмін даних не тільки між клієнтської і серверної сторонами сторінки, але і між клієнтської стороною і контролом серверної сторони, розміщеному на сторінці. Використовується XmlHTTP. За неперевіреними даними дозволяє передавати тільки текстову інформацію, але тут так би мовити було б бажання.
Є й інші способи реалізації ajax обміну даними між сторінкою та сервером. TestICBEH.rar -архів проекту прикладу для IcallbackEventHandler.

Розглянемо передачу даних .js скриптом клієнтської сторінки в серверне уявлення сторінки: 2способа. І в серверний контрол управління, розміщений на сторінці: 1способ. Головна задумка в тому, щоб дані передавати в сам серверний контрол управління, розміщений на серверній стороні сторінки, а не на серверне уявлення сторінки. Сторінка створена в VS2008 як web додаток, створене два проекти серверних контролів управління, кілька контролів розміщено на сторінці. Дані зі сторінки на сервер і назад передаються по кліку на кожен з елементів управління.

Розглянемо передачу даних на серверне уявлення сторінки, що містить контрол. Розглянуто 2 способи: через [System.Web.Services.WebMethod] і інтерфейс IHttpHandler. Зрозуміло є й інші. Якщо коротко, то через IHttpHandler швидше, через [WebMethod] простіше, але в сам контрол цими методами дані передати не вийде. У контрол можна передати дані через реалізацію інтерфейсу ICallbackEven tHandler.
Посилання на джерело з прикладами і описом ICallbackEventHandler webform_docallback: http://www.intuit.ru/department/se/aspdotnet/18/4.html

[System.Web.Services.WebMethod]


1.На сторінці повинен бути присутнім ScriptManager. У поточному випадку це ToolkitScriptManager. В його властивості параметр EnablePageMethods потрібно встановити в true. Цим дозволяється виклик методів сторінки розташованих на серверній стороні, помічених атрибутом [WebMethod]. У reference потрібно додати System.Web.Services і відповідно using System.Web.Services; або використовувати [System.Web.Services.WebMethod]. На скріншоті частина візуального редактора.

Пробував працездатність без установки EnablePageMethods -Працює.
2. Код .cs. Створюємо на серверній стороні статичний метод розташований в класі, що описує сторінку, в поточному випадку містить контрол / ли. Метод повинен бути статичним. Метод помічаємо атрибутом [System.Web.Services.WebMethod]:

... public partial class WebForm2: System.Web.UI.Page // сторінка містить контроли {[System.Web.Services.WebMethod] public static string GetSome (string param1, string param2) // приймає, обробляє і відправляє назад дані метод { return "S =" + param1 + "" + param2 + "= S"; } ...


3.Код .js файл:

... кнопка.click (function () // {$ .ajax ({// Передаємо введені дані на сервер і отримуємо відповідь type: "POST", url: window.location.href + '/ GetSome', // url: адреса поточної сторінки / ім'я статичного методу на стороні сервера data: "{ 'param1': 'Fp1', 'param2': 'Sp2'}", contentType: "application / json; charset = utf-8", dataType: "json" , async: true, cache: false, success: function (data, textStatus, XHR) {alert ( 'stat:' + textStatus + 'd:' + data.d + 'xhr:' + XHR);}}); return false;}); ...


Результат, після натискання клієнтської кнопки наступний:

Передали дані на серверну сторону, дані були оброблені, повернуті клієнтської сторінці і відображені в повідомленні. Все як і має бути.

інтерфейс IHttpHandler

Випадок обміну даними між DOM елементом сторінки і сервером за допомогою IHttpHandler POST. Дані серверного елемента управління (контрола) розташованого на сторінці, передаються на серверну сторону уявлення сторінки, яка містить контрол, а не в сам контрол.

1.Создаём файл .ashx -Додаємо до проекту Generic Handler. У поточному випадку, прямо в корінь проекту web-додатки.

2.Прінімаем POST запити, Парс в HashTable, формуємо і передаємо Вам відповідь. Файл * .ashx редагуванню не підлягає. У ньому знаходиться єдиний рядок: "<% @ WebHandler Language =" C # "CodeBehind =" HandlerEGV.ashx.cs "Class =" Monitor12.HandlerEGV "%>" Вміст * .ashx.cs файлу:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Script.Serialization; using System.Collections; namespace Monitor12 {public class DataInOut {public int Id {get; set; } Public string Data1 {get; set; } Public string Data2 {get; set; }} Public class HandlerEGV: IHttpHandler {private DataInOut GetData (int Id) // Id-тут це деякий умовний параметр, за яким визначаємо характер відповіді. У поточному випадку, звичайно ніякої фактичної обробки не проводиться, а довільно придумані рядки відразу відправляються як відповідь на сторінку клієнта {var datainout = new DataInOut (); datainout.Id = Id; // Прийнята від DOM елемента інформація через $ .ajax ({...}); // Деякі дії з прийнятими даними і формування відповідних полів даних datainout.Data1 = "Dat_aa"; // Сформована у відповідь інформація datainout.Data2 = "Dat_bb"; // Сформована у відповідь інформація return datainout; } Public void ProcessRequest (HttpContext context) {System.IO.StreamReader reader = new System.IO.StreamReader (context.Request.InputStream); string requestFromPost = reader.ReadToEnd (); // Зараз requestFromPost = "Id = 10009 & tst = ttss & empty =" // Нехай здійснюється обмін тільки текстовими даними // Створюємо HashTable, де ключ = json прийшов ключ, data = json прийшли дані. Якщо ключі дублюються, то така пара ігнорується char [] c1 = new char [] { '&'}; char [] c2 = new char [] { '='}; Hashtable ht = new Hashtable (); string [] buf = null; string [] parms = requestFromPost.Split (c1, StringSplitOptions.RemoveEmptyEntries); foreach (string s in parms) {buf = s.Split (c2); if (buf.Length <2) {continue; } If (! Ht.ContainsKey (buf [0])) ht.Add (buf [0], buf [1]); // Про всяк, значення з повторюваними ключами пропускаємо. Перевіряв, пари, з повторюваними ключами через POST не передаються: //.js файл $ .ajax ({}); запит: data: { 'Id': '10009', 'tst': 'ttss', 'empty': '', 'tst': 'ttss', 'tst2': 'ttss'}, // Дані, що передаються на серверну сторону // на сервері взяли: "Id = 10009 & tst = ttss & empty = & tst2 = ttss" Тобто повторна пару 'tst': 'ttss' була десь отфильтрованием} // GetData -функція, в якій обробляється прийнятий запит і формується відповідь було надіслане, для відправки на сторінку DataInOut dio = GetData (Convert.ToInt32 ((ht [ "Id" ]). ToString ())); // Обробляємо прийняті дані і формуємо відповідь було надіслане JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer (); string serdio = javaScriptSerializer.Serialize (dio); context.Response.ContentType = "text / html"; context.Response.Write (serdio); // serdio так виглядає відповідь було надіслане від сервера, що передається назад на сторінку, яка зробила запит // { "Id": 10009, "Data1": "Dat aa", "Data2": "Dat bb"}} // якщо IsReusable = true, то об'єкт хенделра буде повторно використовуватися на випадок повторних запитів. Заново, при кожному запиті створюватися не буде. public bool IsReusable {get {return true; }} // MSDN: Повертає значення, що дозволяє визначити, чи може інший запит використовувати екземпляр класу}}

3.Код .js файл. При натисканні на кнопку виробляється передача даних на сервер, обробка і подальший прийом, з висновком повідомлення.

кнопка.click (function () // {$ .ajax ({type: "POST", cache: false, // параметр заборони кешування потрібно встановити async: true, url: "HandlerEGV.ashx", // Handler (папка) /MyHandler.ashx(файл) contentType: "application / json; charset = utf-8", dataType: "json", data: { 'Id': '10009', 'tst': 'ttss', 'empty': '', 'tst': 'ttss', 'tst2': 'ttss'}, // Дані, що передаються на серверну сторону responseType: "json", success: function (data, textStatus, XHR) // {// Відображаємо прийняті дані alert ( 'status:' + textStatus + '/ Data1:' + data.Data1 + 'Data2:' + data.Data2 + '/ xhr:' + XHR);}, error: function () // {alert ( "Status Error");}}); return false;});

Вам відповідь на запит з сервера, після натискання кнопки:

інтерфейс System.Web.UI.IcallbackEventHandler

Передача даних з клієнтської сторінки на серверну сторону і назад сел редством реалізації інтерфейсу IcallbackEventHandler для створюваного контрола.

TestICBEH.rar -архів проекту прикладу для IcallbackEventHandler.

Скріншот тестового прикладу для інтерфейсу IcallbackEventHandler. Містить 3 статично разм ещённих, через візуальний редактор, кнопки-розширених серверних контролів, серверний контрол успадкований від GridView і 2 динамічно створені через jQuery кнопки. Клік по кожному з елементів призводить до передачі даних на сервер, обробку, повернення результату назад на сторінку і відображення в діалоговому вікні.


Потрібно здійснити наступне: розробляємо серверний контрол управління. Є кілька однакових контролери розміщених на сторінці. Нехай контролом буде кнопка, функціональність якої розширюємо. Кнопка динамічно створювана в контролі. Потрібно, щоб після натискання на динамічно створену кнопку контрола на сервер передавалися деякі дані, оброблялися, і поверталися назад в клієнтське уявлення контрола.
Розглянемо послідовність дій.
Нехай інтерфейс IScriptControl і все, що до нього покладається вже реалізовано. Підключаємо інтерфейс IcallbackEventHandler. public class tbutt: Button, IScriptControl, ICallbackEventHandler
1.При завантаженні сторінки, в методі onload контрола на серверній стороні, через Page.ClientScript.GetCallbackEventReference формується WebForm_DoCallback прототип функції, вміст в cbReference. Далі в ручну створюємо скрипт cbScript. Він описує функцію UseCallback, що викликає WebForm_DoCallback для здійснення зворотної передачі. Далі реєструється програмно створений скрипт UseCallback функції.

protected override void OnLoad (EventArgs e) {this.Attributes.Add ( "onclick", "return false"); // Відключаємо штатний PostBack у поточного контрола-кнопки this.Attributes.Add ( "a6sSm1z", ""); // Унікальний ідентифікатор, присвоєний поточного контролю. Для виділення в .js всіх таких же контролів, які перебувають на сторінці // Cоздаём функцію, яка буде керувати запитами і відповідями на стороні клієнта string cbReference = Page.ClientScript.GetCallbackEventReference (this, "arg", "ProcessResult", "context") ; // ProcessResult -функція зареєстрована в якості одержувача результату на стороні клієнта .js скрипт string cbScript = "function UseCallback (arg, context)" + "{" + cbReference + ";" + "}"; // UseCallback -функція ініціює процес зворотної передачі на сервер даних. Запускається з .js скрипта, наприклад після натискання кнопки Page.ClientScript.RegisterClientScriptBlock (this.GetType (), "UseCallback", cbScript, true); // реєструємо скрипт UseCallback щойно створеної функції base.OnLoad (e); }

2.Реалізуем 2 функції інтерфейсу IcallbackEventHandler:

string returnstring = string.Empty; string ICallbackEventHandler.GetCallbackResult () // повертає результат клієнтського скрипту, в даному випадку {return returnstring; } Void ICallbackEventHandler.RaiseCallbackEvent (string eventArgument) // дозволяє отримати зі сторінки дані, але тільки строкового типу {// Що-небудь робимо з прийнятими параметрами returnstring = eventArgument + "Clock:" + DateTime.Now.ToString (); }

3.В .js файл додаємо наступне:

/// <reference path = "jquery-1.9.0-vsdoc.js" /> function ProcessResult (result, context) // Функція приймає відповідне повідомлення від сервера {alert ( 'ServerAnswer:' + result); } $ (Document) .ready (function () // {// Всім існуючим на сторінці контроль-кнопках призначаємо додаткову функціональність // Кожному елементу-контроль, з атрибутом a6sSm1z призначаємо деякі властивості $ (this) .find ( 'input [a6sSm1z ] '). each (function () // a6sSm1z -унікальний атрибут, в поточному разі присвоєний кожній кнопці-контроль. Присвоєння проводиться в onload. {$ (this) .click (function () // this -в цій області видимості це розробляється контрол {$ ( '#' + this.id) .css ({ 'background-color': 'red'}); // Під час натискання кнопка підсвічується червоним UseCallback ( 'StaticButton id =' + this.id + ' ',' Ucontext '); // Функція, яка ініціює зворотний в изов}); // alert ( 'id:' + this.id);}); // Створюємо динамічну кнопку var inbtn = $ (document.createElement ( "input")). attr ({name: 'inputIMEIbutton', value: 'dynamic jQuery button', type: 'button'}); inbtn.click (function () // {// alert ( "dynamic jQuery button"); UseCallback ( 'DynamicButton id =' + this.id + ' ',' Ucontext '); // Функція, яка ініціює зворотний виклик}); $ (Document.body) .after (inbtn); // Додаємо динамічно створену кнопку на сторінку, в кінець});

Тут: сама верхня рядок -для роботи jQuery intellisence. ProcessResult -функція прінімающаяя відповідь було надіслане від сервера як результат кліка по кнопці. UseCallback -та сама функція, яка формується програмно в 1. Функція приймає 2 аргументу перший передається на сервер містить всі потрібні агрумент, розділені наприклад '&' для подальшого розбору на серверній стороні. Тут поділ не використовувалося. Другий аргумент в поточному випадку просто присутній і ніде не обробляється.
Загалом процес виглядає так: при натисканні на кнопку запускається функція UseCallback, .js скрипт, що містить першим аргументом передаються на сервер дані. Функція контрола-кнопки RaiseCallbackEvent на серверній стороні, приймає дані. Потім додає поточний системний час до прийнятого аргументу. Потім автоматично запускається GetCallbackResult передає результат клієнтського поданням контрола в .js скрипт-функцію ProcessResult. Функція ProcessResult виводить результат на екран, у вигляді повідомлення з веб-сторінки. У проекті реалізовані 5 кнопок 3 статичних, створених в візуальному редакторі і 2 динамічна, створювана динамічно через jQuery.
Реалізація поточного проекту VS2008 Framework 3.5.
Скріншоти кліків по статичної та динамічної кнопок:

Інтерфейс System.Web.UI.IcallbackEventHandler для контрола успадкованого від GridView

Загалом припускав, будуть нюанси при реалізації IcallbackEventHandler для GridView. Нюансів не було, все так же, хіба довелося реалізовувати ObjectDataSource для GridView -Взяти шматок коду з іншого проекту. Проект в прикріпленому файлі.
Скріншот кліка по таблиці: