Элементы управления Web Parts.
Этот набор элементов управления поддерживает WebParts-модель ASP.NET для построения компонентных, легко конфигурируемых Web-порталов.
Элементы управления являются мощным и удобным инструментом для разработчика приложений. Фактически, любой разработчик может создать собственные элементы управления с нужной ему логикой, если функциональности стандартных элементов управления недостаточно. Это становится возможным благодаря существующей модели генерации HTML-кода для страницы. Давайте более подробно разберем модель генерации кода HTML.
Как мы уже могли убедиться, страница ASP.NET Web Forms представляет собой совокупность элементов управления, каждый из которых обладает собственной функциональностью и логикой. В этом случае встает вопрос о том, какой именно программный компонент будет генерировать код HTML, который будет передаваться клиенту.
Для решения этой задачи в ASP.NET Web Forms используется следующий подход. Страница - классPage представляет собой контейнер элементов управления, который содержит внутри себя все элементы управления, которые отображаются пользователю. Каждый элемент управления - класс Control также является контейнером для других элементов управления. Таким образом, элементы управления могут быть вложены друг в друга, в связи с чем выстраивается иерархия элементов управления страницы. Например, давайте рассмотрим следующую ASPX-разметку для страницы. Как видно из примера, на форме размещаются два элемента управления Panel, которые имеют вложенные элементы управления.
Иерархически структуру элементов управления для данной формы можно представить следующим образом:
Рисунок 4.6 – Иерархия элементов управления
Аналогичным образом уровень вложенности может быть еще более глубоким.
Для того чтобы стало возможным выстраивать подобную иерархию элементов управления на странице, страница Page и элементы управления Control имеют в составе своих свойств коллекцию Controls, которая как раз и содержит ссылки на дочерние элементы управления. Например, если требуется получить доступ к элементам управления на странице, а также вложенным элементам управления, то можно использовать следующий код.
Таким образом, любой элемент управления ASP.NET Web Forms имеет в своем составе коллекцию Controls, которая содержит набор дочерних элементов управления. Однако, если с контейнерными элементами управления такими как Panel, которые по смыслу должны содержать дочерние элементы управления вопросов не возникает, то как быть с обычными элементами управления, например, с кнопкой Button, меткой Label и прочими элементами управления, которые не подразумевают по смыслу наличие дочерних элементов управления? В этом случае вопрос решается достаточно просто – если элемент управления по смыслу не подразумевает наличие дочерних элементов управления, то содержимое его коллекции Controls просто игнорируется. Решение о том, нужно ли игнорировать коллекцию Controls у элемента управления принимает сам элемент управления. Этот аспект тесно связан с концепцией генерации HTML-кода.
Процесс генерации HTML-кода страницы заключается в следующем. Страница ASP.NET Web Forms (класс Page) содержит набор методов "Render", которые выполняют генерацию HTML-кода. При вызове метода, генерируется общий каркас страницы – теги "html", "head", "body" и др. После этого на странице начинается последовательный перебор элементов управления из коллекции Controls. Для каждого элемента управления, который содержится в коллекции Controls, вызывается метод "RenderControl". Этот метод реализован для каждого элемента управления в зависимости от его логики. В процессе исполнения этого метода генерируется HTML-код этого элемента управления. Если по смыслу подразумевается, что элемент управления может содержать дочерние элементы управления, то в процессе исполнения метода "RenderControl" элемент управления самостоятельно обращается к коллекции Controls, получает список дочерних элементов управления и вызывает метод "RenderControl" у дочерних элементов управления. Если обработка дочерних элементов управления не требуется, то коллекция Controls просто игнорируется. Таким образом, для страницы выполняется рекурсивная генерация HTML-кода, при котором каждый элемент управления сам генерирует собственный HTML-код. Схематически этот процесс можно представить следующим образом.
Рисунок 4.7 – Формирование HTML- кода страницы Page
Таким образом, при генерации страницы все элементы управления самостоятельно генерируют свой HTML-код и передают его своему контейнеру, чтобы тот смог сформировать общий HTML-код.
Как уже упоминалось, разработчик веб-приложения может самостоятельно разрабатывать собственные элементы управления, если функциональности стандартных элементов управления ему недостаточно. Для разработки собственных элементов управления существуют два подхода:
- создание пользовательских элементов управления (user control);
- создание специальных серверных элементов управления (custom server control).
Разработка пользовательских элементов управления (user control) очень похожа на разработку самой страницы - веб-формы. Пользовательский элемент управления является небольшой частью страницы, которая может содержать статический HTML-код и серверные другие элементы управления. Преимуществом такого элемента управления является то, что создав такой элемент управления, его можно многократно использовать на множестве страниц. При этом процесс разработки элемента управления очень похож на процесс разработки самой страницы, а для того, чтобы произошли изменения на всех страницах, использующих данный элемент управления, достаточно всего лишь изменить сам элемент управления. Обычно данный тип элементов управления используется для вынесения общих элементов страницы, которые используются многократно на разных страницах. В этом случае логика концентрируется в элементе управления, а на странице делается лишь ссылка на этот элемент управления.
Для создания пользовательского элемента управления нужно добавить его в состав проекта, используя элемент меню "Add – New Item", в котором необходимо выбрать тип содержимого "Web User Control".
Рисунок 4.8 – Cоздание пользовательского элемента управления
При создании пользовательского элемента управления по умолчанию создаются два файла – файл разметки (ascx) и файл кода (cs). Файл разметки по своей структуре очень напоминает файл разметки веб-формы (aspx) – в нем также присутствует управляющая директива Control и сама разметка. Содержимое файла разметки будет иметь следующий вид.
При построении пользовательского элемента управления используют те же подходы, что и при разработке web-страниц. В рамках элемента управления доступны те же глобальные объекты HttpContext, Application, Session, ViewState, Request,Response, Server и т.д.
В остальном разработка пользовательского элемента управления ничем не отличается от разработки веб-формы ASP.NET Web Forms.
После создания собственного элемента управления его необходимо зарегистрировать на странице. В противном случае его невозможно добавить на страницу. Для регистрации элемента управления на страницу добавляется директива Register, которая содержит все необходимые параметры. Для регистрации пользовательского элемента управления директива Register должна содержать следующий набор параметров:
Таблица 4.2 – Атрибуты директивы Register для регистрации пользовательского элемента управления
Наименование параметра | Описание |
Src | путь до элемента управления; |
TagPrefix | префикс, который будет использоваться на странице для размещения элемента управления; |
TagName | имя тега, который будет использоваться на странице для размещения элемента управления. |
Таким образом, регистрация и размещения пользовательского элемента управления на странице может выглядеть следующим образом.
Другим подходом к созданию собственных элементов управления является создание специальных серверных элементов управления. Специальными серверными элементами управления являются классы .NET Framework, которые программным образом генерируют собственный HTML-код. В отличии от пользовательских элементов управления, которые разрабатываются подобно веб-формам, серверные элементы управления всегда предварительно компилируются в сборки. В зависимости от того, какой код будет написан для элемента управления, можно разработать содержимое "с нуля" или унаследовать внешний вид и поведение от существующего элемента, усовершенствовав его функциональные возможности.
Для реализации элемента управления необходимо прямо или косвенно унаследовать собственный элемент управления от класса System.Web.UI.Control. КлассControl предоставляет свойства и методы, общие для всех элементов управления, такие как ID,ViewState и Controls. При создании класса-наследника от Control в классе будет присутствовать как минимум один метод – метод Render. Этот метод имеет единственный параметр типа HtmlTextWriter. При помощи этого параметра можно получить доступ к выходному потоку, который пересылается пользователю. Именно при помощи объекта HtmlTextWriter осуществляется генерация HTML-кода элемента управления, который будет передан пользователю при использовании этого элемента управления на странице.
Объект HtmlTextWriter имеет набор методов для генерации HTML кода. Каждый из этих методов записывает HTML-код в выходной поток, который впоследствии будет передан пользователю.
- Методы AddAttribute() и AddStyleAttribute() позволяют добавить любой HTML-атрибут и его значение в выходной поток. Этот атрибут будет применен в следующем HTML-теге, который будет сгенерирован для клиента. Вместо использования явного имени атрибута можно воспользоваться заранее заданным перечислением HtmlTextWriterAttribte (для AddAttribute) или HtmlTextWriterStyle (для AddStyleAttribute);
- Метод RenderBeginTag() позволяет записать открывающий HTML-тег в выходной поток. Вместо задания явного имени тега можно воспользоваться перечислением HtmlTextWriterTag;
- Метод RenderEndTag() позволяет записать закрывающий HTML-тег в выходной поток, соответствующий открытому HTML-тегу (с помощью метода RenderBeginTag). Имя HTML-тега указывать не нужно;
- Метод WriteBeginTag() аналогичен методу RenderBeginTag(), за тем исключением, что WriteBeginTag() не записывает закрывающую угловую скобку (">"). Это позволяет дополнить текущий HTML-тег дополнительными атрибутами;
- Метод WriteAttribute() позволяет записать HTML-атрибут для HTML-тега, открытого при помощи метода WriteBeginTag;
- Метод WriteEndTag() позволяет записать закрывающую угловую скобку (">") для HTML-тега, который был открыт с помощью метода WriteBeginTag().
-
Например, элемент управления, отображающий гиперссылку на странице, может иметь следующий программный код для генерации HTML-кода на странице.
Специальные серверные элементы управления также необходимо зарегистрировать для использования. Для этого также используется директива Register. Однако, в отличии от пользовательских элементов управления, при регистрации специального серверного элемента управления используется следующий набор параметров:
Таблица 4.3 – Параметры директивы Register для регистрации специального серверного элемента управления
Наименование параметра | Описание |
Namespace | пространство имен, в котором расположены объекты, являющиеся элементами управления; |
Assembly | имя сборки, в которой располагаются элементы управления (если элемент управления расположен в другой сборке); |
TagPrefix | префикс, который будет использоваться на странице для размещения элемента управления. |
Параметр TagName не указывается при регистрации специальных серверных элементов управления, а именем тега служит имя класса, реализующего элемент управления. Использование специального серверного элемента управления на странице может выглядеть следующим образом.
Кроме того, специальные серверные элементы управления можно зарегистрировать в конфигурационном файле. Это может быть удобно, когда элемент управления используется на множестве страниц – в этом случае использование директивы Register может излишне "перегружать" ASPX-код страницы.
Пример конфигурационного файла приведен ниже.
Таким образом, элементы управления являются важным механизмом платформы ASP.NET Web Forms и при необходимости могут быть доработаны веб-разработчиком в зависимости от его нужд.
Элементы управления являются одним из наиболее важных механизмов ASP.NET Web Forms. Каждый элемент управления самостоятельно генерирует свой HTML-код. Страница и любой элемент управления является контейнером для любых элементов управления – так выстраивается иерархия элементов управления. Генерация кода HTML осуществляется рекурсивно. Существует два способа создания собственных элементов управления – пользовательские элементы управления и специальные серверные элементы управления. Разработка пользовательских элементов управления похожа на разработку веб-форм, а разработка специальных серверных элементов управления сводится к разработке собственного класса и реализации логики генерации HTML-кода. Для использования собственных элементов управления их необходимо зарегистрировать. Для этих целей используется либо директива Register, которая размещается в разметке ASPX, либо конфигурационный файл.
4.5 Модель подій та життєвий цикл сторінок
Обработка запроса и генерация страницы большой и сложный процесс, который происходит на стороне сервера. При обработке запроса в каждый момент времени сервер выполняет различные действия, которые в общем случае незаметны для пользователя приложения и разработчика. Зачастую для разработчика нет необходимости знать о процессах, которые происходят в рамках среды исполнения. Однако при реализации некоторых механизмов может потребоваться вмешаться в процесс обработки запроса. Например, это может быть необходимо, когда разрабатывается собственная система безопасности или реализуется сложный механизм кэширования страницы. В этом случае нужно каким-то образом вмешаться в процесс разработки и запустить собственный код. Для этих целей в ASP.NET существует модель событий, которая позволяет это сделать. В рамках этой модели существуют предопределенные события, которые запускаются каждый раз при обработке запроса от клиента в строго определенные моменты времени. Все события в модели событий ASP.NET можно разделить на два больших типа:
- События страницы - исполняются каждый раз при обработке обращения к странице;
- Глобальные события– исполняются в момент запуска или остановки приложения
Рассмотрим механизм работы событий ASP.NET Web Forms, которые генерируются при каждом обращении к странице. Эти события можно разделить на группы, в зависимости от времени исполнения:
- События, выполняющиеся в момент подготовки к обработке запроса;
- События, выполняющиеся перед генерацией результата - кода HTML;
- События, выполняющиеся после генерации результата.
Первый тип событий необходим для отслеживания момента подготовки объектов страницы, инициализации ее структуры и формирования общей инфраструктуры. Подписавшись на такие события можно инициализировать собственные объекты, необходимые для обработки запроса.
После обработки таких событий происходит генерация событий, выполняющихся непосредственно перед генерацией кода HTML. К событиям этой группы относятся такие события как аутентификация и авторизация пользователя, опрос кэша на наличие данной страницы, восстановление состояния и др. Эти события позволяют выполнить собственный код до генерации результата, который будет передан пользователю.
После генерации кода HTML выполняются события, которые позволяют выполнить заключительные действия после обработки запроса. Например, при обработке этих запросов можно сохранить результат в кэше, сохранить состояние страницы или освободить память от ранее созданных объектов.
В целом процесс генерации страницы можно представить следующим образом (рис4.9).
Давайте более подробно рассмотрим этапы обработки страницы: