GrabDuck

Более чистая HTML-разметка в ASP.NET 4 Web Forms

:

imageЭто шестнадцатая статья из серии, посвященной предстоящему выходу VS 2010 и .NET 4.

Сегодняшний пост первый из серии, рассказывающий о важных изменениях, которые мы произвели с Web Forms в ASP.NET 4 для генерации чистой, соответствующей стандартам CSS-дружественной разметки. Сегодня я расскажу о проделанной нами работе, для предоставления лучшего контроля над атрибутом “ID”, генерируемый серверными элементами управления для клиента.

Генерация чистой, соответствующей стандартам CSS-дружественной разметки


Одной из самых распространенных жалоб разработчиков была невозможность генерировать нормальную верстку для серверных элементов управления в ASP.NET Web Forms. Вот список конкретных проблем в предыдущих версия ASP.NET:
  • Авто-генерирование атрибута ID в HTML делает сложным работу с JavaScript и CSS.
  • Использование таблиц вместо семантической разметки для некоторых элементов управления (к примеру asp:menu), что безобразно для стилизации.
  • Некоторые элементы управления генерировали строчные стили, даже когда не было явно указано никаких свойств стилей.
  • ViewState часто был достаточно большим, что далеко от идеала.

ASP.NET 4 предоставляет улучшенную поддержку построения соответствующую стандартам страницы прямо из коробки. Теперь, встроенный серверный элемент управления <asp:> в ASP.NET 4 генерирует более чистую разметку и поддерживает CSS стилизацию, что избавляет от всех вышеперечисленных проблем.

Совместимость разметки во время обновления существующих ASP.NET Web Forms приложений


Частым вопросом, который задают люди, когда слышат о более чистой разметке, появившейся в ASP.NET 4 – “Замечательно, а что теперь будет с моими существующими приложениями? Данные нововведения все сломают, когда я обновлю проект?”

Чтобы вы были уверенны о неизменности верстки и стилизации в существующих ASP.NET Web Forms приложениях, мы добавили конфигурационный флаг – controlRenderingCompatbilityVersion, в web.config, который позволяет вам решить, какую версию генератора разметки использовать:

image

Когда флаг controlRenderingCompatbilityVersion установлен в “3.5”, ваше приложение и серверные элементы управления по умолчанию отрисовывают разметку соответствующую.NET 3.5. Когда флаг controlRenderingCompatbilityVersion установлен в “4.0”, ваше приложение и серверные элементы управления генерируют семантическую разметку, соответствующую стандарту XHTML 1.1, более чистые клиентские ID, а также отсутствуют посторонние строчные стили.

По умолчанию, данный флаг равен 4.0 для всех новых ASP.NET Web Forms приложений, построенных с использованием ASP.NET 4. Для всех других, более ранних приложений, которые обновляются с помощью VS 2010 мы автоматически устанавливаем флаг controlRenderingCompatbilityVersion в 3.5. Позже, вы с легкостью сможете изменить его значение, как на уровне всего приложения, так и в файле web.config отдельно для каждой страницы или для всей директории.

Клиентский ID


Возможность иметь чистый, предсказуемый атрибут ID у генерируемого HTML элемента – это то, что просили разработчики долгое время для Web Forms (значения ID, типа “ctl00_ContentPlaceholder1_ListView1_ctrl0_Label1” не особо популярны). Обладая контролем над значением ID, вам становится проще писать JavaScript, использовать CSS, а также уменьшить количество разметки на больших страницах.
Новое свойство для элементов управления ClientIDMode

ASP.NET 4 поддерживает новое свойство ClientIdMode в базовом классе Control. Свойство ClientIdMode указвает, как элемент управления должен генерировать клиентский ID. Свойство ClientIdMode поддерживает четыре возможных значения:
  • AutoID – генерирует по принципу .NET 3.5 (автогенерируемый ID до сих пор добавляет префикс ctrl00 для совместимости)
  • Predictable (по умолчанию) – обрезает “ctl00” у строки ID и, если это список или контейнер, то добавляет дочерним элементам родительский ID (id=”ParentControl_ChildControl”)
  • Static – дает полный контроль над именованием элемента управления разработчику, в не зависимости что он укажет для ID, все будет выведено в результат.
  • Inherit – говорит элементу управления использовать режим именования родительского элемента управления

Свойство ClientIDMode может быть установлено напрямую любому элементу управления или в контейнере и тогда внутренние элементы будут с унаследованными настройками:

image

Или оно может быть задано на уровне всей страницы, используя директивы <%@ Page %> или <%@ Control %>, в данном случае элементы управления внутри страницы или пользовательского элемента управления наследую настройки и могут опционально их перегружать.

image

Или его можно установить в web.config приложения, в данном случае страницы в приложении унаследуют настройки и, так же, могут  перегрузить их.

image

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

Пример: использование свойства ClientIdMode для не списковых элементов управления


Давайте взглянем, как вы можете использовать новой свойство ClientIdMode для элементов управления на странице, задавая “ID”. Для демонстрирования мы создадим простую страницу, назовем её “SingleControlExample.aspx”, которая основана на master-page “Site.Master”, и содержит один элемент <asp:label> с ID “Message”, находящийся в <asp:content> с именем “MainContent”:

image

В нашем code-behind файле добавим простой код, как показано ниже, для задания текста Label динамически:

image

Если мы запускаем приложение, используя ASP.NET 3.5 или мы настроили ASP.NET 4 приложение использовать отрисовку с версии 3.5, или установили ClientIdMode=AutoID, тогда сгенерированная разметка, отосланная клиенту, будет выглядеть следующим образом:

image

ID является уникальным, что хорошо, но уродливым из-за “ctl100” префикса, что не особо радует.

Генерация разметки, когда ClientIdModel установлен в “Predictable”

С ASP.NET 4, серверные элементы управления по умолчанию генерируются, используя ClientIdMode=”Predictable”. Это позволяет быть уверенным, что все значения ID уникальны и на странице отсутствуют конфликты, в тоже время ID менее многословный и более предсказуемый. Это означает, что сгенерированная разметка элемента управления <asp:label> по умолчанию, в ASP.NET 4, будет выглядеть следующим образом:

image

Обратите внимание, префикс “ct100” исчез. Так как элемент управления “Message” находится в контейнере “MainContent”, по умолчанию, его ID будет снабжен префиксом “MainContent_Message” для предотвращения потенциальных коллизий с другими элементами управления на странице.

Генерация разметки, когда ClientIdModel установлен в “Static”

Иногда вы не хотите, чтобы значения ID не были вложено иерархическими, а просто шли с тем значением, которое мы желаем установить:

image

Все это дает нам возможность полностью контролировать значение клиентского ID элементов управления.

Пример: использование свойства ClientIdMode для списков связанных с данными


Связанные с данными списки или гриды исторически было сложно использовать или настраивать стили, когда работали с автоматически генерируемыми ID в Web Forms. Теперь давайте взглянем на сценарий, где мы настроим ID для ListView в ASP.NET 4.

Ниже представлен фрагмент кода ListView, который отображает содержимое из связанной коллекции, в нашем случае аэропортов:

image

Далее мы можем написать код в code-behind файле для динамического связывания списка аэропортов с ListView:

image

Во время выполнения список по умолчанию будет выглядеть, как <ul>. Заметьте, что <ul> и <li> элементы в ListView не являются серверными элементами управления, и для них отсутствует ID в разметке:

image

Добавляем клиентский ID для каждой строчки

Давайте представим, что нам нужно добавить клиентский ID, для программного доступа к каждому <li>, через JavaScript. Мы хотим, чтобы данные ID были уникальными, предсказуемыми и опознаваемыми.

Нужно пометить каждый <li> в шаблоне, как серверный элемент управления, задав ему атрибут runat=”server” и дать каждому id “airport”:

image

По умолчанию ASP.NET 4 сгенерирует чистый ID, как показано ниже, никаких ctl001 не будет:

image

Используем свойство ClientIDRowSuffix

Наш выше представленный шаблон теперь генерирует уникальные ID для каждого <li> элемента, но если мы будем программно обращаться к нему через JavaScript, то хотели бы, чтобы ID содержал код аэропорта. Хорошие новости – это можно очень просто сделать, используя новое свойство ClientIDRowSuffix в связанном элементе управления ASP.NET 4:

Для этого, задаем свойству ClientIDRowSuffix значение “Code” в нашем ListView. Оно указывает ListView использовать связанное свойство “Code” с нашего класса Airport, во время генерации ID:

image

А теперь, вместо суффикса “1” или “2”, мы получим значение Airport.Code (_CLE, _CAK, _PDX):

image

Вы можете использовать ClientIDRowSuffix в любых других элементов, у которых присутствует связь с данными, например GridView.

Итоги


ASP.NET позволяет вам генерировать гораздо более чистую HTML разметку для серверных элементов управления.

В следующей статье я поведаю о других нововведениях, затронувших разметку в ASP.NET 4.