Лабораторная работа №7 Персонализация приложений с помощью пользовательских профилей и тем

advertisement
Лабораторная работа №7
Персонализация приложений с помощью
пользовательских профилей и тем
1. Цель работы
Целью работы является теоретическое ознакомление с персонализацией страниц,
приобретение практических навыков в подключении профилей пользователей с
использованием API персонализации платформы ASP.NET 2.0, а также в применении темы
оформления ASP.NET 2.0 для модификации внешнего вида Web-сайта
2. Состав рабочего места
2.1. Оборудование: IBM-совместимый персональный компьютер (ПК).
2.2. Программное обеспечение: операционная система Windows, интегрированная
оболочка Visual Studio. Провайдер персонализации SQL Server при поддержке ASP.NET
2.0.
Сценарий
Попытаемся создать в компании Adventure Works индивидуальный шаблон
оформления для этого портала.
Сперва необходимо добавить несколько Web Parts на домашнюю страницу, которые
дадут возможность пользователям находить других работников организации.
Принимая во внимание отзывы заинтересованных сторон, необходимо выбрать
соответствующий уровень персонализации, предложенный конечному пользователю, и
новые темы оформления, соответствующие корпоративному стилю.
Требования:
Вам необходимо создать портал, в котором каждый пользователь сможет задать внешний
вид каждой страницы.
Пользователи должны иметь возможность выбрать какие Web-частиони хотят поместить
на странице, и как они должны отображаться на ней.
При первом посещении портала пользователи должны иметь возможность задать свою
цветовую схему, выбрав из доступных тем.
После начальной настройки, при каждом последующем посещении, пользователь должен
видеть выбранную цветовую схему.
Решение:
Для решения поставленных задач будем использовать темы оформления.
Рисунок ниже показывает образец приложения, которое будет создано в результате
выполнения лабораторной работы.
3. Краткие теоретические сведения
Персонализация страниц
Широкие возможности персонализации требуются далеко не каждому приложению
ASP.NET. Включив в состав приложения персонализационный слой, вы можете сделать
его страницы более дружественными пользователю, удобными и привлекательными. Для
одних приложений персонализация — всего лишь дополнительное удобство, без которого
вполне можно было бы обойтись, тогда как для других, таких как порталы и электронные
торговые центры, это ключевая функция, без которой они не могут функционировать
должным образом. ASP.NET 2.0 поддерживает две взаимодополняющие формы
персонализации: пользовательские профили и темы.
Подсистема пользовательских профилей обеспечивает возможность постоянного
хранения структурированных данных, а для доступа к ней используется типизированный
дружественный программисту API. Приложение определяет собственную модель
персонализированных данных, и исполняющая среда ASP.NET делает остальное, выполняя
синтаксический разбор определения этой модели и компилируя результирующий класс.
Каждая переменная-член персонализационного класса соответствует элементу
информации, связанной с конкретным пользователем. Загрузка и сохранение
персонализированных данных выполняются прозрачно для конечного пользователя и не
требуют от автора страницы глубокого знания внутренней архитектуры подсистемы
персонализации.
Тема определяет настраиваемый набор стилей и визуальных атрибутов, назначаемых
элементам сайта. К числу таких элементов относятся таблицы стилей страниц,
изображения, шаблоны, а также свойства элементов управления. Тема объединяет все
визуальные стили всех настраиваемых элементов страницы, так что ее можно назвать чемто вроде супер-CSS. Мы подробно рассмотрим вопрос о темах далее.
Создание пользовательского профиля
На высшем уровне абстракции пользовательский профиль — это набор свойств,
которые исполняющая среда ASP.NET 2.0 сгруппировала в динамически сгенерированный
класс. Данные профиля сохраняются в постоянной памяти для каждого пользователя в
отдельности и хранятся там до тех пор, пока не будут удалены кем-либо, имеющим
административные привилегии. При выполнении страницы ASP.NET динамически создает
объект профиля, содержащий типизированные свойства, определенные вами в модели
данных. Этот объект добавляется затем в текущий объект HttpContext и делается
доступным страницам через свойство Profile.
Место хранения данных профиля скрыто от пользователя и даже, до некоторой
степени, от программиста. Пользователю просто ни к чему знать, как и где хранятся эти
данные, а программисту обычно достаточно указать тип провайдера профилей, который он
желает использовать. Каждый провайдер использует свое хранилище данных; встроенные
провайдеры хранят их в базе данных Microsoft SQL Server, а пользовательские могут
использовать и другие хранилища.
Определение модели данных
Для того чтобы воспользоваться API профилей ASP.NET 2.0, нужно первым делом
решить, какая структура данных профиля требуется вашему приложению. Эту модель
данных вы описываете в файле web.config в формате XML, определяя свойства и соответствующие им типы .NET Framework.
Каждое свойство задается в виде пары имя-значение в подразделе <properties>
раздела <profile> конфигурационного файла. Раздел <profile>, содержащий также
информацию о провайдере, в свою очередь, является подразделом <system.web>. Приведем
пример определения пользовательского профиля, состоящего из двух строковых свойств,
BackColor и ForeColor.
<profile>
<properties>
<add name= "BackColor" type="string" />
<add name="ForeColor" type="string" />
</properties>
</profile>
Все свойства, определенные с использованием тэга <add>, являются членами объекта
динамически созданного класса, доступного как часть HTTP-контекста страницы. В
атрибуте type задается тип свойства. Если он не задан, по умолчанию свойству назначается
тип System.String. Допускается использование любого типа данных, поддерживаемого
общеязыковой средой. В таблице ниже перечислены допустимые атрибуты элемента
<add>. Обязательным является только атрибут name.
Атрибут
Описание
allowAnonymous
Определяет, разрешено ли сохранение значений
свойства для анонимных пользователей. По
умолчанию данный атрибут имеет значение false
defaultValue
Значение свойства по умолчанию
customProviderData
Данные для пользовательского провайдера
профилей
name
Имя свойства
provider
Имя провайдера, используемого для чтения и
записи значения свойства
readOnly
Определяет, будет ли значение свойства доступным
только для чтения. По умолчанию данный атрибут
имеет значение false
serializeAs
Указывает, как следует сериализовать значение
свойства. Допустимыми установками являются
Xml, Binary, String и ProviderSpecific
type
Тип свойства, определенный в .NET Framework. По
умолчанию string
Табл.1.Описание атрибутов элемента <add>
Разработчику приложения вовсе не обязательно знать, как осуществляется запись
информации в хранилище персонализационных данных и как она оттуда считывается.
Однако само это хранилище разработчику необходимо создать и сконфигурировать. Далее
мы подробно обсудим этот вопрос. А пока взгляните на фрагмент кода, который позволит
вам составить представление о генерируемом ASP.NET классе ProfileCommon, который
реализует модель данных профиля:
namespace ASP
{
public class ProfileCommon : ProfileBase
{
public virtual string BackColor
{
get {(string) GetPropertyValue("BackColor");}
set {SetPropertyValue("BackColor", value);}
}
public virtual string ForeColor
{
get {(string) GetPropertyValue("ForeColor");}
set {SetPropertyValue("ForeColor", value);}
}
public virtual ProfileCommon GetProfile(string username)
{
object о = ProfileBase.Create(username);
return (ProfileCommon) o;
}
}
}
Экземпляр этого класса связывается со свойством Profile класса страницы, а доступ к
нему осуществляется следующим образом:
// Использование свойства BackColor для установки цвета фона страницы
theBody.Attributes["bgcolor"] = Profile.BackColor;
Несмотря на то, что ASP.NET 2.0 поддерживает и профили анонимных пользователей,
между учетными записями пользователей и информацией их профилей существует тесная
взаимосвязь. Мы еще поговорим об этом подробнее, а пока можно лишь обратить ваше
внимание на данный факт.
Использование коллекций
В приведенном выше примере в качестве элемента данных профиля фигурировало
одиночное скалярное значение. Однако механизм персонализации позволяет использовать и
более сложные типы данных, такие как коллекции и пользовательские типы. Например, в
следующем фрагменте конфигурационного файла свойство Links определено как коллекция
строк:
<properties>
<add name="Links"
type="System.Collections.Specialized.StringCollection" />
</properties>
Чтобы в хранилище можно было записывать значения, не являющиеся скалярными,
такие как коллекции или массивы, их необходимо сериализировать. Способ сериализации
задается с помощью атрибута serialize As, принимающего значения String, Xml, Binary и
ProviderSpecific. Если атрибут serializeAs не задан, используется установка String. Как
правило, сериализация коллекций осуществляется путем их преобразования в двоичный
формат или в формат XML.
Пользовательские типы данных
Свойство пользовательского профиля не обязательно должно относиться к одному из
встроенных типов данных — тип может быть и пользовательским, нужно только указать, как
должна осуществляться его сериализация. Реализуя пользовательский тип, вы пишете класс
и компилируете его, после чего добавляете имя полученной сборки к информации о типе
свойства профиля:
<properties>
<add name="ShoppingCart"
type="My.Namespace.DataContainer, MyAssembly" serializeAs="Binary" />
</properties>
Чтобы сборка, содержащая пользовательский тип, была доступна приложению
ASP.NET, ее следует поместить в папку Bin этого приложения или зарегистрировать в
глобальном кэше сборок (GAC).
Работа с пользовательским профилем
Включение и отключение функции поддержки профилей осуществляется с помощью
атрибута enabled раздела <profile> файла web.config. Если этот атрибут имеет значение true
(а таковым оно является по умолчанию), функция персонализации включена для всех
страниц. Когда данная функция отключена, страницы не имеют свойства Profile.
Создание базы данных пользовательских профилей
Итак, вы уже знаете, что каждый профиль содержит персонализационные данные,
связанные с одним конкретным пользователем, и сохраняется в постоянной памяти.
Присвоив атрибуту enabled конфигурационного раздела <profile> значение true, вы
активизируете подсистему поддержки пользовательских профилей, но прежде чем ее можно
будет использовать, необходимо выполнить еще одну задачу — создать инфраструктуру
хранения данных.
Это можно сделать с помощью административного средства Web Site Administration
Tool (WSAT), входящего в состав ASP.NET 2.0 и полностью интегрированного в Visual
Studio. Напомню, что оно вызывается командой WebsiteASPNET Configuration.
С помощью данного средства вы можете создать базу данных SQL Server 2005,
используемую по умолчанию для хранения данных профилей, — ее файл, aspnetdb.mdf,
должен находиться в папке AppData приложения. Схема этой базы данных (в том числе
набор и структура таблиц) фиксирована. Здесь же содержатся таблицы, предназначенные для
хранения информации о членстве и ролях. Указанная информация необходима, в частности,
и подсистеме персонализации, поскольку данные пользовательских профилей по
определению связаны с пользователями. Идентификаторы пользователей (будь то
идентификаторы учетных записей Windows или учетных записей, поддерживаемых
конкретным приложением) используются для индексирования данных их профилей.
Пользовательские профили не имеют срока давности и хранятся «вечно», то есть до тех
пор, пока администратор Web-сайта не удалит их по каким-нибудь соображениям.
Разумеется, WSAT — не единственное средство, с помощью которого можно
сформировать инфраструктуру для хранения данных профилей. Например, если вашему
приложению необходим пользовательский провайдер персонализации, то подготовку этой
инфраструктуры (будь то таблица SQL Server, база данных Oracle или иное хранилище)
должна осуществлять программа его инсталляции. Об установке и конфигурировании
провайдеров профилей речь пойдет в следующем разделе.
Работа с анонимными пользователями
Хотя функция пользовательских профилей предназначена, прежде всего, для
сохранения информации аутентифицированных пользователей, существует возможность
сохранять такую информацию и для анонимных пользователей. Однако в таком случае
должно выполняться несколько дополнительных требований. В частности, необходимо
включить функцию идентификации анонимных пользователей, которая по умолчанию
отключена:
<anonymousIdentification enabled="true" />
Эта новая функция ASP.NET 2.0 позволяет присваивать уникальные идентификаторы
неаутентифицированным пользователям, чтобы в контексте персонализации их можно было
интерпретировать как зарегистрированных пользователей.
Кроме того, в модели данных профиля вам необходимо пометить атрибутом
allowAnonymous те свойства, которые должны поддерживаться для анонимных пользователей. Например, в приведенном ниже фрагменте кода анонимным пользователям
разрешается задавать цвет фона, но не добавлять новые ссылки.
<anonymousIdentification enabled="true" />
<profile enabled="true">
<properties>
<add name="BackColor"
type="System.D rawi ng.Colo r" allowAnonymous="true" />
<add name="Links"
type="System.Collections.Specialized.StringCollection"
serializeAs="Xml" />
</properties>
</profile>
Доступ к свойствам профиля
Перед началом цикла обработки запроса свойству Profile страницы присваивается
экземпляр динамически созданного класса, представляющего определенный в файле
web.config пользовательский профиль. При первой загрузке страницы свойства профиля
получают значения по умолчанию (если таковые имеются) или инициализируются пустыми
объектами, но эти свойства никогда не бывают равными null. Если свойство имеет
пользовательский тип или является коллекцией, как свойство Links в приведенном выше
примере, декларативно задать для него значение по умолчанию вы не можете. (Тем не менее
во время выполнения свойство Links будет равным не null, а пустой коллекции). А как
задать значение свойства программным способом?
Свойства, для которых значения по умолчанию не заданы декларативно, можно
инициализировать в обработчике события Page_Load (разумеется, сначала убедившись, что
страница не обрабатывает возврат формы):
if (!IsPostBack)
{
// Включаем в состав коллекции Links несколько предопределенных ссылок
if (Profile.Links.Count == 0)
{
Profile.Links.Add("http://www.contoso.com");
Profile.Links.Add("http://www.northwind.com");
}
}
Теперь представьте себе страницу, подобную показанной на рис. 1, где на отдельной
панели выводится список избранных ссылок. Пользователь может изменять этот список и
настраивать несколько визуальных атрибутов, в частности, цвета и шрифт.
Структура пользовательского профиля, используемого кодом этой страницы,
описывается следующей XML-разметкой:
<profile enabled="true">
<properties>
<add name="BackColor" type="string" />
<add name="ForeColor" type="string" />
<add name="Links"
type="System.Collections.Specialized.StringCollection"/>
<group name="Font">
<add name="Name" type="string" />
<add name="SizeInPoints" type="int" defaultValue="12" />
</group>
</properties>
</profile>
Рис.1. Пример страницы
Благодаря поддержке профилей одна и та же страница у разных пользователей
выглядит по-разному.
Данные этого профиля используются для адаптации пользовательского интерфейса
страницы:
private void ApplyPagePersonalization()
{
// Устанавливаем цвета панели
InfoPanel.ForeColor = ColorTranslator.FromHtml(Profile.ForeColor);
InfoPanel.BackColor = ColorTranslator.FromHtml(Profile.BackColor);
// Устанавливаем шрифт панели
InfoPanel.Font.Name = Profile.Font.Name;
InfoPanel.Font.Size = FontUnit.Point(Profile.Font.SizeInPoints);
// Создаем ссылки
Favorites.Controls.Clear(),
if(Profile.Links.Count == 0)
Favorites.Controls.Add(new LiteralControl("No links available."));
else
foreach (object о in Profile.Links)
{
HyperLink h = new HyperLink ();
h.Text = o.ToString ();
h.NavigateUrl = o.ToString ();
Favorites.Cont rols.Add(h);
Favorites.Controls.Add(new LiteralControl("<br />"));
}
}
Метод ApplyPagePersonalization вызывается из обработчика события Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Инициализируем необходимым образом свойства профилей
}
ApplyPagePersonalization();
}
Инициализация — важный этап жизненного цикла страницы, но происходящее на
этом этапе всецело определяется нуждами конкретного приложения. В нашем примере при
первом обращении пользователя к странице цвета не задаются и гиперссылки не
определяются. Так как мы перебираем элементы коллекции в цикле, пустая коллекция
вполне подходит и никакая иная инициализация для нее не требуется. (Заметьте, что .NET
Framework обеспечивает создание экземпляров всех объектов, на которые в программе
имеются ссылки) А как насчет цветовых свойств? Если значение по умолчанию задано в
файле web.config, исполняющая среда использует его для инициализации соответствующего
свойства при первом обращении пользователя к странице; иначе необходимо позаботиться
об установке свойства в обработчике события Page_Load.
Когда обработка запроса завершается, содержимое объекта профиля сохраняется в
постоянной памяти и извлекается при следующем вызове страницы. Тогда уже все свойства
будут инициализированы, если только администратор сайта не удалит какие-либо данные.
Заметьте, что если пользователю позволено настраивать внешний вид и поведение
страницы, ему должен быть предоставлен для этой цели удобный интерфейс. Например, в
состав страницы, показанной на рис. 1, входит элемент управления MultiView, с помощью
которого при щелчке пользователем ссылки Click here to edit или Close происходит
переключение между основным режимом использования страницы и режимом
редактирования ее настроек.
ProfileModule подключается к двум событиям HTTP и вызывается дважды: после
авторизации запроса и перед завершением его выполнения. Если функция персонализации
отключена, данный модуль немедленно возвращает управление исполняющей среде; в противном случае он генерирует для приложения событие Personalize, а затем загружает
персонализационные данные из профиля текущего пользователя. Когда генерируется
событие Personalize, эти данные еще не загружены. Обработчик указанного события должен
содержаться в файле global.asax:
void Profile_Personalize(object sender, ProfileEventArgs e)
{
ProfileCommon profile = null;
// Если пользователь анонимный - выход
if (User == null) return;
// Определяем профиль с учётом роли пользователя. База данных
// профилей содержит по одной записи для каждой роли
if (User.IsInRole("Administrators"))
profile = (ProfileCommon) ProfileBase.Create("Administrator");
else if (User.IsInRole("Users"))
profile = (ProfileCommon) ProfileBase.CreateC'User");
else if (User.IsInRole("Guests"))
profile = (ProfileCommon) ProfileBase.Create("Guest");
// Делаем так, чтобы HTTP-модуль поддержки профилей
// использовал объект профиля THIS
if (profile != null) e.Profile = profile;
}
Нужно понимать, что роль слоя персонализации в приложении отнюдь не сводится к
предоставлению пользователям приятной возможности настроить его интерфейс по своему
вкусу. Это универсальное средство хранения информации, связанной с отдельными
пользователями, и не обязательно даже, чтобы информация была введена самими
пользователями.
Слой персонализации использует идентификатор текущего пользователя в качестве
ключа для извлечения необходимого набора данных. А как насчет ролей? Что если у вашего
приложения сотни пользователей с различными именами и все они используют всего две-три
разные группы установок, в зависимости от роли, исполняемой каждым из пользователей?
Имеет ли смысл хранить в базе данных сотни почти идентичных записей? Конечно, лучше
было бы сохранять наборы установок для ролей, но стандартная подсистема
пользовательских профилей не имеет о ролях ни малейшего представления. Вот почему
иногда возникает необходимость в обработке события Personalize или написании
собственного провайдера профиля.
В приведенном выше коде процесс создания объекта пользовательского профиля
переопределен так, чтобы этот объект создавался с учетом роли пользователя, а не его
имени. Статический метод Create класса ProfileBase принимает имя пользователя и создает
соответствующий экземпляр объекта профиля. ProfileCommon — имя динамически
создаваемого класса, представляющего пользовательский профиль.
Обработчик события Personalize получает данные профиля посредством класса
ProfileEventArgs, у которого имеется доступное для чтения и записи свойство с именем
Profile. Когда выполнение этого обработчика завершается, модуль HTTP, реализующий
функцию поддержки профилей, проверяет содержимое свойства Profile. Если его значением
является null, модуль продолжает свою работу обычным образом и создает объект профиля,
основываясь на идентификаторе пользователя. В противном случае модуль просто передает
странице в качестве объекта профиля текущее значение свойства Profile.
Перенос данных анонимных пользователей
Вы уже знаете, что анонимные пользователи могут сохранять и восстанавливать
данные персонализации, вводя свой уникальный идентификатор. Однако если пользователь,
до сих пор бывший анонимным, решит зарегистрироваться на сайте, с созданной для него
учетной записью нужно будет связать существующий профиль этого пользователя. Такой
перенос установок не происходит автоматически.
Когда к приложению подключается зарегистрированный пользователь, модуль
персонализации генерирует событие MigrateAnonymous, в обработчике которого можно
перенести в его профиль установки, заданные им ранее анонимно. Делается это так:
void Profile_MigrateAnonymous(object sender, ProfileMigrateEventArgs e)
{
// Загрузка профиля анонимного пользователя
ProfileCommon anonProfile;
anonProfile = Profile.GetProfile(e.AnonymousId);
// Перенос свойств в новый профиль
Profile.BackColor = anonProfile.BackColor;
}
Вы получаете профиль анонимного пользователя, извлекаете значения его свойств и
копируете их в профиль зарегистрированного пользователя.
Провайдеры профилей
В ASP.NET 2.0 API профилей состоит из двух независимых компонентов: слоя доступа
и слоя хранения.
Слой доступа реализует строго типизированную модель чтения и записи значений
свойств и управления идентификаторами пользователей. Он обеспечивает сохранение и
восстановление данных от имени текущего пользователя приложения.
Слой хранения с помощью специализированных провайдеров выполняет операции,
связанные с сохранением и восстановлением значений. В состав ASP.NET 2.0 входит
провайдер профилей, в качестве СУБД использующий MS SQL Server. Он записывает
данные в выбранное хранилище и отвечает за то, какой будет конечная схема этих данных.
Провайдер должен быть способен либо сериализовать объект данных (превратив его,
например, в текст XML-формата или двоичный объект), либо уметь извлечь из него
требуемую информацию. При необходимости провайдер профилей можно написать
самостоятельно.
Конфигурирование провайдеров профилей
Для каждой функции, реализуемой в соответствии с моделью провайдеров, должен
быть определен провайдер, используемый по умолчанию. Обычно он задается в атрибуте
defaultProvider того раздела конфигурационного файла, который связан с данной функцией.
В том случае, если он не задан, используемым по умолчанию считается первый из
перечисленных в этом разделе провайдеров.
Стандартный провайдер профилей ASP.NET 2.0 носит имя AspNetSqlProfileProvider.
Для хранения информации он использует базу данных MS SQL Server. Вот запись о его
регистрации в подразделе <providers> раздела <profile> конфигурационного файла
machine.config:
<profile>
<providers>
<add name="AspNetSqlProfileProvider"
connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider" />
</providers>
</profile>
Каждому зарегистрированному провайдеру соответствует свой узел <add> раздела
<providers>. Атрибуты name и type задаются для всех провайдеров, набор остальных
атрибутов зависит от типа конкретного провайдера. При желании в атрибуте description
можно задать текстовое описание провайдера.
Атрибут connectionStringName служит для определения строки подключения к базе
данных пользовательских профилей. Он содержит не строку подключения, а ее имя — сама
же строка зарегистрирована в другом месте конфигурационного файла. Например, очевидно,
что LocalSqlServer — это не строка подключения к удаленному или локальному экземпляру
SQL Server. Элемент с таким именем вы найдете в разделе <connectionStrings>, введенном в
ASP.NET 2.0 для того, чтобы все строки подключения можно было хранить централизованно
(этот раздел также находится в файле machine.config):
<connectionStrings>
<add name="LocalSqlServer" connectionString="data source=.\SQLEXPRESS;
Integrated Security=SSPI; AttachDBFilename=|DataDirectory|aspnetdb.mdf;
UserInstance=true" providerName="System.Data.SqlClient" />
</connectionStrings>
Как видите, данная строка подключения содержит ссылку на экземпляр SQL Server с
именем SQLEXPRESS и служит для подключения к базе данных aspnetdb.mdf, хранящейся в
разделе данных приложения — папке App_Data.
Пользовательские провайдеры профилей
Для разработки новых приложений вполне подходит встроенный провайдер профилей.
Однако в случае, если вы переносите на платформу ASP.NET 2.0 старое приложение ASP
или ASP.NET, данные которого хранятся в нереляционной форме или в СУБД, отличной от
SQL Server, этот провайдер вам не подойдет, и придется написать собственный провайдер
профилей.
Провайдер профилей, представляет собой прослойку кода между персонализационной
подсистемой и физическим хранилищем данных. Этот слой кода абстрагирует физические
характеристики хранилища данных и открывает доступ к его содержимому посредством
универсального набора свойств и методов. Пользовательский провайдер профилей
реализуется в виде класса, наследующего класс ProfileProvider.
<properties>
<add name="BackColor" type="string" provider="MyProvider" />
</properties>
Темы
В течение продолжительного времени CSS-стили помогали разработчикам сайтов
единообразно оформлять страницы. Но хотя выбор таблицы стилей можно осуществлять
программно на сервере, CSS по сути своей является клиентской технологией, изначально
предназначавшейся для применения обложек к HTML-элементам. А при разработке страниц
ASP.NET вы имеете дело преимущественно с серверными элементами управления.
Стили CSS можно использовать для оформления серверных элементов управления, но
это не лучшее средство для выполнения данной задачи. Главный недостаток CSS-стилей
заключается в том, что у элементов управления ASP.NET могут быть свойства, не имеющие
прямого соответствия среди стилевых свойств CSS. Внешний вид элемента управления
определяется целой группой ресурсов, среди которых изображения, строки, шаблоны,
разметка, сочетание нескольких CSS-стилей. Чтобы правильного применить обложки к
элементам управления ASP.NET, одних только CSS-файлов недостаточно. Для этой цели
используются темы ASP.NET.
Темы ASP.NET тесно связаны с темами Windows. Для задания темы достаточно
установить единственное свойство, и к выбранному объекту — будь то отдельный элемент
управления, страница или даже весь сайт — тут же будут применены все ее установки.
Понятие темы в ASP.NET
Разрабатывая страницу в ASP.NET 1.x, вы не можете позволить себе сконцентрироваться только на задачах, которые выполняются определенным набором элементов
управления, поскольку необходимо позаботиться и о внешнем виде этих элементов. В
простейшем случае внешний вид элемента управления определяется такими атрибутами, как
цвета, шрифт, рамка и изображение. Но чем сложнее элемент управления, тем больше у него
подобных атрибутов и тем больше времени вы уделяете его внешнему виду.
В ASP.NET 1.1 элемент управления DataGrid— один из самых популярных и наиболее
гибко настраиваемых элементов — предлагает на выбор целую галерею предопределенных
стилей, для чего используется его функция автоформатирования. Встроенные стили
элемента управления DataGrid реализованы в виде набора предопределенных установок,
которые Visual Studio применяет к нему во время разработки. Функция автоформатирования
существенно экономит время разработчика, позволяя выбирать стили визуальным способом.
Однако у нее есть два существенных недостатка. Во-первых, визуальные атрибуты попрежнему содержатся в .aspx-файле, из-за чего у страниц с богатым интерфейсом этот файл
становится нечитабельным, а во-вторых, список доступных форматов фиксирован, и его
нельзя ни изменить, ни расширить.
А ведь как хорошо было бы просто выбирать элементы управления на панели
элементов, размещать их на странице и связывать между собой, не беспокоясь о том, как они
будут выглядеть! В таком случае внешний вид каждого типа элементов управления можно
было бы определять в дополнительном файле проекта, предназначенном специально для
хранения визуальных атрибутов всех элементов. Изменения, вносимые в этот файл,
отражались бы на всех элементах управления сайта, и его интерфейс всегда оставался бы
согласованным. Исходные же файлы .aspx не содержали бы установок визуальных
атрибутов. Подумайте, как заманчиво все это звучит! А ведь я рассказал о существующей
функции ASP.NET 2.0 — о темах!
Тема — это набор обложек и связанных с ними файлов, таких как изображения и таблицы стилей; можно сказать, что это нечто вроде супер-CSS. Когда поддержка тем
включена, внешний вид всех элементов управления, связанных с определенной темой,
задается централизованно. Рассмотрим такую разметку:
<asp:Calendar ID="Calendar1" runat="server" />
Без использования тем определенный здесь календарь будет выглядеть по-спартански
скромно. Но стоит задать для него тему, и он станет красочным и привлекательным. Таким
образом, между контентом и форматированием страницы в систему ASPNET 2.0 проведена
четкая граница.
Термин
Обложка
(skin)
Определение
Именованный набор свойств и шаблонов, который
можно применить к любому количеству элементов
управления страницы. Обложка всегда связана с
определенным типом элементов управления
Таблица стилей CSS или серверная таблица стилей, которая может
(style sheet)
использоваться страницами сайта
Тема таблицы
Тема, используемая для абстрагирования свойств
стилей
(style sheet theme) элементов управления от самих этих элементов.
Элемент управления может переопределить такую
тему
Настроечная
Тема, используемая для абстрагирования свойств
тема
элементов управления от самих этих элементов. Она
(customization
theme)
переопределяет любые установки, заданные в
объявлении элемента управления и в определении
темы таблицы стилей
Табл.2.Определение основных терминов.
Структура темы
Физически тема представляет собой совокупность файлов и папок, хранящихся в одной
корневой папке, имя которой является именем этой темы. Темы могут быть глобальными и
локальными. Глобальные темы видимы всем приложениям, установленным на серверном
компьютере, а локальные — только тому приложению, в котором они определены. Каталоги
глобальных тем расположены по адресу:
%WINDOWS%\Microsoft.NETFramework\[вepcия]\ASP.NETClientFiles\Theme
В общем случае тема может содержать следующие ресурсы.
 Файлы CSS. Называемый также таблицей стилей, файл CSS содержит заданные в
специальном формате определения визуальных стилей, применяемых к элементам
HTML-документа. Он располагается в корневой папке темы. Старые Web-браузеры,
поддерживающие HTML версии 3.2 и более ранних версий, не применяют CSS-стили.
Текущую спецификацию стандарта CSS, поддерживаемого и постоянно обновляемого
консорциумом W3C, вы найдете на сайте последнего по адресу http://www.w3.org.
 Файлы обложек. Файл обложки содержит специфическую для заданной темы
разметку определенного набора элементов управления. Он состоит из последовательности определений элементов управления, содержащих значения большинства их
визуальных свойств, и шаблонов. Каждая обложка связана с конкретным типом
элементов управления и имеет уникальное имя. Для одного типа элементов управления
можно определить несколько обложек. Когда к элементу управления применяется
обложка, его разметка, содержащаяся в .aspx-файле страницы, модифицируется с
учетом установок обложки. Способ модификации элемента управления зависит от того,
какая именно тема к нему применяется — настроечная или тема таблицы стилей.
Файлы обложек содержатся в корневой папке темы.
 Файлы изображений. Элементы управления с богатым интерфейсом часто содержат
изображения. Так, в многостраничном элементе управления DataGrid они используются
на первой и последней страницах. Изображения, входящие в состав обложки, обычно
хранятся в подпапке Images папки ее темы (имя подпапки можно изменить, но оно
должно соответствовать имени, заданному в URL графических элементов обложки.)
 Шаблоны. Действие обложки элемента управления может распространяться не только
на его визуальные свойства, но и на структуру, при условии, что данный элемент
управления поддерживает шаблоны. Это позволило бы вам, меняя определение
шаблона в теме, изменять внутреннюю структуру элемента управления, не затрагивая,
однако, его программный интерфейс и поведение. Шаблон определяется как компонент
обложки элемента управления и хранится в файле обложки.
Перечисленные типы компонентов темы охватывают большую часть данных, которые вы
могли бы пожелать включить в ее состав. Однако этот набор типов не является замкнутым —
в папку темы можно добавить дополнительные вложенные папки, поместив в них любые
данные, имеющие смысл для элементов управления, к которым будет применяться данная
тема. Представьте, например, что у вас имеется специализированный элемент управления,
который выводит свой пользовательский интерфейс при помощи внешнего
пользовательского элемента управления ASP.NET (.ascx). Составляя обложку этого
специализированного элемента управления, вы можете указать в ней URL пользовательского
элемента управления — тогда последний станет частью темы и его можно будет хранить в
папке данной темы. Где именно, решать вам, но, пожалуй, неплохим выбором будет
создание для него подкаталога Controls. Мы еще вернемся к этому примеру, когда будем
обсуждать разработку демонстрационной темы.
Настроечные темы и темы таблиц стилей
Мы говорили, что существуют два вида тем: настроечные и темы таблиц стилей. Первые применяются для окончательной настройки сайта, и заданные в них установки
переопределяют установки свойств элементов управления, содержащиеся в исходных файлах
.aspx. Изменив тему страницы, вы полностью меняете ее внешний вид, не корректируя ни
строчки в ее исходном файле. Поэтому в случае применения настроечных тем страница
может содержать для каждого элемента управления минимум разметки.
Темы таблиц стилей подобны обычным каскадным таблицам стилей, но они
воздействуют на свойства элементов управления, а не на стили элементов HTML. Такие
темы применяются к элементам управления сразу после их инициализации, до того как будут
применены атрибуты, заданные в файле .aspx. Используя тему таблицы стилей, разработчик
определяет значения свойств элементов управления по умолчанию, которые затем могут
быть переопределены установками, заданными в исходном файле .aspx.
4. Порядок выполнения работы
Упражнение 1
Персонализация сайта
1)
Откройте стартовую страничку
1. В среде Microsoft Visual Studio, в меню File, нажмите Open Web Site.
2. В последующем окне укажите путь E:\LabFiles\ Starter\language\AdWorksWebSite и нажмите Open.
Откройте страничку web.config
1. В проводнике решения выберите web.config.
2)
Создайте профиль пользователя
1. Во вкладке <system.web> добавьте элемент profile.
2. Добавьте атрибут enabled к элементу profile и установите его значение как true.
3. Добавьте атрибут defaultProvider к элементу profile и установите его значение как
AspNetCustomProvider.
4. Добавьте пункт providers к элементу profile.
5. Добавьте провайдер к элементу providers и установите следующие атрибуты.
Аттрибут
Значение
Name
Type
connectionStringName
AspNetCustomProvider
System.Web.Profile.SqlProfileProvider
NWindConn
6. Добавьте пункт properties к элементу profile.
7. Добавьте значение к элементу properties и задайте следующие параметры.
Attribute
Value
Name
Type
Theme
String
Ваш код должен выглядеть следующим образом.
<profile enabled="true" defaultProvider="AspNetCustomProvider">
<providers>
<add name="AspNetCustomProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="NWindConn"/>
</providers>
<properties>
<add name="Theme"
type="String" />
</properties>
</profile>
8. В меню File выберите Save web.config.
3)
Добавьте выпадающий список выбора темы
1. В проводнике решения выберите AdWorks.master.
2. Под html комментарием <!-- Ex 1 -->, добавьте тэг span с атрибутом style, который
должен содержать text-align: right; width: 96%.
3. Добавьте текст Theme:.
4. Добавьте элемент DropDownList, и в окне Properties установите следующие параметры.
Атрибут
Значение
ID
AutoPostBack
runat
ThemeList
True
server
5. Добавьте три элемента списка со следующими названиями :
Default
BasicBlue
SmokeAndGlass
6. Установите событие OnSelectedIndexChanged в DropDownList к
ThemeList_SelectedIndexChanged.
Ваш код должен выглядеть следующим образом.
<span style="text-align: right; width: 96%;">
Theme:
<asp:DropDownList ID="ThemeList" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="ThemeList_SelectedIndexChanged">
<asp:listitem>Default</asp:listitem>
<asp:listitem>BasicBlue</asp:listitem>
<asp:listitem>SmokeAndGlass</asp:listitem>
</asp:DropDownList>
</span>
4)
Создайте метод Page_PreRender
1. В тэге <script> создайте метод Page_PreRender, который имеет параметры типа Object,
и типа EventArgs.
2. Установите свойство Theme как Profile.Theme.
Ваш код должен выглядеть следующим образом.
void Page_PreRender(object sender, EventArgs e)
{
ListItemCollection items = ThemeList.Items;
ThemeList.SelectedIndex = items.IndexOf(items.FindByText(Profile.Theme));
}
5)
Выполните метод ThemeList_SelectedIndexChanged
1. Создайте метод ThemeList_SelectedIndexChanged и установите параметр sender как object
и параметр e как EventArgs.
2. Создайте переменную типа string под названием theme и установите ее в
ThemeList.SelectedValue.
3. Проверьте, определена ли theme значением Default, и если это так и есть, установите
значение theme равным String.Empty.
4. Установите свойство Profile.Theme в качестве значения переменной theme.
5. Добавьте необходимый код для перезагрузки странички.
Ваш код должен выглядеть следующим образом..
void ThemeList_SelectedIndexChanged(object sender,
EventArgs e)
{
string theme = ThemeList.SelectedValue;
if (theme == "Default")
theme = "";
Profile.Theme = theme;
Response.Redirect(this.Page.
AppRelativeVirtualPath + "?str=Reload");
}
1. Чтобы хранить страничку в меню File кликните Save the AdWorks.Master.
Просмотр результатов
1. В проводнике решения кликните правой кнопкой по Default.aspx , а затем - View in
Browser.
5. Содержание отчета
В отчете должны быть представлены:


Исходный код.
Результат выполненой работы в виде скриншотов.
Скачать