Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Архитектура ASP.NET 2.0

Автор: Gaidar Magdanurov
Дата :25 августа 2006

Постаравшись разобраться с внутренней инфраструктурой ASP.NET версии 2.0 можно обнаружить, что в ней нет никаких глобальных отличий от инфраструктуры версии 1.х. В жизненный цикл страницы добавились новые события, разработчик получил возможность использовать множество новых объектов и элементов управления, но общие принципы обработки HTTP остались те же, поскольку вероятность придумать что-либо более подходящее под концепцию ASP.NET представляется весьма небольшой.

В этой статье будут рассмотрены основные усовершенствования в модели компиляции ASP.NET страниц, разделение кода и представления и взаимодействие среды выполнения ASP.NET с веб-сервером IIS.

Среда выполнения ASP.NET и веб-сервер IIS

Параллельное использование с предыдущими версиями ASP.NET

Поскольку в ASP.NET 2.0 присутствуют изменения, которые могут стать фатальными для использующих предыдущие версии ASP.NET веб-приложений, разработчики и IIS предусмотрели возможность использовать разные версии ASP.NET для разных приложений на одном сервере.

В консоли управления веб-сервером IIS можно выбрать версию ASP.NET, которая будет использована для каждого приложения, а также установить версию ASP.NET, которая будет использоваться вновь создаваемыми приложениями.

Рис. 1. Конфигурирование версии ASP.NET

Эта возможность позволяет продолжить работу с веб-приложениями, созданными с использованием предыдущих версий ASP.NET.

Ручная установка ASP.NET

Для ручной установки, которая может понадобиться, если .NET Framework был установлен до установки веб-сервера IIS или по какой-либо другой причине, используется утилита командной строки aspnet_regiis.exe, которую можно найти в директории %WINDIR%\Microsoft.NET\Framework\v2.0.50727\.

Ключ Описание
-i Полная установка. Регистрирует ASP.NET 2.0 для сервера IIS и обновляет регистрацию для всех веб-приложений.
-ir Только регистрирует ASP.NET 2.0 для сервера IIS. Веб-приложения продолжают использовать ранее установленную версию ASP.NET.
-s <путь> Обновляет регистрацию для приложений, находящихся в директории <путь> и всех вложенных директориях.
-sn <путь> Обновляет регистрацию для приложений, находящихся только в директории <путь>. Не затрагивает регистрацию приложений, находящихся во вложенных директориях.
-lv Показывает список всех установленных версий ASP.NET.
-lk Показывает список всех приложений и зарегистрированную для них версию ASP.NET.
Таблица 1. Ключи aspnet_regiis.exe

Взаимодействие с IIS

Следует отметить, что веб-серверы IIS 5 и IIS 6 по-разному взаимодействуют с ASP.NET 2.0, поскольку для этих двух версий IIS используются разные модели обработки запросов.

При использовании IIS 5, среда выполнения ASP.NET представлена отдельным процессом aspnet_wp.exe. Этот процесс получает управление от IIS с помощью ASP.NET ISAPI расширения aspnet_isapi.dll. Если расширение запрошенного ресурса связано с ASP.NET ISAPI расширением, то запрос поступает на обработку рабочим процессом ASP.NET, который, в свою очередь, отвечает за загрузку CLR, создание управляемых объектов и выстраивания очереди событий для ASP.NET страницы. В этом случае особенно важно отметить, что рабочий процесс aspnet_wp.exe обслуживает все веб-приложения: каждое приложение выполняется в отдельном домене приложения AppDomain в рамках одного рабочего процесса. Рабочий процесс выполняется под специальной учетной записью ASPNET.

Процесс обработки запроса при использовании IIS 5 может быть разбит на следующие шаги:

  1. IIS получает запрос, определяет тип ресурса и, если данный тип связан с ASP.NET, передает его на обработку расширению aspnet_isapi.dll. ISAPI расширение передает запрос на дальнейшую обработку рабочему процессу ASP.NET.
  2. После получения запроса, рабочий процесс передает сообщение ISAPI расширению, сообщая о том, что запрос будет обработан.
  3. Запрос выполняется в контексте рабочего процесса ASP.NET.
  4. После окончания выполнения, рабочий процесс передает данные ISAPI расширению, которое отвечает за освобождение ресурсов, занятых рабочим процессом.

В случае использования IIS 6 модель обработки запросов несколько меняется, поскольку IIS 6 используем модель пула приложений – отдельного рабочего процесса, который обслуживает одно или несколько веб-приложений. Каждый пул приложений обслуживается отдельным экземпляром рабочего процесса w3wp.exe.

IIS 6 использует для получения и обработки запросов драйвер, работающий на уровне ядра операционной системы http.sys, все запросы проходят через этот драйвер, который отвечает за сопоставление запроса соответствующему пулу приложений. Рабочий процесс, обслуживающий пул приложений, загружает необходимые ISAPI расширения. В случае ASP.NET это рашсирение aspnet_isapi.dll, которое в свою очередь загружает CLR и начинает обработку HTTP запроса. Рабочие процессы выполняются под учетной записью NetworkService.

Структура ASP.NET страницы и модель компиляции

Структура страницы ASP.NET 2.0 не отличается от структуры страниц ASP.NET 1.х. Страница по-прежнему разделена на две основные части: директивы и представление. Код программной логики страницы может быть вынесен в отдельный файл (выделенный код, Code Behind), либо включен в представление страницы в качестве блока <script> с установленным атрибутом runat=”server” (встроенный код, inline code)).

Разделение кода программной логики и представления

Рассмотрим оба этих способа размещения кода и различия между подходом к разделению кода в ASP.NET 1.х и 2.0. В ASP.NET 1.x при использовании модели встроенного кода класс страницы ASP.NET наследовал классу System.Web.UI.Page и при выполнении приложения компилировался во временную сборку.

Рис. 2. Модель встроенного кода ASP.NET 1.x

При использовании модели разделения кода и представления в ASP.NET 1.x схема наследования становится более сложной, поскольку классу System.Web.UI.Page наследует класс, определенный в файле программной логики (Code Behind), которому, в свою очередь, наследует класс страницы ASP.NET. При этом класс, определенный в файле программной логики компилируется в единую сборку приложения, находящуюся в директории bin, а класс страницы компилируется во временную сборку.

Рис. 3. Модель выделенного кода ASP.NET 1.x

В ASP.NET 2.0, в связи с появлением возможность разделения классов, общая схема становится несколько иной. Для ASP.NET страницы создается частичный класс страницы (partial class), который объединяется частичным классом, объявленным в файле программной логики, который затем компилируется как единой целое, поэтому в файле с исходным кодом нет декларации элементов управления и создания экземпляров этих элементов. Код, создающий элементы управления, генерируется во время компиляции на основании файла с кодом разметки страницы.

Частичные классы (partial class)

Разделение классов позволяет разбивать код класса на несколько различных частей, исходный код которых может быть размещен в разных файлах. Например, класс User:

 
        public class User 
        { 
          private int mInt; 
          private long mLong; 
          private string mString; 
          private bool mBool; 
          public int MyInt{ 
            get{return this.mInt;} 
            set{this.mInt = value;} 
          } 
        } 
		

Может быть разбит на несколько частей с использованием ключевого слова partial:

 
        public partial class User 
        { 
          private int mInt; 
          private long mLong; 
          private string mString; 
          private bool mBool; 
        } 
        public partial class User 
        { 
          public int MyInt{ 
            get{return this.mInt;} 
            set{this.mInt = value;} 
          } 
        }
		

Рис. 4. Модель частичных классов ASP.NET 2.0

Если быть откровенным, то дело обстоит не совсем так, как показано на Рис. 4. Помимо класса, «собранного» из двух частей – частичного класса в файле исходного кода и частичного класса, сгенерированного средой выполнения, существует класс страницы, точно также как и в ASP.NET 1.x наследующий классу, определенному в файле исходного текста.

Если посмотреть код сборки, созданной для страницы, содержащей одну кнопку Button1, то можно найти два класса, имеющих отношение к одной странице. Собственно класс, определенный в файле исходного кода:

 
  public class _Default : Page, IRequiresSessionState 
  { 
        static _Default(); 
        public _Default(); 
        protected void Button1_Click(object sender, EventArgs e); 
        protected void Page_Load(object sender, EventArgs e); 
        protected HttpApplication ApplicationInstance { get; } 
        protected DefaultProfile Profile { get; } 
        protected Button Button1; 
        protected HtmlForm form1; 
        public static string Hello; 
  } 
  

И класс страницы, наследующий ему:

 
  [CompilerGlobalScope] 
  public class default_aspx : _Default, IHttpHandler 
  { 
        public default_aspx(); 
        private HtmlHead __BuildControl__control2(); 
        private HtmlTitle __BuildControl__control3(); 
        private Button __BuildControlButton1(); 
        private HtmlForm __BuildControlform1(); 
        private void __BuildControlTree(default_aspx __ctrl); 
        protected override void FrameworkInitialize(); 
        public override int GetTypeHashCode(); 
        public override void ProcessRequest(HttpContext context); 
        private static object __fileDependencies; 
        private static bool __initialized; 
  } 
  

Модель компиляции

Для ASP.NET 1.x существовало две основных стратегии компиляции:

  1. Перекомпиляция исходного кода приложения, содержащегося в файлах программной логики, при этом создается единая сборка, помещаемая в каталог bin
  2. Динамическая компиляция приложения во время первого запроса, в этом случае в каталог на сервере помещаются все исходные файлы веб-приложения и полная компиляция осуществляется при поступлении первого запроса к приложению.

В ASP.NET 2.x появились новые дополнительные стратегии, связанные с новой моделью компиляции приложений: для каждой ASP.NET страницы создается своя собственная сборка. Эта модель компиляции открывает возможность не перекомпилировать все приложение при изменении одного файла исходного кода, а осуществлять компиляцию только измененных файлов. Поэтому ASP.NET 2.0 предлагает три основных стратегии компиляции приложений:

  1. Перекомпиляция файлов программной логики. В этом случае создаются сборки в директории bin, которые во время выполнения объединяются с динамическими сборками, генерируемыми для страниц с использованием механизма разделения классов.
  2. Полная пре-компиляция. Абсолютно новая возможность, появившаяся в ASP.NET 2.0 и позволяющая создать одну сборку для всех файлов приложения, включая файлы ASPX, содержащие HTML разметку. Сборка помещается в директорию bin веб-приложения, а содержимое всех ASPX файлов замещается на стоку «This is a marker file generated by the precompilation tool, and should not be deleted!».
  3. Динамическая компиляция. Эта стратегия аналогична используемой в ASP.NET стратегии динамической компиляции по запросы, с одним исключением, что страницы компилируются не одновременно, а по мере поступления запросов к каждой конкретной странице.

Прекомпиляция веб-приложения

Для осуществления пре-компиляции веб-приложения перед публикацией на веб-сервере можно использовать утилиту командной строки aspnet_compiler.exe, находящейся в директории %WINDIR%\Microsoft.NET\Framework\v2.0.50727\., либо графическую утилиту, встроенную в Visual Studio 2005 (утилита пре-компиляции не включена в Express версию Visual Studio 2005).

Ключ Описание
-p <path> Указывает полный физический путь путь к приложению <path>.
-u Если этот ключ указан, то разметка в файлах ASPX сохраняется, в противном случае разметка замещается фразой «This is a marker file generated by the precompilation tool, and should not be deleted!».
Указывает утилите aspnet_compiler.exe на то, что необходимо осуществить полную перекомпиляцию всех файлов, даже не измененных со времени последней компиляции.
Таблица 2. Ключи aspnet_compiler.exe

Пример использования aspnet_compiler.exe:

aspnet_compiler.exe -p C:\ASPNET\WebApp c:\wwwroot\WebApp

Использование графической, утилиты, встроенной в Visual Studio 2005 еще проще: чтобы вызвать утилиту пре-компиляции необходимо выбрать пункт Publish в меню Build. Затем указать путь к каталогу, куда должны быть помещены скомпилированные файлы проекта, предназначенные для публикации и выбрать желаемые опции.

Рис. 5. Встроенная утилита пре-компиляции

Преимущества пре-компиляции заключаются выигрыше во времени динамической компиляции на сервере, а также в отсутствии необходимости распространять исходные тексты веб-приложений, что позволяет защитить исходные тексты от умышленного и неумышленного повреждения, а также нарушении авторских прав на исходный код.

Недостатком иногда может быть отсутствие возможности внести изменения в код веб-приложения, уже опубликованного на сервере.

Объектная модель страницы

Как уже было описано выше при обсуждении разделения кода программной логики и представления страницы, вне зависимости от того, используется ли модель разделения кода или нет, класс страницы наследует классу Page, который, в свою очередь, является элементом управления, поскольку наследует классу TemplateControl. А также, класс Page является HTTP обработчиком, поскольку реализует интерфейс IHttpHandler.

 
  public class Page : TemplateControl, IHttpHandler {}
  

В ASP.NET 2.0 в классе Page появились новые свойства, методы, события и внутренние объекты, которые были добавлены для реализации новых возможностями ASP.NET 2.0, таких как поддержка шаблонов (master pages) и тем оформления, персонализация, встроенные счетчики посещений и асинхронная обработка, о которых будет рассказано в последующих главах этой книги.

Новые свойства класса Page

Свойство

Описание

EnableTheming

Позволяет определить, используются ли темы для станицы или нет.

IsAsync

Определяет способ выполнения страницы: синхронный или асинхронный.

IsCallback

Указывает, была ли страница вызвана в результате обратного вызова со стороны клиента (Callback).

IsCrossPagePostBack

Указывает, была ли страница вызвана в результате отправки данных на сервер другой страницей.

MasterPageFile

Позволяет указать файл шаблона (master page) для данной страницы.

PreviousPage

Возвращает объект, представляющий страницу с которой был осуществлен вызов данной страницы.

Title

Позволяет получить или установить заголовок страницы.

Таблица 3. Новые свойства класса Page

О свойствах IsCrossPagePostBack и IsCallback будет сказано несколько слов далее в этой главе, при рассмотрении возможности использования клиентских обратных вызовов и отправки данных другой странице.

Новые методы класса Page

Большинство новых методов класса Page наследуются от класса Control, от которого наследуется TemplateControl, поэтому применимы для всех элементов управления ASP.NET.

Метод

Описание

EnsureID

Создает уникальный идентификатор для элемента управления (для страницы практической пользы не имеет).

Focus

Устанавливает фокус ввода для элемента управления (для страницы практической пользы не имеет).

GetValidators

Возвращает коллекцию влидаторов, относящихся к определенной группе.

RegisterRequiresControlState

Устанавливает для переданного в качестве параметра элемента управления необходимость управления состоянием элемента управления (control state).

SetFocus

Устанавливает фокус ввода на определенный элемент управления.

TestDeviceFilter

Проверяет, является ли текущий браузер, используемый для просмотра страницы, указанным в качестве параметра метода.

Таблица 4. Новые методы класса Page

Новые внутренние объекты класса Page

К унаследованным от контекста HTTP запроса объектам Application, Session, Request и Response и глобальным объектам среды выполнения Cache, Trace и User, доступных в объекте страницы, добавился набор объектов, упрощающих работу со страницей.

Объект

Описание

ClientScript

Экземпляр класса ClientScriptManager, предоставляющего набор методов для работы с клиентскими сценариями.

Header

Экземпляр объекта HtmlHead, представляющего заголовок HTML страницы.

Master

Ссылка на объект, представляющий шаблон, используемый для данной страницы.

Таблица 5. Новые внутренние объекты класса Page

Необходимо отметить, что объект Header доступен только когда в файле разметки в блоке <head> указан атрибут runar=”server”.

 
  <header runat=”server”>
    <title>Это страница</title>
  </header> 

В этом примере, с помощью свойства Header.Title можно получить заголовок страницы «Это страница».

Объект Master доступен, если для страницы определен шаблон одним из описанных в следующей главе книги, посвященной шаблонам, способом.

Новые события класса Page

Новые события страницы, добавленные в ASP.NET 2.0 позволяют разработчику получить больший контроль над жизненным циклом страницы и управлять внутренними механизмами ASP.NET. Подробное описание событий и порядка выполнения будет рассмотрено в параграфе, посвященном жизненному циклу страницы. Здесь же будет рассмотрены только новые события.

Событие

Описание

InitComplete

Возникает после инициализации объекта страницы.

LoadComplete

Происходит после окончания загрузки страницы.

PreInit

Первое событие в жизненном цикле страницы.

PreLoad

Возникает перед загрузкой информации о состоянии.

PreRenderComplete

Происходит после создания всех дочерних элементов управления.

Таблица 6. Новые события класса Page

Новые атрибуты директивы @Page

Поведение страницы ASP.NET определяется директивами, заданными в директиве @Page в файле разметки ASPX, либо установленные непосредственно в коде. Директива @Page в ASP.NET 2.0 унаследовала большинство атрибутов от предыдущих версий ASP.NET. В этом параграфе будут рассмотрены только новые атрибуты ASP.NET 2.0. Для подробного изучения возможностей директивы @Page рекомендуется воспользоваться документацией MSDN.

Атрибут

Описание

Async

Если атрибут установлен в true, то генерируемый для страницы класс будет наследовать IHttpAsyncHandler, если установлен в false, то класс наследует IHttpHandler.

AsyncTimeout

Устанавливает временной интервал тайм-аута, используемого для асихронного выполнения страницы.

CompilationModel

Атрибут позволяет управлять компиляцией страницы.

EnableTheming

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

MasterPageFile

Путь к файлу шаблона, используемого для данной страницы.

Theme

Имя темы визуального оформления, используемой для страницы.

Таблица 7. Новые атрибуты директивы @Page

Об асинхронном выполнении страниц будет рассказано в следующих главах этой книги. Пока же стоит сказать, что установка директивы Async в true позволяет асинхронно выполнять код параллельно с обработкой жизненного цикла страницы.

Директива CompilationModel может принимать одно из трех значений, указанных в таблице.

Значение

Описание

Always

Страница всегда должна быть скомпилирована.

Auto

Страница не должна быть скомпилирована, если это возможно.

Never

Страница никогда не должна быть скомпилирована.

Таблица 8. Значения атрибута CompilationModel

Если атрибут CompilationModel установлен в Never, то наличие встроенного программного кода приведет к ошибке.

Жизненный цикл страницы

Жизненный цикл страницы ASP.NET начинается с получения и обработки Web-сервером IIS запроса к данной странице и передачи этого запроса среде выполнения ASP.NET. В момент получения запроса, среда выполнения загружает класс вызываемой страницы, устанавливает свойства класса страницы, выстраивает дерево элементов, заполняет свойства  Request и Response и вызывает метод IHttpHandler.ProcessRequest. После этого среда выполнения проверяет, каким образом была вызвана эта страницы и если страница вызвана путем передачи данных с другой страницы, о чем будет рассказано далее, то среда выполнения устанавливает свойство PreviousPage.

    Стоит отметить также, что помимо рассмотренных ниже этапов выполнения страницы существуют еще и этапы уровня приложения, не специфичные для страницы.

Этап

Описание

Запрос станицы Запрос страницы осуществляется ядо начала жизненного цикла страницы. Когда пользователь осуществляет запрос, среда выполнения ASP.NET устанавливает, необходимо ли осуществить компиляцию страницы и начать жизненный цикл, либо можно выдать в качестве ответа страницу из кеша, таким образом, не выполняя страницы.
Начало жизненного цикла На этом этапе происходит установка свойство Response и Request и свойства UICulture. Также, на этом этапе устанавливается, была ли эта страница запрошена в результате постбэка (отправления данных на сервер) и соответствующим образом устанавливается свойство IsPostBack.
Инициализация страницы Ко времени инициализации страницы все дочерние пользовательские элементы управления уже созданы и имеют установленный свойства UniqueID. В это же время к странице применяются темы оформления. Если страница вызвана в результате постбэка, то данные, отправленные на сервер, еще не загружены в свойства элементов управления, на этом этапе.
Загрузка Если страница вызвана в результате постбэка, то на этом этапе устанавливаются свойства элементов управления, на основании информации о состоянии (ViewState и ControlState).
Валидация Вызывается метод Validate() для всех, находящихся на странице валидаторов.
Обработка постбэка Вызываются обработчики событий (при условии, что постбэк произошел).
Рендеринг Сохраняется информация о состоянии, затем класс страницы вызывает соответствующие методы дочерних элементов управления для генерации HTML представления и передачи его в  Response.OutputStream.
Выгрузка Выгрузка происходит после того, как создано HTML представление для всей страницы.

Во время прохождения этапов жизненного цикла возникают события, подписавшись на которые, разработчик может выполнять свой собственный код. Стоит упомянуть атрибут AutoEventWireup, директивы @Page: если этот атрибут установлен в true (значение по умолчанию), то методы класса страницы, названные Page_НазваниеСобытия, автоматически становятся обработчиками соответствующих событий жизненного цикла станицы.
    Для того, чтобы проследить жизненный цикл страницы и последовательность возникновения событий, можно установить атрибут Trace директивы @Page в true, а атрибут TraceMode в "SortByTime". Тогда в разделе Trace Information можно найти список произошедших событий (колонка Message). Например:

Trace Information

Category

Message

From First(s)

From Last(s)

aspx.page Begin PreInit    
aspx.page End PreInit 0.0364973314167865 0.036497
aspx.page Begin Init 0.0379050459346291 0.001408
aspx.page End Init 0.047693704143491 0.009789
aspx.page Begin InitComplete 0.0477864508468221 0.000093
aspx.page End InitComplete 0.0481875670270608 0.000401
aspx.page Begin PreLoad 0.0489879732516718 0.000800
aspx.page End PreLoad 0.0494462283607275 0.000458
aspx.page Begin Load 0.0494924892194238 0.000046
aspx.page End Load 0.0553441897381414 0.005852
aspx.page Begin LoadComplete 0.0554711043059809 0.000127
aspx.page End LoadComplete 0.055942153615399 0.000471
aspx.page Begin PreRender 0.0561455634022874 0.000203
aspx.page End PreRender 0.0618604874695332 0.005715
aspx.page Begin PreRenderComplete 0.06269871008062 0.000838
aspx.page End PreRenderComplete 0.0633259746265858 0.000627
aspx.page Begin SaveState 0.080360541216174 0.017035
aspx.page End SaveState 0.213795377788888 0.133435
aspx.page Begin SaveStateComplete 0.213911298043872 0.000116
aspx.page End SaveStateComplete 0.214385763389788 0.000474
aspx.page Begin Render 0.214440078745078 0.000054
aspx.page End Render 0.315044337228923 0.100604

Из всех событий жизненного цикла страницы, разработчик может подписаться только на пять, помимо событий дочерних элементов управления. Эти события: PreInit, Init, Load, PreRender, Unload. Рассмотрим варианты использования этих событий.

Событие

Использование

PreInit Во время этого события можно использовать свойство IsPostBack, для того, чтобы определить вызвана ли эта страница в первый раз или в результате постбэка. В плане управления страницей разработчик может: создавать динамически элементы управления, динамически устанавливать шаблон дизайна или тему оформления, считывать или устанавливать свойства объекта Profile.

Стоит особо отметить, что на данном этапе, если страница была вызвана в результате постбэка, свойства элементов управления еще не установлены. В случае, если разработчик самостоятельно установит свойства на этом этапе, на следующем установленный значения могут быть изменены.

Init На этом этапе разработчик может считывать или инициализировать свойства элементов управления.
Load На этом этапе разработчик может считывать или изменять свойства элементов управления.
PreRender Последняя возможность внести изменения во внешний вид страницы.
Unload Освобождение занятых ресурсов (закрытие открытых соединений с базой данных, завершение работы с файлами и т.п.)

Важно, что на этом этапе уже создано HTML представление страницы и попытка внести какие-либо изменения (например, вызвав метод Response.Write()), приведет к исключению.

Новые возможности страницы ASP.NET

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

Передача данных формы другой странице

Существенное ограничением серверных форм в ASP.NET 1.x – отсутствие возможности непосредственно передавать данные, введенные в форме, другой странице. Чтобы отправить значения элементов форму другой странице необходимо использовать простою HTML форму и в атрибуте action указать путь к странице, которая должна получить данные, либо создать свой собственный класс страницы, наследник класса Page, в котором переопределить метод Render так, чтобы получить возможность замещать атрибут action на какой-либо другой.

В ASP.NET 2.0 тег элемента управления, вызывающего отправление данных на сервер, может иметь дополнительный атрибут PostBackUrl, позволяющий указать какой странице система должна передать Web-форму.

Рис. 6. Передача данных на сервер

 
  <form id="frmTest" runat="server"> 
    <asp:textbox id="txtFirstName" runat="server" /><br /> 
    <asp:textbox id="txtLastName" runat="server" /><br /> 
    <asp:button id="btnSend" Text="Отправить данные" PostBackUrl="crosspost.aspx" 
         runat="server" /> 
  </form> 
  

После щелчка по кнопке, браузер пользователя будет переадресован на страницу crosspost.aspx, при этом вся информация об элементах управления формы, с которой произошло отправление данных, будет также передано.

Чтобы реализовать эту возможность, среда ASP.NET 2.0 осуществляет проверку ASPX страниц на предмет наличия элементов управления с заданным атрибутом PostBackUrl и, при наличии таковых, создает на странице дополнительное скрытое поле __PREVIOUSPAGE, которое и содержит информацию о состоянии элементов формы. Эта информация доступна странице-получателю через свойство PreviousPage.

 
  void Page_Load(object sender, EventArgs e) 
  {         
        if (PreviousPage != null)         
        { 
           // Получаем объекты отправленной формы     
          TextBox txtFirstName = 
          (TextBox)PreviousPage.FindControl("txtFirstName"); 
          TextBox txtLastName = 
          (TextBox)PreviousPage.FindControl("txtLastName"); 
           // Используем данные 
           txtInfo.Text = "Добрый день, " + txtFirstName.Text + "!"; 
        } 
  } 
  

На уровне HTML кода, отправка данных другой форме выглядит следующим образом.

 
  <form method="post" action="GetValues.aspx" id="frmTest"> 
  <input type="submit" name="btnSend" value="Post Data" 
     onclick="javascript:WebForm_DoPostBackWithOptions( 
     new WebForm_PostBackOptions(&quot;btnSend&quot;, &quot;&quot;, false, 
     &quot;&quot;, &quot;CrossPage.aspx&quot;, false, false))" id="btnSend" /> 
  </form> 
  

Из чего можно заключить, что данные формы не направляются из браузера непосредственно странице CrossPage.aspx, а предварительно направляются все той же странице GetValues.aspx, которая содержит форму frmTest. Это необходимо для поддержки серверной проверки (validation) введенных данных с использованием элементов управления RequiredFieldValidation, RangeValidation и других.

Клиентские обратные вызовы

В ASP.NET 2.0 стало возможным обновлять данные на странице без отправки страницы на сервер и ее полного обновления. Это стало возможно благодаря появлению клиентских сценариев с обратным вызовом (callback scripts). После того, как некоторое событие вызывает запрос к серверу, обновленные данные передаются непосредственно в клиентский сценарий в качестве аргументов функции.

Подобный способ обновления данных на странице удобно и выгодно применять, когда для обновления всей информации требуется много ресурсов и достаточно длительное время, при этом эти часть данных обновляется часто, а остальные данные статичны. Тогда время на обновления данных, например, одного пользовательского элемента, учитывая время запроса к серверу, обработки и получения ответа, будет существенно ниже, чем время обновления всей страницы.

Допустим, существует страница, на которой находится выпадающий список. Когда пользователь выбирает некоторое значение из списка, в некоторый элемент управления загружается значение, логически связанное с выбранным из списка значением. При этом задача такова, что нельзя хранить все данные на стороне клиента (возможно данных слишком много и страница будет долго передаваться по сети, либо данные генерируются на сервере не только в зависимости от выбранного пользователем элемента выпадающего списка). В ASP.NET 1.x для решения этой задачи необходимо привязать к событию изменения значения в выпадающем списке серверный метод. При этом список должен вызывать отправку страницы на сервер при каждом изменении значения (AutoPostBack="True").

 
  protected void ddStatic_SelectedIndexChanged(object sender, EventArgs e) 
  { 
  // На основании значения ddStatic.Items[ddStatic.SelectedIndex].Value 
  // метод устанавливает свойства дригих элементов управления 
  } 
  

В ASP.NET 2.0, как уже было сказано выше, существует возможность не обновлять всю страницу целиком. В данном случае разумно обновить только необходимые данные, поскольку обновлять всю страницу только для того, чтобы установить одно значение слишком расточительно.

Для реализации механизма обновления данных без перезагрузки страницы необходимо создать клиентскую функцию обратного вызова, принимающую переданные с сервера параметры, серверную функцию, принимающую параметры от клиента и возвращающую клиенту значения на основании полученных параметров и связать эти две функции. Мало того, механизм обратного вызова в ASP.NET 2.0 позволяет возвращать результат асинхронно. Для этого в интерфейсе ICallbackEventHandler определены два метода: RaiseCallbackEvent, для получения параметров на сервере и GetCallbackResult для возвращения результата клиенту.

Для реализации функциональности предыдущего примера в ASPX файле помещается следующий код.

 
  <script> 
  function UpdateText(result, context)  
  {  
        dSpan.innerText = result; 
  } 
  </script> 
  <asp:DropDownList ID="ddDynamic" runat="server"> 
  </asp:DropDownList><br /> 
  <span id="dSpan" style="font-weight: bold;"></span> 
  

Класс страницы, использующей функции с обратным вызовом должен реализовывать интерфейс ICallbackEventHandler.

 
  public partial class ScriptCallback_aspx : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler { }
  

Сигнатуры функций, поддерживающие обратный вызов выглядят следующим образом:

 
  public virtual void RaiseCallbackEvent(string Аргументы) 
  public virtual string GetCallbackResult() 
  private string EventArgument = ""; 
  public void RaiseCallbackEvent (string eventArgument) 
  { 
      EventArgument = eventArgument; 
  } 
  public string GetCallbackResult() 
  { 
      return EventArgument; // значение типа string 
  } 
  

Последним шагом к поставленной цели является связывание серверной и клиентских функций.

 
  protected void Page_Load(object sender, EventArgs e) 
  { 
        // создаем ссылку на функцию обратного вызова 
        string callbackFunction = Page.ClientScript.GetCallbackEventReference 
        ( 
              this, 
              "document.all['ddDynamic'].value", 
              "UpdateText", 
              "null" 
        ); 
        // Привязываем сценарий к событию изменения значения выпадающего 
        // списка 
  ddDynamic.Attributes["onchange"] = String.Format("javascript:{0}",     
  callbackFunction); 
  } 
  

Метод GetCallbackEventReference объекта ClientScriptManager принимает в качестве параметров ссылку на объект страницы, строку, указывающую на значение, которое необходимо передавать на сервер при обратном вызове, имя метода на стороне клиента и принимающего ответ сервера. Подробное описание можно получить в документации MSDN или с помощью инструмента Visual Studio - Object Browser.

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

 
  // Список, вызывающий перезагрузку страницы 
  <select name="ddStatic" 
  onchange="javascript:setTimeout('__doPostBack(\'ddStatic\',\'\')', 0)" id="ddStatic"> 
  </select>  
  // Список вызывающий метод с обратным вызовом 
  <select name="ddDynamic" id="ddDynamic" 
  onchange="javascript:WebForm_DoCallback('__Page',document.all['ddDynamic'].value,UpdateText,null,null,false)"> 
  
Стандартная функция doPostBack весьма проста и служит для сохранения данных о событии в скрытые поля формы.
 
  var theForm = document.forms['frmCallBack']; 
  function __doPostBack(eventTarget, eventArgument) { 
      if (theForm.onsubmit == null || theForm.onsubmit()) { 
          theForm.__EVENTTARGET.value = eventTarget; 
          theForm.__EVENTARGUMENT.value = eventArgument; 
          theForm.submit(); 
      } 
  } 
  

При использовании функций с обратным вызовом механизм значительно сложнее. Код функции WebForm_DoCallback гораздо больше, чем doPostBack, поскольку эта функция определяет тип объектной модели браузера, после чего загружает необходимый для передачи данных с модуль. Например, для браузера поддерживающего DOM это будет Microsoft.XMLHTTP.

Посмотреть код различных клиентских функций, используемых средой ASP.NET 2.0 можно сохранив страницу, поддерживающую функции с обратным вызовом на жесткий диск и открыв в текстовом редакторе файл WebResource.axd, ссылка на который имеется в HTML странице.

Заключение

В этой статье было рассказано о новых элементах, привнесенных в архитектуру ASP.NET 2.0 по сравнению с ASP.NET 1.x.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог