<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1828187461577424428</id><updated>2011-11-28T01:31:19.295+02:00</updated><category term='jquery'/><category term='asp.net'/><category term='ajax'/><title type='text'>nolled</title><subtitle type='html'>блог о программировании</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nolled.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nolled.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Volodymyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1828187461577424428.post-2535039886218585074</id><published>2009-11-05T16:31:00.001+02:00</published><updated>2009-11-08T22:10:13.227+02:00</updated><title type='text'>RouteHandler для IHttpHandler</title><content type='html'>Сегодня я увидел ошибку в &lt;a href=" https://connect.microsoft.com/VisualStudio/fefeedba/ViewFeedback.aspx?FeedbackID=505071&amp;wa=wsignin1.0"&gt;Connect&lt;/a&gt; в которой некто предлагает PageRouteHandler’у (новинка в ASP.NET 4) обрабатывать IHttpHandler так же как и Page. Вообще, я не согласен с этим предложением, потому что Page является IHttpHandler, а не наоборот. Что если человек действительно хочет новый обработчик? Дадим ему такое языковыворачивающее название IHttpHandlerRouteHandler.&lt;br /&gt;К сожалению, уже совсем поздно добавлять такое в ASP.NET 4, но оно оказывается тривиально простым для написания. По сути вот оно:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public class HttpHandlerRouteHandler&amp;lt;THandler&amp;gt;   &lt;br /&gt;   : IRouteHandler where THandler : IHttpHandler, new()   &lt;br /&gt; {  &lt;br /&gt;      public IHttpHandler GetHttpHandler(RequestContext requestContext)   &lt;br /&gt;      {  &lt;br /&gt;        return new THandler();  &lt;br /&gt;      }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Конечно, оно само по себе не особо полезно. Нам нужен метод-расширитель (“extension method”) для того чтобы действительно было просто регистрировать маршруты для HttpHandler’ов.Я написал целый ряд их, но только два примера тут в моем блоге. Остальные вы можете получить скачав проект внизу этого поста.&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public static class HttpHandlerExtensions   &lt;br /&gt; {  &lt;br /&gt;      public static void MapHttpHandler&amp;lt;THandler&amp;gt;(this RouteCollection routes, string url) where THandler : IHttpHandler, new()   &lt;br /&gt;      {  &lt;br /&gt;           routes.MapHttpHandler&amp;lt;THandler&amp;gt;(null, url, null, null);  &lt;br /&gt;      }  &lt;br /&gt;  //...  &lt;br /&gt;      public static void MapHttpHandler&amp;lt;THandler&amp;gt;(this RouteCollection routes, string name, string url, object defaults, object constraints) where THandler : IHttpHandler, new()   &lt;br /&gt;      {   &lt;br /&gt;           var route = new Route(url, new HttpHandlerRouteHandler&amp;lt;THandler&amp;gt;());  &lt;br /&gt;           route.Defaults = new RouteValueDictionary(defaults);  &lt;br /&gt;           route.Constraints = new RouteValueDictionary(constraints);  &lt;br /&gt;           routes.Add(name, route);  &lt;br /&gt;      }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Это дает нам очень простую возможность регистрировать маршрут, который обрабатывается IHttpHandler'ом. В этом случае, я регистрирую маршрут, использующий мой SimpleHttpHandler для обработки любого двухсегментного URL.&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public static void RegisterRoutes(RouteCollection routes)  &lt;br /&gt; {  &lt;br /&gt;      routes.MapHttpHandler&amp;lt;SampleHttpHandler&amp;gt;("{foo}/{bar}");  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;И здесь код SampleHttpHandler для завершения. Все что он делает, так это выводит значения маршрута.&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public class SampleHttpHandler : IHttpHandler   &lt;br /&gt; {  &lt;br /&gt;      public bool IsReusable   &lt;br /&gt;      {  &lt;br /&gt;           get { return false; }  &lt;br /&gt;      }  &lt;br /&gt;      public void ProcessRequest(HttpContext context)   &lt;br /&gt;      {  &lt;br /&gt;           var routeValues = context.Request.RequestContext.RouteData.Values;  &lt;br /&gt;           string message = "I saw foo='{0}' and bar='{1}'";  &lt;br /&gt;           message = string.Format(message, routeValues["foo"], routeValues["bar"]);  &lt;br /&gt;           context.Response.Write(message);  &lt;br /&gt;      }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Затем я делаю запрос для /testing/yo и вижу сообщение&lt;br /&gt;“I saw foo='testing' and bar='yo'”&lt;br /&gt;в моем браузере.&lt;br /&gt;Здесь одно ограничение – мой http handler должен иметь конструктор без параметров. Это впринципе неплохое ограничение, так как ранее регистрируя маршрут необходимо было вводить проверку, что обработчик имеет пустой конструктор.&lt;br /&gt;Вольный перевод статьи &lt;a href="http://haacked.com/archive/2009/11/04/routehandler-for-http-handlers.aspx"&gt;Phil Haack&lt;/a&gt; &lt;br /&gt;Там же пример для Visual Studio 2010.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1828187461577424428-2535039886218585074?l=nolled.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nolled.blogspot.com/feeds/2535039886218585074/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://nolled.blogspot.com/2009/11/routehandler-ihttphandler.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/2535039886218585074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/2535039886218585074'/><link rel='alternate' type='text/html' href='http://nolled.blogspot.com/2009/11/routehandler-ihttphandler.html' title='RouteHandler для IHttpHandler'/><author><name>Volodymyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1828187461577424428.post-6026953283841460721</id><published>2009-11-03T20:34:00.002+02:00</published><updated>2009-11-04T09:47:44.164+02:00</updated><title type='text'>Использование C# dynamic для упрощения  доступа к ADO.NET данным</title><content type='html'>Сценарий таков, что вы не используете какой-либо ORM такие как &lt;em&gt;LINQ to SQL&lt;/em&gt; или &lt;em&gt;Entity Framework&lt;/em&gt;, но вы напрямую используете &lt;em&gt;ADO.NET&lt;/em&gt; для выполнения  SQL-команд. Это вообще не принятый мною способ, но много народа предпочитает его более высокому уровня доступа к данным.&lt;br /&gt;Давайте посмотрим на пример, который мы собираемся улучшить. Возьмем пример из MSDN о SqlCommand:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; string commandText = "SELECT OrderID, CustomerID FROM dbo.Orders;";  &lt;br /&gt; using (var connection = new SqlConnection(Settings.Default.NorthwindConnectionString)) {  &lt;br /&gt;   using (var command = new SqlCommand(commandText, connection)) {  &lt;br /&gt;     connection.Open();  &lt;br /&gt;     using (SqlDataReader reader = command.ExecuteReader()) {  &lt;br /&gt;       while (reader.Read()) {  &lt;br /&gt;         Console.WriteLine(String.Format("{0}, {1}", reader[0], reader[1]));  &lt;br /&gt;       }  &lt;br /&gt;     }  &lt;br /&gt;   }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Давайте сейчас предположим, что мы мы заинтересованы только в одном select-запросе, который даст возможность нам несколько абстрагироваться от деталей в SQL. Написав несколько небольших хелперов, который используют dynamic, мы сможем написать довольно простой код:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; string commandText = "SELECT OrderID, CustomerID FROM dbo.Orders;";  &lt;br /&gt; foreach (var row in SimpleQuery.Execute(Settings.Default.NorthwindConnectionString, commandText)) {  &lt;br /&gt;   Console.WriteLine(String.Format("{0}, {1}", row.OrderID, row.CustomerID));  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Некоторые примечания:&lt;br /&gt;Нам достаточно сделать единственный вызов и прямо получить объекты с которыми мыможем работать. Сравните это с использованием SqlConnection, SqlCommand и SqlDataReader.&lt;br /&gt;Мы используем стандартный шаблон перечисления, в котором SqlDataReader делает вызов reader.Read() на каждой итерации, что выглядит ужасно.&lt;br /&gt;И еще одно важное: мы получаем прямой доступ к свойствам объекта строки благодаря динамическому объекту! Например мы можем написать row.OrderID вместо reader[0](или reader[“OrderID”])&lt;br /&gt;Как же это работает? Первое, давайте посмотрим на SimpleQuery.Execute метод:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public static IEnumerable&amp;lt;dynamic&amp;gt; Execute(string connString, string commandText) {  &lt;br /&gt;   using (var connection = new SqlConnection(connString)) {  &lt;br /&gt;     using (var command = new SqlCommand(commandText, connection)) {  &lt;br /&gt;       connection.Open();  &lt;br /&gt;       using (SqlDataReader reader = command.ExecuteReader()) {  &lt;br /&gt;         while (reader.Read()) {  &lt;br /&gt;           yield return new DataRecordDynamicWrapper(reader);  &lt;br /&gt;         }  &lt;br /&gt;       }  &lt;br /&gt;     }  &lt;br /&gt;   }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Это собственно тоже самое что и в MSDN коде за исключением что оно оборачивает возвращаемый reader в &lt;strong&gt;DataRecordDynamicWrapper&lt;/strong&gt;, который делает всю волшебную динамическую работу. Также заметьте что метод возвращает  &lt;strong&gt;IEnumerable&lt;dynamic&gt;&lt;/strong&gt; благодаря которому собственно мы и можем писать '&lt;em&gt;var row&lt;/em&gt;' в тестовом коде (который по-моему выглядит лучше чем '&lt;em&gt;dynamic row&lt;/em&gt;').&lt;br /&gt;Так что сейчас все что осталось так это взглянуть на &lt;strong&gt;DataRecordDynamicWrapper&lt;/strong&gt;, который невероятно прост:&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; public class DataRecordDynamicWrapper : DynamicObject {  &lt;br /&gt;   private IDataRecord _dataRecord;  &lt;br /&gt;   public DataRecordDynamicWrapper(IDataRecord dataRecord) { _dataRecord = dataRecord; }  &lt;br /&gt;   public override bool TryGetMember(GetMemberBinder binder, out object result) {  &lt;br /&gt;     result = _dataRecord[binder.Name];  &lt;br /&gt;     return result != null;  &lt;br /&gt;   }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Все что он делает, так это получает данные по индексу в&lt;strong&gt; _dataRecord&lt;/strong&gt; для заданного имени свойства.&lt;br /&gt;Единственная последняя вещь, которая ничего не стоит для того чтобы сделать реальной, мы должны добавить поддержку SQL параметров, которые дадут простоту написания SQL кода, не подверженного SQL-инъекциям. Это может быть просто сделано передавая параметры в SimpleQuery.Execute. &lt;br /&gt;Вольный перевод статьи &lt;a href="http://blogs.msdn.com/davidebb/archive/2009/10/29/using-c-dynamic-to-simplify-ado-net-use.aspx" title="David Ebbo"&gt;David Ebbo&lt;/a&gt; (Исходный код там же)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1828187461577424428-6026953283841460721?l=nolled.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nolled.blogspot.com/feeds/6026953283841460721/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://nolled.blogspot.com/2009/11/c-dynamic-adonet.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/6026953283841460721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/6026953283841460721'/><link rel='alternate' type='text/html' href='http://nolled.blogspot.com/2009/11/c-dynamic-adonet.html' title='Использование C# dynamic для упрощения  доступа к ADO.NET данным'/><author><name>Volodymyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1828187461577424428.post-8328483796926847210</id><published>2009-10-31T21:30:00.001+02:00</published><updated>2009-11-04T09:44:57.079+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='asp.net'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>ASP.NET: Вызов метода страницы с помощью jQuery</title><content type='html'>В этом примере будет рассмотрено как можно вызывать метод ASP.net страницы используя библиотеку jQuery.&lt;br /&gt;Добавляем на страницу следующий javascript код:&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; $(function() {  &lt;br /&gt;  $("#ZipCodeTextBox").bind('change', function(event) {  &lt;br /&gt;   // If it doesn't look like a zip code, don't even bother with the request  &lt;br /&gt;   if (/^\d{5}(-\d{4})?$/.test($(this).val()))  &lt;br /&gt;    $.ajax({  &lt;br /&gt;     type: "POST",  &lt;br /&gt;     contentType: "application/json; charset=utf-8",  &lt;br /&gt;     url: "Default.aspx/GetCityStateByZip",  &lt;br /&gt;     data: "{'zip': '" + $(this).val() + "'}",  &lt;br /&gt;     dataType: "json",  &lt;br /&gt;     success: function(msg) {  &lt;br /&gt;      $("#CityStateLabel").text(msg.d.City + ", " + msg.d.State);  &lt;br /&gt;     }  &lt;br /&gt;    });  &lt;br /&gt;  });  &lt;br /&gt; });  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Для знакомых с jQuery этот код должен показаться довольно обычным. А новички могут быть удивлены насколько этот небольшой участок кода функционален.&lt;br /&gt;&lt;br /&gt;Для начала добавляем обработчик события &lt;i&gt;onchange&lt;/i&gt; к текстовому полю с &lt;i&gt;id&lt;/i&gt; "&lt;i&gt;#ZipCodeTextBox&lt;/i&gt;":&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; $(function() {  &lt;br /&gt;  $("#ZipCodeTextBox").bind('change', function(event) {  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Потом, jQuery ждет пока DOM страницы загрузится, поэтому мы можем быть уверенными, что &lt;i&gt;textbox&lt;/i&gt; к которому мы хотим привязать событие будет найден. Используя супер-простую возможность jQuery в выборе элементов, мы передаем CSS-селектор &lt;i&gt;#ZipCodeTextBox&lt;/i&gt; в функцию&lt;b&gt; $()&lt;/b&gt;. Затем мы вызываем функцию &lt;i&gt;bind()&lt;/i&gt; для &lt;i&gt;textbox&lt;/i&gt;, передавая &lt;i&gt;'change'&lt;/i&gt; как тип события и вторым параметром саму функцию, которую мы хотим вызывать в ответ на вызов этого события. Эта функция принимает один параметр, event в данном примере, но это не будет использовано здесь.&lt;br /&gt;&lt;br /&gt;Когда вызывается событие &lt;i&gt;onchange&lt;/i&gt; нашего &lt;i&gt;textbox&lt;/i&gt;, блок кода внутри функции &lt;i&gt;bind&lt;/i&gt; выполнится. Сначала мы выполняем простую проверку значения &lt;i&gt;textbox&lt;/i&gt;’a c помощью регулярного выражения. Для получения значения &lt;i&gt;textbox&lt;/i&gt;, мы можем использовать &lt;b&gt;$(this)&lt;/b&gt;, который существенно расширяет наш &lt;i&gt;textbox&lt;/i&gt; элемент, предоставляя доступ ко всем существующим возможностям jQuery. В этом случае, &lt;b&gt;$(this).val()&lt;/b&gt;&amp;nbsp; это все что необходимо – &lt;b&gt;val()&lt;/b&gt; возвращает значение хранящие элементы формы.&lt;br /&gt;&lt;br /&gt;Наше регулярное выражение&lt;br /&gt;&lt;code&gt;/^\d{5}(-\d{4})?$/&lt;/code&gt;&lt;br /&gt;используется для проверки, что значение текстового поля состоит из 5 цифр - &lt;i&gt;\d{5}&lt;/i&gt; – за которыми может следовать дефис и еще 4 цифры&amp;nbsp; – &lt;i&gt;(-\d{4})?&lt;/i&gt;. Очевидные примеры почтового индекса могут быть 01721-8582 или 95060. Если значение введенное в&lt;i&gt; textbox&lt;/i&gt; не удовлетворяет этому формату, то вызов метода страницы не будет произведен.&lt;br /&gt;Итого вся проверка такая:&lt;br /&gt;&lt;code&gt;/^\d{5}(-\d{4})?$/.test($(this).val())&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Отсюда мы вызываем &lt;b&gt;$.ajax()&lt;/b&gt;, другую jQuery функцию, которая создает AJAX запрос с заданными параметрами. ASP.NET требует чтобы наш запрос был выполнен методом POST (c GET не сработает) и с установленным &lt;i&gt;content-type ‘application/json’&lt;/i&gt;. Url-параметр это просто имя нашей страницы содержащей &lt;i&gt;PageMethod&lt;/i&gt; (&lt;i&gt;Default.aspx&lt;/i&gt; в нашем примере) за которым следует прямой слеш '/‘ и имя метода нашей страницы в code-behind файле. Наш метод должен быть объявлен с аттрибутом &lt;i&gt;WebMethod()&lt;/i&gt; для того чтобы успешно выполнить запрос:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; Imports System.Web.Services  &lt;br /&gt; ...  &lt;br /&gt; &amp;lt;WebMethod()&amp;gt; _  &lt;br /&gt; Public Shared Function GetCityStateByZip(zip As String) As CityState  &lt;br /&gt; ...  &lt;br /&gt; End Function  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Данные которые отправляются на страницу должны быть в JSON формате, который сводится к набору пар 'имя-значение’ заключенные в фигурные скобки. Так как наш &lt;i&gt;PageMethod&lt;/i&gt; ожидает параметр 'zip’, мы строим наши данные по типу&lt;br /&gt;&lt;br /&gt;&lt;code&gt;{'zip':'95064'}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Затем мы устанавливаем &lt;i&gt;datatype&lt;/i&gt; параметру запроса значение 'json'. Весь список AJAX параметров:&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; type: "POST",  &lt;br /&gt; contentType: "application/json; charset=utf-8",  &lt;br /&gt; url: "Default.aspx/GetCityStateByZip",  &lt;br /&gt; data: "{'zip': '" + $(this).val() + "'}",  &lt;br /&gt; dataType: "json"  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Наконец, мы определяем success параметр нашего AJAX вызова, устанавливая его значение функцией параметр которой результат нашего запроса.&lt;br /&gt;&lt;code&gt;success: function(msg) {&lt;br /&gt;&amp;nbsp; $("#CityStateLabel").text(msg.d.City + ", " + msg.d.State);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Мы можем производить любые манипуляции с данными&amp;nbsp; которые нам нужны тут, хотя некоторые будут спорить, что обработка данных должна быть помещена на серверной стороне. Я полагаю, что в действительности это зависит от конкретной задачи. Во всяком случае, мы собираемся проделать здесь несколько манипуляций с DOM, включая простое присваивание определенному asp:Label элементу значения города&amp;nbsp; и штата, которые возвращены нам из&lt;i&gt; PageMethod&lt;/i&gt;. Опять, &lt;b&gt;$()&lt;/b&gt; берет CSS селектор как параметр, возвращая нам элемент, который мы хотим модифицировать. И мы хотим только изменить текст метки, так что мы используем &lt;b&gt;text()&lt;/b&gt; функцию, передавая ей значение, которое мы хотим установить.&lt;br /&gt;&lt;br /&gt;Изначально, я ожидал что использование &lt;i&gt;msg.City&lt;/i&gt; и&lt;i&gt; msg.State&lt;/i&gt; подобно тому как оно работает в Microsoft AJAX вызове метода страницы. Было довольно запутанно до тех пор пока не проверил JSON возвращенный из &lt;i&gt;PageMethod&lt;/i&gt; используя FireBug для Firefox (если у вас его нету, вы можете достать его здесь &lt;a href="http://getfirebug.com/" title=""&gt;http://getfirebug.com/&lt;/a&gt; ). Кажется, ASP.net обертывает весь JSON ответ и присваивает его к ключу с названием 'd'. Наш полученный JSON объект:&lt;br /&gt;&lt;code&gt;{'d': {'City': 'Santa Cruz', 'State': 'CA'}}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Так как наш JSON объект является параметром msg переданной в success функцию, то для того чтобы получить значения города мы должно просто включить &lt;i&gt;d&lt;/i&gt; в наше выражение – &lt;i&gt;msg.d.City&lt;/i&gt;.&lt;br /&gt;На этом все! Нам удалось вызвать &lt;i&gt;PageMethod&lt;/i&gt; с помощью jQuery.&lt;br /&gt;&lt;br /&gt;Перевод статьи &lt;a href="http://bit.ly/3Vrlk9"&gt;Brian Dobberteen&lt;/a&gt; (исходный код там же)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1828187461577424428-8328483796926847210?l=nolled.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nolled.blogspot.com/feeds/8328483796926847210/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://nolled.blogspot.com/2009/10/aspnet-jquery.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/8328483796926847210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1828187461577424428/posts/default/8328483796926847210'/><link rel='alternate' type='text/html' href='http://nolled.blogspot.com/2009/10/aspnet-jquery.html' title='ASP.NET: Вызов метода страницы с помощью jQuery'/><author><name>Volodymyr</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
