суббота, 31 октября 2009 г.

ASP.NET: Вызов метода страницы с помощью jQuery

В этом примере будет рассмотрено как можно вызывать метод ASP.net страницы используя библиотеку jQuery.
Добавляем на страницу следующий javascript код:
 $(function() {  
  $("#ZipCodeTextBox").bind('change', function(event) {  
   // If it doesn't look like a zip code, don't even bother with the request  
   if (/^\d{5}(-\d{4})?$/.test($(this).val()))  
    $.ajax({  
     type: "POST",  
     contentType: "application/json; charset=utf-8",  
     url: "Default.aspx/GetCityStateByZip",  
     data: "{'zip': '" + $(this).val() + "'}",  
     dataType: "json",  
     success: function(msg) {  
      $("#CityStateLabel").text(msg.d.City + ", " + msg.d.State);  
     }  
    });  
  });  
 });  

Для знакомых с jQuery этот код должен показаться довольно обычным. А новички могут быть удивлены насколько этот небольшой участок кода функционален.

Для начала добавляем обработчик события onchange к текстовому полю с id "#ZipCodeTextBox":

 $(function() {  
  $("#ZipCodeTextBox").bind('change', function(event) {  

Потом, jQuery ждет пока DOM страницы загрузится, поэтому мы можем быть уверенными, что textbox к которому мы хотим привязать событие будет найден. Используя супер-простую возможность jQuery в выборе элементов, мы передаем CSS-селектор #ZipCodeTextBox в функцию $(). Затем мы вызываем функцию bind() для textbox, передавая 'change' как тип события и вторым параметром саму функцию, которую мы хотим вызывать в ответ на вызов этого события. Эта функция принимает один параметр, event в данном примере, но это не будет использовано здесь.

Когда вызывается событие onchange нашего textbox, блок кода внутри функции bind выполнится. Сначала мы выполняем простую проверку значения textbox’a c помощью регулярного выражения. Для получения значения textbox, мы можем использовать $(this), который существенно расширяет наш textbox элемент, предоставляя доступ ко всем существующим возможностям jQuery. В этом случае, $(this).val()  это все что необходимо – val() возвращает значение хранящие элементы формы.

Наше регулярное выражение
/^\d{5}(-\d{4})?$/
используется для проверки, что значение текстового поля состоит из 5 цифр - \d{5} – за которыми может следовать дефис и еще 4 цифры  – (-\d{4})?. Очевидные примеры почтового индекса могут быть 01721-8582 или 95060. Если значение введенное в textbox не удовлетворяет этому формату, то вызов метода страницы не будет произведен.
Итого вся проверка такая:
/^\d{5}(-\d{4})?$/.test($(this).val())

Отсюда мы вызываем $.ajax(), другую jQuery функцию, которая создает AJAX запрос с заданными параметрами. ASP.NET требует чтобы наш запрос был выполнен методом POST (c GET не сработает) и с установленным content-type ‘application/json’. Url-параметр это просто имя нашей страницы содержащей PageMethod (Default.aspx в нашем примере) за которым следует прямой слеш '/‘ и имя метода нашей страницы в code-behind файле. Наш метод должен быть объявлен с аттрибутом WebMethod() для того чтобы успешно выполнить запрос:

 Imports System.Web.Services  
 ...  
 <WebMethod()> _  
 Public Shared Function GetCityStateByZip(zip As String) As CityState  
 ...  
 End Function  
Данные которые отправляются на страницу должны быть в JSON формате, который сводится к набору пар 'имя-значение’ заключенные в фигурные скобки. Так как наш PageMethod ожидает параметр 'zip’, мы строим наши данные по типу

{'zip':'95064'}

Затем мы устанавливаем datatype параметру запроса значение 'json'. Весь список AJAX параметров:
 type: "POST",  
 contentType: "application/json; charset=utf-8",  
 url: "Default.aspx/GetCityStateByZip",  
 data: "{'zip': '" + $(this).val() + "'}",  
 dataType: "json"  

Наконец, мы определяем success параметр нашего AJAX вызова, устанавливая его значение функцией параметр которой результат нашего запроса.
success: function(msg) {
  $("#CityStateLabel").text(msg.d.City + ", " + msg.d.State);
}


Мы можем производить любые манипуляции с данными  которые нам нужны тут, хотя некоторые будут спорить, что обработка данных должна быть помещена на серверной стороне. Я полагаю, что в действительности это зависит от конкретной задачи. Во всяком случае, мы собираемся проделать здесь несколько манипуляций с DOM, включая простое присваивание определенному asp:Label элементу значения города  и штата, которые возвращены нам из PageMethod. Опять, $() берет CSS селектор как параметр, возвращая нам элемент, который мы хотим модифицировать. И мы хотим только изменить текст метки, так что мы используем text() функцию, передавая ей значение, которое мы хотим установить.

Изначально, я ожидал что использование msg.City и msg.State подобно тому как оно работает в Microsoft AJAX вызове метода страницы. Было довольно запутанно до тех пор пока не проверил JSON возвращенный из PageMethod используя FireBug для Firefox (если у вас его нету, вы можете достать его здесь http://getfirebug.com/ ). Кажется, ASP.net обертывает весь JSON ответ и присваивает его к ключу с названием 'd'. Наш полученный JSON объект:
{'d': {'City': 'Santa Cruz', 'State': 'CA'}}

Так как наш JSON объект является параметром msg переданной в success функцию, то для того чтобы получить значения города мы должно просто включить d в наше выражение – msg.d.City.
На этом все! Нам удалось вызвать PageMethod с помощью jQuery.

Перевод статьи Brian Dobberteen (исходный код там же)