На днях столкнулся такой ситуацией, что многие некоторые разработчики при упоминании Ajax имеют в виду компонент UpdatePanel и не понимают как она работает. Сегодня я решил попытаться исправить эту ситуацию и рассказать что такое и как устроен ASP.NET Ajax.

 Для начала обратимся Википедии и посмотрим, что такое Ajax:

AJAX (Asynchronous Javascript and XML — «асинхронный JavaScript и XML») — это подход к построению интерактивных пользовательских интерфейсов веб-приложений, заключающийся в «фоновом» обмене данными браузера с веб-сервером. В результате при обновлении данных веб-страница не перезагружается полностью, и веб-приложения становятся более быстрыми и удобными.

Для выполнения асинхронных запросов, на JavaSctipt необходимо создать объект XMLHttpRequest, который и будет взаимодействовать с сервером. В зависимости от браузера, объект создаётся разными способами, но можно написать универсальный метод для его создания:

    function createRequestObject()
    {
    if (window.XMLHttpRequest) {
    try {
    return new XMLHttpRequest();
    } catch (e){}
    } else if (window.ActiveXObject) {
    try {
    return new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e){
    try {
    return new ActiveXObject('Microsoft.XMLHTTP');
    } catch (e){}
    }
    }
    return null;
    }
 

 

Теперь вернёмся в ASP.NET. Как несложно догадаться, Microsoft ASP.NET Ajax имееит клиент-серверную архитектуру:

Серверная часть Microsoft ASP.NET Ajax отвечает за авторизацию и аутентификацию пользователей, генерацию и регистрацию на странице необходимых скриптов, имеет всё необходимое для работы с веб-службами, включая генерацию proxy-классов, xml и JavaScript сериализацию. Также доступно несколько компонентов (ScriptManager, UpdatePanel, UpdateProgress и Timer), которых вполне достаточно для реализации базовых функций.

Клиентская часть имеет название Microsoft AJAX Library и состоит из нескольких JavaScript файлов, с помощью каких взаимодействие с сервером становится проще. В этой библиотеке доступно множество классов, для взаимодействия с веб-службами, работы с DOM-моделью браузера, имебтся базовые классы для создания собственных контролов.

В следующих постах я расскажу подробнее о том, как работает серверная часть и загляну внутрь Microsoft AJAX Library.

Ссылки, где можно почитать подробнее об ASP.NET AJAX:


Время от времени приходится организовывать возможность загрузки пользователями файлов на сервер: загрузка аватарок, файлов для галереи и т.д.  

Для решения этой задачи существует стандартный ASP.NET компонент FileUpload, который, в свою очередь, педставляет html-тэг <input type="file" />. В простнйшем случае код для загрузки файлов будет выглядеть так:

  •  Default.aspx:
    1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
    2.  
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4.  
    5. <html xmlns="http://www.w3.org/1999/xhtml">
    6. <head runat="server">
    7.     <title></title>
    8. </head>
    9. <body>
    10.     <form id="form1" runat="server">
    11.     <div>
    12.         <asp:FileUpload ID="fu" runat="server" />
    13.        
    14.         <input type="submit" value="Upload" />
    15.     </div>
    16.     </form>
    17. </body>
    18. </html>
    19.  
    20.  

  • Default.aspx.cs
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.UI;
    6. using System.Web.UI.WebControls;
    7. using System.IO;
    8.  
    9. namespace WebApplication1
    10. {
    11.     public partial class _Default : System.Web.UI.Page
    12.     {
    13.         protected void Page_Load(object sender, EventArgs e)
    14.         {
    15.             if (IsPostBack && fu.FileContent != null)
    16.             {
    17.                 fu.PostedFile.SaveAs(path);
    18.             }
    19.         }
    20.     }
    21. }
    22.  
    23.  
Этот способ имеет несколько недостатков, один из которых - необходимость делать полный postback. Поэтому возникает желание сделать это с промощью AJAX. Т.к. использование AJAX подразумевает собой применение объекта XMLHttpRequest, который из-за соображений безопастногсти запрещает передавать на сервер файлы, то решать данную задачу приходится другим способом. А именно с использованием iframe.
Переделаем предыдущий варивант и с приминением ifame:
  • Default.aspx: 
    1. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
    2.  
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    4.  
    5. <html xmlns="http://www.w3.org/1999/xhtml">
    6. <head runat="server">
    7.     <title></title>
    8. </head>
    9. <body>
    10.     <script type="text/javascript">
    11.         function onFormSubmit() {
    12.             var formUpload = document.getElementById('form1');
    13.             formUpload.target = 'upload_target';
    14.             formUpload.action = 'default.aspx';

    15.         }
    16.     </script>
    17.     <form id="form1" onsubmit="onFormSubmit();">
    18.     <div>
    19.         <input id="file1" type="file" name="file1" /> <br />
    20.         <input id="file2" type="file" name="file2" />
    21.        
    22.         <input type="submit" value="Upload" />
    23.        
    24.         <iframe id="upload_target1" name="upload_target" src="" style="width:0;height:0;border:0px solid #fff;"></iframe>
    25.     </div>
    26.     </form>
    27. </body>
    28. </html>
    29.  

  • Default.aspx.cs:
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.UI;
    6. using System.Web.UI.WebControls;
    7. using System.IO;
    8.  
    9. namespace WebApplication1
    10. {
    11.     public partial class _Default : System.Web.UI.Page
    12.     {
    13.         protected void Page_Load(object sender, EventArgs e)
    14.         {
    15.             if (IsPostBack)
    16.             {
    17.                 HttpFileCollection uploads = HttpContext.Current.Request.Files;
    18.                 for (int i = 0; i < uploads.Count; i++)
    19.                 {
    20.                     HttpPostedFile upload = uploads[i];
    21.  
    22.                     if (upload.ContentLength == 0)
    23.                         continue;
    24.  
    25.                     upload.SaveAs(path);
    26.                 }
    27.  
    28.             }
    29.         }
    30.     }
    31. }
    32.  
    33.  
Таким образом мы получаем ajax-эффект закгрузки файлов на сервер. Ещё одним интересным способом загрузки файлов является использование flash-компонентов (http://www.swfupload.org/). Готовый к приминению ajax-компонент можно скачать здесь: http://ajaxuploader.com/. Посмотреть how-to видео можно на сайте ASP.NET (http://www.asp.net/learn/videos/)

Свершилось! Несколько дней назад вышел .net 3.5 service pack 1. В месте с ним мы получили ASP.NET Dynamic Data, Entity Framework,  ADO.NET Data Services и много чего другого. Подообнее можно почитать тут.

Но, разумеется, в каждой бочке мёда найдётся своя ложка дёгтя. Ей стал Ajax Control Toolkit, а именно одни из его базовых компонентов - ToolkitScriptManager. После установки .net 3.5 sp1 ToolkitScriptManager, входящий в состав Microsoft Ajax Control toolkit, перестал правильно функционировать. Разработчики компонентов достаточно быстро отреагировали  и выпустили новый релиз, который имеет совместимость с носледней версией .net framework. Так что ставим новую версию, и продолжаем использовать пусть и не лучшую, но уже ставшую достаточно популярной связку MS Ajax и Ajax Control Toolkit. Новую версию тулкита качает здесь.


Интеграция различных скриптов на страницу, где используется MS Ajax - задача нередкая, но единого решения для неё не существует. Я поделюсь с вами некоторыми методами, которые помогут интегрировать срипт в вашу страницу.

  • Никогда не подключайте скрипты с помощью тега <script src="..."></script>. Вместо этого следует использовать копмонени ScriptManager либо ScriptManagerProxy.
  • Что бы не говорили разработчики MS Ajax и AjaxControlToolkit, в конец каждого файла со скриптом следует добавить такой код:
    if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
    Данный код указывает на то, что скрипт полностью загрущился и можно его выполнять.
  • Если скрипт необходимо подгружать только в определённых ситуациях (например, добавление нового компонента на форму), то его следует регистрировать с помощью статических методов класса ScriptManager вида RegisterClientScriptXXX().
  • Для выполнения скрипта после загрузки на страницу есть несколько методов:
    1) использовать клиентское событие EndRequest;
    2) создать функцию с именем pageLoad() - метод аналогичен первому;
    3) если скрипт необходимо зарегистрировать с помощью серверного кода, то используйте метод ScriptManager.RegisterStartupScript().

Эти методы не являются панацеей от всех бед, но помогают экономить часть времени, необходимого на интеграцию скриптов. Иногда хватает только этого, иногда приходится часами отлаживать чужой javascript, но знать о них, как я думаю, должен каждый разработчик, использующий MS Ajax.


e0ne's comments

A Web Developer's Blog!