Статьи

Создайте сайт с поддержкой XML / XSLT с помощью .NET

Заинтересованы в .NET? Не пропустите .NET Feature Guide — это отличный ресурс!

Сегодня мы создадим простой динамический веб-сайт с использованием ASP.NET, C #, XML и XSLT. Я предполагаю, что у вас есть опыт работы с ASP.NET, C #, XML и XSLT. Приведенный здесь исходный код сайта показывает все детали реализации, включая обработку ошибок.

Почему XML и XSLT?

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

Подход XML / XSLT естественным образом отделяет представление от базовой бизнес-логики. У этого метода есть множество преимуществ:

  • Лучшее повторное использование кода бизнес-логики быстро и надежно
  • Создание нескольких альтернативных интерфейсов, так что обслуживание клиентов с различными возможностями или потребностями легко и быстро
  • Возможны пользовательские настройки, такие как кобрендинг, индивидуальный дизайн
  • У больших команд разработчиков есть специализированные дизайнеры пользовательского интерфейса и основные разработчики. Разделение пользовательского интерфейса уменьшает зависимости между разработчиками, тем самым повышая производительность
  • Даже модульное тестирование пользовательского интерфейса проще, поскольку XML-документ — это все, что необходимо для воспроизведения конкретных тестов.

Но если разделение пользовательского интерфейса и бизнес-логики является основой всех этих преимуществ, зачем использовать для этого XML и XSLT?

Думайте о XSLT как о HTML, потому что большая часть кода в XSLT — это HTML. Учитывая, что есть пара правил, которые нужно соблюдать, и HTML должен быть правильно сформирован, но ничего особенного в этом нет. Есть бесплатные инструменты, которые помогут вам конвертировать HTML в XSLT. HTML Tidy, доступный на сайте W3C , является одним из них.

Что насчет XML? Что ж, XML может представлять любой тип структуры данных и используется в качестве входных данных для преобразования XSLT. Большинство современных баз данных (SQL Server, Oracle и т. Д.) Могут возвращать результаты своих запросов в формате XML. Кроме того, API базы данных (ADO) также могут преобразовывать свои результаты в формат XML.

Архитектура сайта

Архитектура сайта, который мы создадим, проста. Для каждого HTTP-запроса / ответа уровни бизнес-логики и управления данными предоставляют соответствующие данные в виде XML. Уровень представления предоставляет XSLT и различные параметры для преобразования. Результатом преобразования XSLT является HTML, который возвращается пользователю.

Многоразовый уровень представления презентаций поддерживает скины и глобализацию. Файлы XSLT хранятся в локальном каталоге с именем «UI». Каждый набор «скинов» XSLT-файлов хранится в подкаталоге с именем скина. Каждый набор глобализации XSLT-файлов хранится в подкаталоге с идентификатором локали в каталоге скина. Скин по умолчанию не имеет имени, то же самое относится и к набору глобализации.

Вот как выглядит дерево каталогов:

UI  skin1  lcid1  lcid2  skin2 

Каталоги пользовательского интерфейса содержат все файлы пользовательского интерфейса, необходимые для окончательного рендеринга на стороне клиента, включая изображения, CSS, сценарии Java и многое другое.

Независимая от приложения и повторно используемая функциональность изолирована в классе UIEngine в файле UIEngine.cs.

Класс предоставляет три свойства: ApplicationBase, Skin и Lcid, а также методы Transform, ExtractUIParameters и ExtractAction. ApplicationBase содержит относительный путь к каталогу пользовательского интерфейса, Skin содержит текущий скин для запроса, а Lcid содержит языковой стандарт запроса.

Метод Transform преобразует данные XML с использованием указанной таблицы стилей и записывает полученный HTML-код в объект ответа.

 Transform(HttpContext ctx, XPathDocument xmldoc,  string stylesheet, int lcid, XsltArgumentList arg) 

База веб-приложений

По умолчанию база приложения извлекается из Web.Config, который является файлом конфигурации для веб-приложения. Это файл XML, который содержит конфигурацию веб-приложения. Файл содержит многочисленные системные настройки для сайта. Существует раздел для пользовательских настроек приложения, который называется <appSettings> . Конфигурация доступна через класс ConfigurationSettings, часть пространства имен System.Configuration. Код так же прост, как:

 <configuration>  ...   <appSettings>      <add key="ui.base" value="ui" />   </appSettings>  </configuration>   m_applicationBase = ConfigurationSettings.AppSettings["ui.base"]; 

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

 string path = m_applicationBase;   // check for skin  if(m_skin.Length > 0)  {    path += m_skin + "\";  }   // check for globalization  if(m_locale > 0)  {    path += m_locale.ToString() + "\";  }   // add visualization parameters  arg.AddParam("ui.path","",path);  arg.AddParam("ui.skin","",m_skin);  arg.AddParam("ui.locale","", m_locale.ToString());   // add the stylesheet  path += stylesheet; 

Чтобы переключить скины, мы устанавливаем имя скина в строке запроса:

 http://localhost/bookstore/title.aspx?skin=dark 

Поскольку HTTP является протоколом без сохранения состояния, имя скина необходимо сохранять при разных вызовах. Существует несколько различных методов: переменные сеанса, параметры запроса, файлы cookie и постоянство базы данных.

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

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

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

 <a href="title.aspx?skin={$ui.skin}&amp;lcid={$ui.locale}">... 

Можно создать страницу конфигурации, на которой будут показаны доступные скины или локали. Например:

 http://localhost/bookstore/title.aspx?skin=dark&lcid=1026 

Этот URL будет отображать список книг по названию, используя скин «dark» и локализованный на болгарском языке — 1026. Обратите внимание, что локализован только пользовательский интерфейс; самих данных нет. По умолчанию кодировка HTML — UTF-8, которая работает с языками. Однако некоторые браузеры не поддерживают UTF-8, и в таблицы стилей XSL может быть добавлена ​​кодировка, зависящая от локали.

Параметры визуализации добавляются в качестве параметров для преобразования XSLT. Они видны в XSLT и могут использоваться для поиска элементов HTML в виде CSS и изображений. Например, мы бы использовали параметр ui.path, чтобы найти файл CSS и изображение:

 <LINK REL="stylesheet" TYPE="text/css" HREF="{$ui.path}css/default.css" />  <img src="{$ui.path}view.gif" alt="view book details" border="0" /> 

Дополнительные пользовательские параметры для каждого файла XSLT могут быть добавлены через аргумент XsltArgumentList, являющийся частью метода Transform.

Как только относительный путь определен, он преобразуется в абсолютный путь и загружается в объект XslTransform:

 XslTransform xslt = new XslTransform();  xslt.Load(ctx.Server.MapPath(path)); 

Данные XML передаются в виде строки и загружаются в XPathDocument:

 XPathDocument mydata = new XPathDocument(new  XmlTextReader(xmldoc,XmlNodeType.Document,null)); 

Преобразование выполняется, и результат записывается в строку:

 StringWriter sw = new StringWriter();  xslt.Transform(mydata,arg,sw); 

Строка записывается в объект Response с включенной буферизацией:

 ctx.Response.BufferOutput = true;  ctx.Response.Write(sw.ToString());  ctx.Response.End(); 

Создать веб-страницы

Когда UIEngine готов, следующим шагом является создание веб-страниц. Есть как минимум два разных метода, которые мы могли бы использовать для выполнения этой задачи. По умолчанию создается страница aspx веб-формы и обрабатывается рендеринг в событии Load. Новый класс является производным от System.Web.UI.Page, а событие Load обрабатывается методом Page_Load . В исходном коде вы найдете пример такой страницы author.aspx, хотя она отключена и не используется.

Метод, который я использую, заключается в реализации IHttpHandler . Хотя я должен написать это вручную (в настоящее время нет мастера), код прост и не требует нескольких исходных файлов. Кроме того, скомпилированное приложение представляет собой одну DLL: то есть отсутствуют файлы страниц (aspx).

  Интерфейс IHttpHandler является частью System.Web имен System.Web и позволяет вам определять пользовательскую обработку HTTP-запросов.  Интерфейс имеет одно свойство IsReusable и один метод ProcessRequest .  Свойство IsReusable имеет значение true, что позволяет повторно использовать объект, а не создавать его каждый раз, когда это необходимо.  Для поддержки состояния сеанса необходимо также реализовать IRequiresSessionState.

Как можно назвать этот обработчик из браузера? Вам нужно будет сопоставить этот обработчик с входящими URL-адресами. Это делается в файле Web.Config:

 <system.web>  ...  <httpHandlers>    <add verb="*" path="*.aspx"    type="bookstore.UIHandler,bookstore" />  </httpHandlers>  </system.web> 

Атрибут 'глагол' относится к глаголу HTTP: GET POST и т. Д. Установка значения ' * ' позволяет использовать любой глагол. Атрибут 'type' указывает имя класса обработчика, дополненное пространством имен, а вторая часть - это имя сборки. Используя мастер .Net, присвойте имени сборки имя проекта - в этом случае «книжный магазин».

Атрибут 'path' более интересен. Можно указать конкретный URL-адрес, например book.aspx, подстановочное имя ( *.aspx ) или даже путь - books/*.aspx . При использовании имени веб-сайта абсолютный URL-адрес в трех случаях будет выглядеть следующим образом:

 http://localhost/bookstore/book.aspx  http://localhost/bookstore/<anyname>.aspx  http://localhost/bookstore/books/<anyname>.aspx 

Обратите внимание, что в третьем случае путь к серверу считается bookstore / books, и HttpContext.Server.MapPath отобразит путь соответствующим образом.

Расширение aspx используется только потому, что оно уже зарегистрировано на веб-сервере. Можно использовать пользовательское расширение, но веб-сервер должен знать, что ASP.NET будет обрабатывать такие расширения.

API

Веб-сайт имеет простой API. Существует четыре ресурса (или виртуальных страницы) или действия после удаления расширений:

  • author.aspx — отображает список книг, отсортированных по автору
  • title.aspx — отображает список книг, отсортированных по названию
  • genre.aspx — отображает список книг, отсортированных по жанру
  • book.aspx — показать полную информацию о выбранной книге

Каждый из этих URL-адресов принимает параметры пользовательского интерфейса « skin » и « lcid », которые являются необязательными. Для book.aspx также требуется параметр id с идентификатором книги.

Запрос обрабатывается в методе ProcessRequest . Сначала извлекаются параметры пользовательского интерфейса и определяется запрашиваемое действие:

 eng.ExtractUIParameters(ctx);  string action = eng.ExtractAction(ctx); 

Затем для каждого действия определяется XSLT, а данные XML извлекаются из логики бизнес-уровня. В этом примере все действия используют одни и те же данные XML, которые реализованы в классе CBookData .

 CBookData bd = new CBookData();  mydata = bd.GetData(ctx); 

Действие ‘book’ принимает идентификатор дополнительного параметра, который извлекается и добавляется в качестве параметра в преобразование XSLT. Другие случаи, такие параметры, также могут быть переданы на уровень бизнес-логики.

 string id = ctx.Request.QueryString["id"]; 

Наконец преобразование выполняется и HTML-страница отображается в браузере пользователя.

 eng.Transform(ctx,mydata,stylesheet,arg); 

Ошибки обрабатываются методом UIEngine.DisplayError , который отображает все сообщения UIEngine.DisplayError исключения в стандартном HTML.

 catch(Exception err)  {   UIEngine.UIEngine.DisplayError(ctx,err.Message);  } 

Страницы ошибок могут быть реализованы с использованием таблиц стилей XSLT таким же образом, что и основной интерфейс.

Исходный код и инструкция по установке

Исходный код заархивирован в файле code.zip, который вы можете скачать здесь . Есть два файла C # UIEngine.cs и UIHandler.cs. Пользовательский интерфейс находится в каталоге «UI» и содержит два скина — по умолчанию и «темный». Темный скин также локализован для локали 1026. Файл данных book.xml находится в данных подкаталога.

  1. С помощью VC.NET создайте новый проект с помощью мастера «Проекты Visual C # | Веб-приложение ASP.NET». В качестве названия вашего проекта введите «книжный магазин». Вы можете выбрать другое имя, но вам нужно изменить пространство имен в UIHandler.cs и httpHandlers в Web.Config, чтобы отразить это имя.
  2. Разархивируйте файл sourcecode.zip в локальный каталог вашего нового проекта (например, C: Inetpubwwwrootbookstore). В каталоге проекта должно быть две папки: «Пользовательский интерфейс» и «Данные».
  3. Добавьте в проект UIEngine.cs и UIHandler.cs, используя меню «Project | Add Existing Items».
  4. При желании удалите WebForm1.aspx, созданный мастером.
  5. Откройте и измените файл Web.Config:
  6.  <configuration>  ...   <system.web>   ...    <httpHandlers>  <add verb="*" path="*.aspx" type="bookstore.UIHandler,bookstore" />     </httpHandlers>   </system.web>   <appSettings>          <add key="ui.base" value="ui" />  </appSettings>  </configuration> 
  7. Скомпилируйте проект.
  8. Показать список. В браузере введите http: //localhost/bookstore/author.aspx. Список книг, отсортированный по автору, должен отображаться.

Этот простой веб-сайт использует функциональность ASP.NET, весь код длиной менее 300 строк без пользовательского интерфейса. Код можно использовать повторно, а мощь XML / XSLT поможет вам создавать и поддерживать динамические веб-сайты без особых усилий. Для реального сайта необходимо добавить базу данных о производительности. Это означает разработку схемы базы данных и запросов к базе данных, которые очень важны для обеспечения хорошей производительности и масштабируемости сайта. Тогда потребуется модуль для связи с базой данных. ADO.NET является хорошим выбором в качестве базовой библиотеки базы данных. Он может обрабатывать различные базы данных, изначально реализован в .NET и может преобразовывать результаты запросов в формат XML.

Удачи на вашем сайте!

Эта статья является частью SitePoint .NET Feature Guide — отличного ресурса для начинающих и опытных разработчиков .NET. Не пропустите!