Основы ASP.NET 2.0
Основы ASP.NET 2.0
Инсталляция и тестовый проект
Microsoft .NET Framework — это платформа для создания, развертывания и запуска web-сервисов и приложений. Она предоставляет высокопроизводительную, основанную на стандартах многоязыковую среду, которая позволяет интегрировать существующие приложения с приложениями и сервисами следующего поколения, а также решать задачи развертывания и использования интернет-приложений. .NET Framework состоит из трех основных частей — общеязыковой среды выполнения (common language runtime), иерархического множества унифицированных библиотек классов и компонентной версии ASP, называемой ASP .NET.
ASP .NET — это часть технологии .NET, используемая для написания мощных клиент-серверных интернет-приложений. Она позволяет создавать динамические страницы HTML. ASP .NET возникла в результате объединения более старой технологии ASP (активные серверные страницы) и .NET Framework. Она содержит множество готовых элементов управления, применяя которые, можно быстро создавать интерактивные web-сайты. Вы также можете использовать сервисы, предоставляемые другими сайтами, прозрачно для пользователей вашего сайта. В общем, возможности ASP .NET ограничены только вашим воображением.
Давайте обсудим, что такое динамические страницы HTML и чем они отличаются от статических. Статическая страница содержит код на языке гипертекстовой разметки HTML. Когда автор страницы пишет ее, он определяет, как будет выглядеть страница для всех пользователей. Содержание страницы будет всегда одинаковым, независимо от того, кто и когда решит ее просмотреть.
Языка HTML вполне достаточно для отображения информации, которая редко изменяется и не зависит от того, кто ее просматривает. Страница HTML — простой ASCII-текст, следовательно, клиент может работать в любой операционной системе.
Совершенно понятно, что если сформировать web-страницу, описав ее структуру средствами HTML, она будет совершенно статична в смысле содержимого. То есть при просмотре в браузере она будет нести в себе точно ту же информацию, что была в нее записана в момент создания, и переданные пользователем данные не могут быть использованы для модификации содержимого отображаемых ему страниц: он сможет увидеть только то, что предварительно было записано в конечный набор файлов.
Но что если мы хотим отобразить на странице текущий курс евро или прогноз погоды? Если мы написали страницу HTML вчера, сегодня она уже устареет. Следовательно, мы должны уметь создавать динамические страницы. Динамическое наполнение страницы — это информация, которая отличается от просмотра к просмотру и содержание которой зависит от того, кому она предназначена. Такое наполнение позволяет обеспечить двусторонний обмен информацией — от клиента к серверу и обратно.
Динамическими принято называть web-страницы, которые перед отправкой клиенту проходят цикл обработки на сервере. В самом простом случае это может быть некоторая программа, которая модифицирует запрашиваемые клиентом статические страницы, используя параметры полученного запроса и некоторое хранилище данных. Даже при такой примитивной организации "неразрешимая" задача из предыдущего абзаца обретает очевидное решение: достаточно подготовить всего одну статическую страницу — шаблон — и перед отправкой страницы программно подставлять в него значение, полученное сегодня из банка или метеобюро.
Большинство страниц на ранних стадиях развития Интернета были статическими. Последние 10 лет растет количество динамических страниц. И это понятно: пользователи Интернета хотят не только читать готовую информацию, но быть активными действующими лицами. Например, они заказывают товары в интернет-магазине, пишут дневники, участвуют в конкурсах. Информационные порталы обновляют новости каждую минуту. Динамические страницы могут подстраиваться под конкретного пользователя, а также реагировать на его действия в браузере. Каким же образом? Для этого придумано множество технологий. Например, чтобы идентифицировать пользователя и сохранить его настройки для данного сайта, применяются файлы-cookies.
Существуют языки, способные динамически изменять содержимое web-страницы. С одной стороны, это языки скриптов, выполняющиеся непосредственно у клиента. Примеры скриптовых языков — JavaScript и VBScript. Скрипты на этих языках встроены в код HTML, который сервер посылает браузеру. Сценарии, выполняемые на стороне клиента, выделяются тегами . Браузер интерпретирует этот код и показывает пользователю результат. Сам код можно просмотреть через View Source браузера. Естественно, эти программы не могут быть большими. Например, если нужно выполнить поиск в базе данных, мы не можем отправить пользователю все ее содержимое. Но скрипты могут проверить правильность запроса, введенного в форму, и тогда не придется перегружать сервер обработкой неправильных запросов. Некоторые программисты создают на JavaScript анимационные эффекты.
Одна студентка intuit. ru желала найти скрипт, который бы отправлял SMS-сообщения. Увы, это невозможно. Выполняемых на стороне клиента сценариев недостаточно для создания полноценных динамических страниц. Даже если на странице используется JavaScript и анимированные картинки .GIF, она называется статической.
Динамическая web-страница должна быть создана "на лету" программой, исполняющейся на интернет-сервере. Широко применяется механизм шлюзов CGI (Common Gateway Interface). Вначале пользователь получает статическую страницу с формой. Вам известно, что в теге FORM существует атрибут ACTION. Именно он задает адрес (URL) исполняемого приложения. На сервере находятся исполняемые файлы программ, написанных, например, на C/С++ или Delphi, которые по протоколу HTTP принимают данные из входного потока или из переменных окружения и записывают в стандартный выходной поток готовую страницу.
Пользователю в ответ на запрос посылается HTML-код, который был специально сгенерирован для него. Это может быть, например, результат поиска в поисковой системе. CGI-скрипты могут быть написаны на интерпретируемом языке (Perl) или даже скрипте командной строки. Входной и выходной потоки переназначаются. На вход интернет-сервер принимает данные, введенные пользователем. После обработки полученных данных пользователю возвращается результирующая страница. При исполнении cgi-программа загружается в память сервера, а при завершении — удаляется. Когда 100 клиентов одновременно обращаются к серверу, в памяти создаются 100 процессов, для размещения кода каждого из которых нужна память.
Это отрицательно сказывается на масштабируемости. Напомним, что масштабируемость — это возможность плавного роста времени ответа программной системы на запрос с ростом числа одновременно работающих пользователей.
Для решения этой проблемы Microsoft была предложена альтернатива — ISAPI (Internet Server Application Programming Interface) расширения и фильтры. Вместо исполняемых файлов используются DLL-библиотеки. Код DLL находится в памяти все время и для каждого запроса создает не процессы, а нити исполнения. Все нити используют один и тот же программный код. ISAPI-приложение выполняется в процессе IIS-сервера. Это позволяет повысить производительность и масштабируемость.
ISAPI-расширения можно создавать в Visual Studio C++ 6.0, пользуясь мастером.
У ISAPI тоже есть недостатки, относящиеся к разработке. Если мы меняем исходный код dll, мы должны его откомпилировать и поместить в исполняемую директорию сервера. Но так как предыдущий вариант dll находится в памяти, необходимо остановить сервер, чтобы получить возможность изменить файл. В это время клиенты не смогут получить с сервера ни один документ, и, конечно, будут недовольны.
Файлы asp отправляются к нему на обработку. На вход поступает asp, а на выходе имеем поток HTML-кода.
Пример файла asp:
<%@ Language=VBScript %> <% Option Explicit%>
<% Dim i; for i=1 to 5 Response.Write("Этот код генерирует ASP!") next i %>;
Тег <%...%> сигнализирует asp, что в нем находится код, который он должен обрабатывать на сервере. Выполняется скрипт на языке, который указан в директиве Language. Оператор Response.Write записывает текст в выходной поток сервера — таким образом, он становится частью HTML-страницы, отправленной пользователю.
Технология asp была ограничена по своим возможностям. ASP использовал скриптовые языки, которые имеют меньше возможностей, чем полнофункциональные языки программирования. Код asp был встроен в HTML в виде специальных тегов, что создавало путаницу. Кусочки asp были разбросаны по нему, как изюм в булке. Но HTML-код обычно создают дизайнеры, которые умеют "делать красиво", а asp — программисты, которые заставляют все это работать. В ASP .NET вы можете держать код asp и HTML в разных файлах.
Скриптовые языки не поддерживают строгую типизацию. Что это значит? Вы можете не описывать переменную до ее использования и можете присваивать ей значения разных типов.
Это удобно, но создает почву для ошибок. Например, у вас есть переменная x1, и вы присваиваете ей значение 1, но вы сделали опечатку и по ошибке написали x2 = 1. Будет создана новая переменная x2, а значение x1 не изменится. В языке со строгой типизацией компилятор заметит, что переменная x2 не описывалась, и выдаст ошибку.
В 2000 году на конференции разработчиков в качестве части новой технологии .NET Microsoft представила ASP+. С выходом .NET Framework 1.0 она стала называться ASP .NET.
ASP .NET — это не продолжение ASP. Это концептуально новая технология Microsoft, созданная в рамках идеологии .NET. В ASP .NET заложено все для того, чтобы сделать весь цикл разработки web-приложения более быстрым, а поддержку — более простой. ASP .NET основана на объектно-ориентированной технологии, но сохранила модель разработки asp: вы создаете программу и помещаете ее в директорию, выделенную сервером, и она будет работать. В ASP .NET появилось много новых функций, а существовавшие ранее в asp значительно усовершенствованы.
В ASP .NET используются компилируемые языки. Во время компиляции проверяется синтаксическая корректность исходного текста. Скомпилированный в промежуточный язык код выполняется быстрее, и он будет таким же независимо от языка, который мы используем. Компилируемые языки поддерживают строгую типизацию.
Компиляция происходит на сервере в момент первого обращения пользователя к странице. Если программист изменил текст страницы, программа перекомпилируется автоматически.
При написании кода можно использовать набор компонентов, поставляемых с .NET.
Платформа .NET Framework предоставляет приложениям среду выполнения, сама непосредственно взаимодействуя с операционной системой. Выше лежит интерфейс ASP .NET-приложений, на котором в свою очередь базируются web-формы (ASP .NET-страницы) и web-сервисы. Интерфейс .NET Framework позволяет стандартизировать обращение к системным вызовам и предоставляет среду для более быстрой и удобной разработки. CLR обеспечивает единый набор сервисов для всех языков.
ASP .NET использует технологию доступа к данным ADO .NET, которая обеспечивает единый интерфейс для доступа к базам данных SQL Server и файлам XML. Кроме того, усиленная модель безопасности позволяет обеспечивать защиту клиента и сервера от несанкционированного доступа.
В 2004 году появилась версия ASP .NET 2.0 (бета-версия, окончательный выход — конец 2005 — начало 2006 гг.). Как утверждается, эта версия позволяет сократить объем кодирования на 70%. Новые возможности версии 2.0 — использование шаблонов дизайна страниц (Master Page), упрощенная локализация web-приложений, более 50 новых серверных элементов управления. Цели, которые преследовали разработчики новой версии, — повысить скорость разработки сайтов, масштабируемость, легкость поддержки и администрирования сайтов, скорость работы сервера. Появилась панель оснастки MMC (консоль управления Microsoft), предоставляющая графический интерфейс для управления настройками ASP .NET. Изменять настройки проекта теперь можно и через web-интерфейс.
ASP .NET 2.0 поддерживает работу на 64-битных процессорах. Сервис персонализации (personalization) предоставляет готовое решение для хранения персональных данных, непосредственно характеризующих пользователя сайта, — так называемого профиля пользователя (Profile).
Шаблоны дизайна, темы и скины позволяют отлаживать дизайн всего сайта отдельно от его функциональности, темы включают графику и каскадные таблицы стилей.
Предыдущие версии Visual Studio для проектов ASP .NET требовали наличия на машине разработчика сервера IIS. Теперь сервер встроен в среду разработки.
ASP .NET 2.0 и Visual Studio 2005 предоставляют инструменты для легкого построения локализируемых сайтов, которые определяют предпочитаемый язык пользователя и посылают ему страницы на его языке.
Возможность прекомпиляции позволяет обнаружить ошибки до загрузки страниц на сервер. Можно не хранить исходные страницы aspx на сервере, тем самым защищая свою интеллектуальную собственность.
В ASP .NET 2.0 встроена технология автоматического обновления кэширования баз данных. Данные, полученные из базы, хранятся на сервере, и он не обращается к базе для обработки повторного запроса. При изменении базы данных кэш обновляет свое содержимое.
ASP .NET — это технология, а не язык, и позволяет программировать на разных языках — С#, Visual Basic, J#. "В платформе .NET все языки равны, но некоторые — равнее" (Дж. Оруэлл). Вот таким языком и является С#, потому что он был специально создан для этой платформы. Программирование C# позволяет в полной мере использовать концепции, методы и паттерны объектно-ориентированной разработки.Язык Visual Basic 8.0 наделен почти теми же возможностями. Чтобы научиться ASP .NET, вам нужно знать основы HTML, а знание asp не обязательно. Оно может даже помешать, так как придется менять образ мышления. Также для понимания желательно знать CSS и JavaScript.
Первый проект
В начале решите, в какой директории будете создавать страницы. Все файлы, находящиеся в одной директории, считаются единым проектом. Запустите выбранную вами среду разработки. Выберите пункт меню File-New-Website. Появится диалоговое окно. Назначьте в нем имя проекта и выберите язык программирования С#.
По умолчанию проект создается в файловой системе. По желанию его можно создать на HTTP или FTP-сервере. Из файловой системы проект всегда можно скопировать на сервер нажатием одной кнопки в заголовке Solution Explorer.
В проекте будет создана страница default.aspx. Выберите ее, и появится окно редактирования с закладками Design и Source. Не меняя ничего, щелкните на кнопке со стрелкой, чтобы просмотреть страницу в браузере. Появится окно, в котором спрашивается, нужно ли добавить в файл web.config возможность отладки. Нажмите "OK". На панели задач должен появиться значок web-сервера. Откроется браузер, показывающий страницу по адресу http://localhost:номер_порта/Website1/default.aspx. "Localhost" обозначает сервер, работающий на вашем компьютере. Встроенный сервер Cassini сам назначает себе номер порта — для каждого проекта он разный. Сервер IIS обычно работает через порт 80 (или 8080, если тот занят), и для него номер порта указывать не нужно. При этом ваша страница будет скомпилирована.
Пока что страница в браузере пустая.
Но исходный код этой страницы не пустой. Программа сгенерировала код для вас.
<%@ Page Language="C#" AutoEventWireup="true"; CodeFile="Default.aspx.cs" Inherits="_Default" %>
Разберем эту страницу.
<%@ Page Language="C#" %>. Тег <% всегда предназначается для интерпретации ASP-кода. Директива Page всегда присутствует на странице aspx. Ее атрибут Language — это указание, что в скриптах данной страницы будет использоваться C#, а могли бы VB, C++ или J#. CodeFile — имя файла с отделенным кодом (code-behind). Inherits — класс, определенный в том файле, от которого наследуется класс страницы.
Одновременно будет создан и файл Default.aspx.cs.
Это технология разделения кода, о которой мы уже говорили. Сама форма находится в файле Default.aspx, а в файле Default.aspx.cs находится класс страницы на языке C#. Таким образом, дизайн страницы может быть изменен не затрагивая кода страницы, что позволяет разделить ответственность за внешний вид и работу страницы между дизайнером и программистом.
тег, задающий элемент управления.
Text="Сервер находится в Москве. Московское время: " />
Серверный элемент управления Label является средством размещения на странице текста, который может содержать теги HTML. Изменяя значения свойств этого элемента управления в коде, вы можете динамически изменять текст на странице. В asp:Label компилятору сообщается, с каким объектом ведется работа (в рассматриваемом случае — с элементом управления Label).
При использовании этого свойства элемент управления обрабатывается компилятором, а не передается браузеру "как есть".
Вставьте в Default.aspx между тегами тег, задающий элемент управления.
Text="Сервер находится в Москве. Московское время: " />
Серверный элемент управления Label является средством размещения на странице текста, который может содержать теги HTML. Изменяя значения свойств этого элемента управления в коде, вы можете динамически изменять текст на странице. В asp:Label компилятору сообщается, с каким объектом ведется работа (в рассматриваемом случае — с элементом управления Label).
Далее задаются различные свойства элемента управления. В первую очередь определяется его имя id="time" и атрибут "runat", а также текст.
В файле Default.aspx.cs должен содержаться такой текст:
using System; ...... public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) {
} }
Ключевое слово partial появилось в C# 2.0, и позволяет разбить текст определения класса между разными файлами.
System.Web.UI.Page — класс, базовый для всех страниц ASP .NET.
Если вы работаете с WebMatrix, вставьте его самостоятельно между тегами файла default.aspx.
Вставьте в эту функцию строчку
Time.Text+=DateTime.Now.ToString();
Возможно, вы уже знакомы с классом System.DateTime библиотеки классов FCL — составной части .NET Framework.
Здесь мы используем этот класс, как в любой программе на C#. Следовательно, любой класс .NET доступен и в локальных, и в распределенных приложениях.
Полученное значение присваивается свойству Text объекта time. Это элемент управления типа Label (метка), который мы вставили. Время на часах клиента и сервера может не совпадать, если они находятся в разных точках земного шара.
Page_Load похож на обычный обработчик события формы. Как можно легко догадаться, эта функция вызывается каждый раз, когда загружается форма.
Запустите страницу на просмотр кнопкой F5 или нажав на кнопку со стрелкой на панели инструментов. В браузере должна открыться страница, на которой будет написано текущее время. Откройте исходный текст страницы. Никакого кода на С# или элементов управления ASP.NET там не будет:
Обновите страницу. Вы увидите новое значение времени.
Вы можете просмотреть страницу с помощью любого другого браузера.
Если вы находитесь в сети и выход в Интернет осуществляется через прокси-сервер, поставьте галочку на странице Connections (для IE) Bypass proxy server for local addresses.
Процесс инсталляции
ASP .NET 2.0 можно установить на компьютерах с ОС Windows 2000 с Service Pack 4, Windows XP с Service Pack 2 и более поздними версиями Windows. Готовые сайты предпочтительно устанавливать на Windows Server 2003.
Для разработки приложения можно использовать любую среду разработки или даже текстовый редактор, при условии, что у вас есть доступ к IIS. Если же вы хотите задействовать всю мощь Microsoft .NET Framework и ASP .NET и при этом затратить как можно меньше усилий, то нужно воспользоваться средой разработки, специально созданной для программирования ASP .NET 2.0.
Если вы приобретете Visual Studio .NET 2005, то для работы достаточно будет только его. .NET Framework содержится на дисках. В его состав входит Visual Web Developer, который позволяет создавать профессиональные web-приложения, а также desktop-приложения на разных языках программирования. Продукты Microsoft выпускаются на DVD, но есть набор из двух CD от "Мегасофт". Visual Studio .NET 2005 требует около 2 Гб дискового пространства. При этом инсталлируется ASP .NET 2.0, среда разработки, SQL Server Express, встроенный web-сервер, Crystal Reports со специальными элементами управления для ASP .NET 2.0.
Сообщества разработчиков
Через меню помощи Visual Web Developer Express можно зайти на сайты форума по ASP .NET. А вот адреса сайтов на русском языке:
http://www.aspnetmania.com
Сообщество разработчиков .NET:
http://www.gotdotnet.ru/
http://www.sql.ru/
http://dotsite.ru/
Сообщество программистов:
http://www.rsdn.ru/
Вы можете завести пробный хостинг на http://europe.webmatrixhosting.net/russia/default.aspx.
изучить нелегко, но благодаря
ASP .NET 2. 0 изучить нелегко, но благодаря ее компонентной модели выигрыш состоит в ускорении разработки по сравнению с другими технологиями.
Основы ASP.NET 2.0
Блоки отображения
Любой код, внедренный с помощью <% и %>, обрабатывается во время события Render как часть страницы. В теле блока <% %> допустимо объявлять переменные (тогда они будут локальными для того метода, в котором данный блок будет реализован), но нельзя объявлять методы или типы.
Такой стиль программирования был характерен для asp. Чаще всего в блоках отображения выводится HTML-код с помощью Response.Write.
<%= someExpr %> является сокращением <% Response.Write (someExpr) %>:
1 Строка HTML
<% Response.Write ("1 Строка ASP.NET
"); %> 2 Строка HTML
<% Response.Write ("2 Строка ASP.NET
"); %> 3 Строка HTML
<% ="3 Строка ASP.NET
"; %>
Более современный способ — использование серверных элементов управления. Они описаны в теле страницы подобно обычным элементам разметки, являются членами класса страницы. К ним возможно обращение через идентификатор. Например, вместо того чтобы выводить текст через Response.Write, можно установить текст элемента управления, как в примере из первой лекции.
Объект любого класса создается с помощью синтаксиса "тег объекта":
Это эквивалентно описанию в классе страницы поля:
System.Collections.ArrayList items;
Еще один способ применяется для связывания с источниками данных и будет рассмотрен в лекции 7
Директива Page
Директива Page позволяет установить свойства страницы, которые будут использованы во время компиляции. Эта директива используется чаще остальных, поэтому ее необходимо рассмотреть более подробно.
Наиболее важные атрибуты директивы перечислены в таблице.
| AutoEventWireup | Автоматическая обработка событий страницы |
| Buffer | Управляет буферизацией страницы. По умолчанию буферизуется |
| ClassName | Позволяет назначать имя класса, сгенерированного данной страницей |
| CodeFile | Название файла с отделенным кодом для данной страницы |
| Culture | Устанавливает набор региональных параметров, т.е. язык, формат валюты, даты, чисел |
| Debug | Если true, на страницу выводится отладочная информация |
| Trace | Вывод трассировочной информации |
| EnableViewState | Сохранение состояния страницы. По умолчанию она сохраняется |
| EnableTheming | Позволяет включить или выключить поддержку тем оформления. По умолчанию включено |
| Inherits | Класс, от которого наследуется класс данной страницы в технологии отделенного кода |
| IsAsync | Показывает, обрабатывается ли страница асинхронно |
| Language | Язык, используемый во внедренном коде |
| WarningLevel | Наибольший допустимый уровень предупреждений компилятора |
| CompilerOptions | Опции компилятора |
Директивы
На каждой странице aspx обычно задаются директивы, с помощью которых Вы можете контролировать поведение страницы. Можно считать их языком, на котором вы общаетесь с компилятором, указывая ему, как обрабатывать данную страницу. Директивы обычно помещают в начале файла. Мы уже встречались с директивой Page в первой лекции.
Синтаксис объявления директив такой:
<%@ [Directive] [Attribute=Value] %>
Можно объявить несколько директив одновременно:
<%@ [Directive] [Attribute=Value] [Attribute=Value] %>
В ASP .NET 2.0 существует 11 директив.
| @Assembly | Name Src | Импортирует на страницу или в элемент управления сборку с заданным именем |
| @Control | такие же, как у Page | Применяется для задания свойств при создании собственных пользовательских элементов управления |
| @Implements | Interface | Указывает, что класс данной страницы реализует данный интерфейс |
| @Import | Namespace | Импортирует пространство имен |
| @Master | такие же, как у Page | Применяется на страницах шаблона дизайна (Master page). Новая в ASP .NET 2.0 |
| @MasterType | TypeName VirtualPath | Дает строго типизированную ссылку на класс, содержащийся в шаблоне дизайна. Позволяет обращаться к свойствам этого класса |
| @OutputCache | Duration Location VaryByCustom VaryByHeader VaryByParam VaryByControl | Управляет кэшированием страницы или элемента управления. Подробнее описана в лекции 15 |
| @Page | см. ниже | Атрибуты, относящиеся к данной странице. Употребляется только в файлах с расширением aspx |
| @PreviousPageType | TypeName VirtualPath | Страница, с которой были отправлены данные, введенные пользователем. Новая в ASP .NET 2.0. Раньше страницы отправляли пост только самим себе |
| @Reference | Page Control | Страница или элемент управления, который нужно компилировать вместе с данной |
| @Register | Assembly Namespace Src TagName TagPrefix | Создает псевдонимы для пространств имен и пользовательских элементов управления |
Пока что подробно рассмотрим два из них — Page и Import.
Как работает ASP .NET
Когда мы инсталлируем .NET, в соответствующих директориях C:\WINDOWS\Microsoft.NET\Framework\ помещается также файл aspnet_isapi.dll. Это — ISAPI-расширение, и предназначено оно для получения запросов, адресованных ASP .NET-приложениям (*.aspx *.asmx и т.д.), а также для создания рабочих процессов aspnet_wp.exe, обрабатывающих запросы. Интернет-сервер — IIS или встроенный в WebMatrix и в Visual Studio Cassini — используют это расширение, когда им надо обработать обращение к страницам с расширением aspx.
Этот модуль разбирает (parse) содержимое страниц aspx вместе с файлом отделенного кода и генерирует класс на языке страницы с объектом Page. Страница aspx отличается от обычной HTML-страницы наличием серверных элементов управления, которые описываются специальными тегами. Для понимания работы ASP .NET важно отметить, что каждому тегу элемента управления соответствует свой член класса страницы. Например,
преобразуется в
@__ctrl = new global::System.Web.UI.WebControls.Label();
Основная задача объекта Page — посылка HTML-кода в выходной поток. Этот класс компилируется в библиотеку DLL, которая загружается в процесс web-сервера. Последующие запросы к странице также обрабатывает DLL, если исходный код страницы не меняется. Все эти файлы можно найти в директории "Temporary ASP.NET Files" текущей версии .NET. Если мы работаем в среде разработки Visual Studio 2005 или VWD, для каждого проекта создается своя поддиректория.
Проект на двух языках
Проект web-сайта состоит из страниц aspx и классов, которые используются на страницах (и, конечно, разнообразных ресурсов). Файлы с классами, к которым можно обратиться из разных страниц, помещают в специальную папку App_Code. При компиляции они помещаются в одну сборку — библиотеку DLL в формате portable executable. Совершенно неважно, на каком языке написан класс, если это язык .NET.
Готовые скомпилированные сборки сторонних производителей тоже можно использовать в проекте. Их помещают в папку Bin. При этом их необходимо импортировать в проект:
<%@ Import Namespace="MyCustomNamespace" %>
Создайте новый проект. Добавьте в него файл, выбрав тип файла Class и язык Visual Basic. Среда сама предложит поместить его в папку Code. Назовем его CustomClass. У него будет очень простой код. Всего одна функция, которая добавляет слово Hello к имени, переданному в качестве параметра:
Imports Microsoft.VisualBasic
Public Class CustomClass
Public Function GetMessage(ByVal name As String) As String Return "Hello, " & name End Function End Class
Добавьте в проект страницу CodeFolder_cs.aspx. Эта страница написана на C#, но она создает класс, написанный на VB .NET:
<%@ page language="C#" %>
На странице определена форма, напоминающая форму Windows-приложения. На ней имеется кнопка, нажатие на которую обрабатывается в функции Button1_Click. В ней создается класс и вызывается его функция GetMessage с параметром, который берется из элемента редактирования. Возвращаемое значение записывается в элемент Label1. В более простом варианте это выглядит так:
Label1.Text = "Hello "+TextBox1.Text;
Класс может быть написан на C#, а использоваться из страницы на Visual Basic:
using System; public class CustomClass2 { public String GetMessage(String input) { return "Hello from C# " + input; } } Код страницы CodeFolder_vb.aspx:
Однако поместить в директории App_Code можно только на одном языке. Если там будут находиться файлы на разных языках, проект не будет компилироваться. Для того чтобы использовать два языка, необходимо создать поддиректорию, добавить ее в файл web.config и поместить в нее файлы на другом языке.
Регистрация в файле web.config:
Программа просмотра классов
Как же узнать, какие классы имеются в библиотеке классов .NET? Для этого предназначен Object Browser (Visual Studio 2005) и Class Browser WebMatrix. Чтобы открыть Object Browser в Visual Studio 2005 или VWD Express, выберите пункт меню View —> Object Browser. Если вы используете WebMatrix, то Class Browser находится в той же папке меню Windows, что и WebMatrix — All Programs —> ASP.NET WebMatrix. В формате ASP .NET Class Browser включен в состав Framework SDK.
Все имеющиеся пространства имен показаны как узлы древовидной структуры. Нас интересует System.Web. Раскройте этот узел. Внутри оказались другие пространства имен. Раскройте System.Web.UI. Там находится большое количество классов, интерфейсов, делегатов, перечислений. Их можно узнать по иконкам. Например, иконка делегата похожа на чемодан.






Выберите класс Page. В окошке справа появится список его методов, полей и событий. Если выбрать метод, в третьем окне под вторым появится его описание. Внутри класса находятся еще две папки — классов-прародителей (Base Classes) и классов-потомков. Все их тоже можно просмотреть. Object Browser показывает и классы текущего проекта. Если классы закомментированы тегами генерации документации XML, то эта информация тоже видна, например Summary, Parameters, Values, Returns.

увеличить изображение
Рис. 2.8.
Исследуя свойство IsPostBack, можно узнать, что оно имеет булевское значение и предназначено только для чтения.
Пространства имен библиотеки классов
Библиотека классов FCL содержит тысячи классов. Для удобства использования они объединены в пространства имен. Чтобы обращаться к классам, объявленным в пространстве имен, без указания полного пути, его нужно импортировать в проект. Если вы хотите работать с файлами формата XML, вам нужно импортировать пространство имен System.XML. В страницах отделенного кода на C#, как всегда, используется директива using.
using System. XML;
На странице aspx — директива Import
<%@ Import Namespace= "System.XML " %>
Для каждого пространства имен требуется отдельная директива Import.
Visual Studio .NET и VWD по умолчанию включают в страницу на C# наиболее часто используемые пространства имен. На страницу aspx импортировать эти пространства имен не требуется.
using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls;
Например, в пространстве имен System.Web.UI находится класс Page, без которого не может существовать ни одна страница ASP .NET, в System.Web — HttpRequest и HttpResponse.
Проверка соответствия стандартам
Существуют разные стандарты HTML и xHTML. Более поздние стандарты предъявляют более строгие требования, например, хHTML 1.1 не разрешает пользоваться
и другими простыми тегами без закрывающей косой черты
. В то же время старые стандарты не поддерживают новые теги.
В заголовке HTTP-запроса указывается стандарт документа, Visual Studio 2005 во всех страницах указывает следующий стандарт:
Этот стандарт требует наличия атрибута xmlns в теге — ссылки на сайт с описанием стандарта.
Многие страницы, сделанные для предыдущих версий ASP .NET, не имеют такого атрибута. В панели инструментов Html Source Editing также находится выпадающий список, где можно выбрать стандарт или версию браузера, для которого предназначена данная страница. Страница автоматически проверяется на соответствие этому стандарту.
События страницы
Работа среды ASP .NET со страницей начинается с получения и обработки web-сервером IIS-запроса к данной странице и передачи этого запроса среде выполнения ASP .NET. Среда выполнения анализирует, нужно ли компилировать страницу или можно выдать в качестве ответа страницу из кэша.
Затем начинается жизненный цикл страницы. Он начинается с этапа PreInit. После получения запроса среда выполнения загружает класс вызываемой страницы, устанавливает свойства класса страницы, выстраивает дерево элементов, заполняет свойства Request, Response и UICulture и вызывает метод IHttpHandler.ProcessRequest. После этого среда выполнения проверяет, каким образом была вызвана эта страница, и если страница вызвана путем передачи данных с другой страницы, о чем будет рассказано далее, то среда выполнения устанавливает свойство PreviousPage.
На этом этапе устанавливается также свойство IsPostback объекта Page, которое позволяет узнать, в первый ли раз загружается форма или она должна формироваться как результат обработки данных, введенных пользователем.
В обработчиках событий страницы можно проверить это свойство:
if (!Page.IsPostBack) { // обрабатывать }
Дальше происходит инициализация страницы — событие Init. Во времени инициализации создаются дочерние пользовательские элементы управления и им устанавливаются свойства id. В это же время к странице применяются темы оформления. Если страница вызвана в результате постбэка, то на этом этапе данные, отправленные на сервер, еще не загружены в свойства элементов управления.
Программист может инициализировать их свойства.
Загрузка. Во время события Load устанавливаются свойства элементов управления на основании информации о состоянии, если страница создается в результате отправки данных формы.
Если на странице существуют валидаторы (классы проверки данных, см. лекцию 5), то для них вызывается метод Validate(). Затем вызываются обработчики событий (при условии, что страница генерируется в ответ на действия пользователя).
В методе Render генерируется сам HTML-код выводимой страницы. При этом страница вызывает соответствующие методы дочерних элементов, а те в свою очередь — методы своих дочерних элементов. В методе Render код выводится в Response.OutputStream. Сама страница тоже считается элементом управления — класс Page является наследником класса Control. Если на странице есть блоки отображения, они становятся частью функции отрисовки (rendering).
Наконец, страница выгружается из памяти сервера и происходит событие Unload.
Во время жизненного цикла страницы происходят различные события. Можно включить трассировку страницы, чтобы посмотреть порядок их возникновения:
<%@ Page Language="C#" Trace ="true" TraceMode="SortByTime" %>

увеличить изображение
Рис. 2.9.
Во время трассировки не выводится событие Unload, потому что оно происходит, когда весь код уже выведен. Во время обработки этого события нужно освободить ресурсы, например, соединения с базами данных или открытые файлы.
Полный список событий страницы, которые можно переопределить в классе страницы:
- PreInit
- Init
- InitComplete
- PreLoad
- Load
- LoadComplete
- PreRender
- PreRenderComplete
- Unload
Для всех событий определены обработчики — виртуальные функции OnInit, OnLoad. Когда AutoEventWireup равно true, в классе автоматически объявляются функции-обработчики событий с префиксом Page — Page_Load, Page_Init и так далее. Одно из самых популярных событий — это Page_Load. Генерируя новую страницу, Visual Studio создает обработчик этого события. Здесь можно изменить внешний вид элементов и задать новые. Можно установить AutoEventWireup в false. В таком случае надо писать перегруженные версии виртуальных функций:
protected override void OnInit(EventArgs e) { }
Так можно добиться ускорения работы страницы.
Способы внедрения кода ASP .NET в страницу
Есть три способа внедрить код на программном языке в страницу aspx.
Блок называется блоком объявления кода. Тег
Учитесь программировать на ASP.NET
В этом примере мы поменяли текст заголовка. Запустите эту страницу. В получившемся HTML-коде внутри тега
Был создан стиль для тега
, что отразилось таким образом:
Внешняя страница CSS была импортирована из файла:
Вставьте в форму следующий код:
У элемента Panel1 устанавливается свойство ScrollBars="Auto" и в него помещается GridView. Стиль, который применен для заголовка, задает относительное положение данного класса у верхней границы панели.При генерации HTML-кода для заголовка GridView генерируются теги
| Событие | Условия наступления |
| Application_Start | Первая страница приложения открывается любым пользователем |
| Application_End | Работа приложения завершается |
| Session_Start | Посетитель активизирует приложение |
| Session_End | Пользователь покидает приложение или не запрашивает страницу в течение некоторого периода времени |
| Application_Error | При выполнении приложения возникает необработанная ошибка |
Данные события предназначены для выполнения кода или создания переменных, которые существуют до тех пор, пока существует программа или пока посетитель пребывает на узле. За счет этого можно сохранять регистрационную информацию, неизменные данные для web-узла или постоянные соединения с источниками данных:
<%@ Application Language="C#" %>
В приложении Starter Kit, например в Application_Start, создаются роли администратора и друга.
ViewState
В лекции 3 упоминалось о скрытом поле ViewState, которое обычно есть у сгенерированных ASP .NET страниц. Говорилось, что там хранится информация о состоянии отображения страницы, которая передается на сервер и обратно, чтобы после перезагрузки на ней сохранялись ее динамические изменения. Там не хранятся введенные пользователем данные, они отправляются, как обычно, в теле запроса POST.
Понимание, что такое состояние отображения и как оно работает, очень важно, особенно для разработчиков, которые пишут собственные элементы управления.
В HTML было введено скрытое поле именно для того, чтобы передавать нужную для программиста, но не нужную или не интересную для пользователя информацию на сервер. ASP .NET пользуется этими полями, при этом шифруя информацию (хотя опытный пользователь сможет ее расшифровать). Состояние отображения хранится в скрытом поле формы с идентификатором __VIEWSTATE.
Каким же образом генерируется это поле, что в нем хранится и когда оно читается при возврате формы? Чтобы это понять, надо более подробно рассмотреть жизненный цикл страницы. Каждый раз, когда на сервере генерируется страница, в первый раз или после постбэка, заново создается объект Page и все его элементы. Если свойство элемента управления декларировано на странице или меняется во время события инициализации, оно будет таким всегда.

Рис. 15.2.
Из картинки видно, что между событиями Init и Load при постбэке происходят еще два события: загрузка состояния отображения и загрузка данных постбэка.
И те, и другие читаются из тела запроса POST. Перед событием Render состояние отображения вновь записывается с помощью функции SaveViewState. Функция SaveViewState объекта рекурсивно вызывает ее же вложенных в нее элементов. При этом эта информация кодируется по алгоритму base-64. Во время отрисовки страницы создается скрытый элемент __VIEWSTATE. Следовательно, во время события Load или в обработчиках событий элементов управления можно изменять свойства страницы или любых ее элементов.
Свойство ViewState есть как у страницы, так и у всех элементов управления на ней.
Пусть у нас есть простая форма:
Во время первой загрузки страницы ничего связанного с сохранением состояния не происходит.
При нажатии на первую кнопку динамически меняется текст метки. Кнопка вызывает отправку данных на сервер, и во время второго жизненного цикла выполняется функция RaisePostBackEvent, которая вызывает обработчик:
protected void Button1_Click(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToLongTimeString(); }
Измененное состояние метки сохраняется в свойстве ViewState. Если теперь нажать на вторую кнопку, то сразу после инициализации страницы в текст метки будет загружаться текст, сохраненный в ViewState.
Если отключить возможность сохранения состояния, то текст метки вернется к своему пустому состоянию. То же самое произойдет и при нажатии на первую кнопку, но так как RaisePostBackEvent происходит после LoadPostBackData, значение, загруженное из ViewState, переписывается новым значением.
Состояние страницы доступно программисту, и в него можно добавлять дополнительные данные. Например, когда нужно было сортировать DataGrid, в переменную ViewState["sort"] записывалось выражение сортировки.
ViewState представляет собой коллекцию пар "ключ/значение", подобно объектам приложения и сессии. В него можно помещать только объекты с атрибутом Serializable. Свойство ViewState имеет тип System.Web.UI.StateBag, и синтаксис доступа к данным похож на доступ к значениям Hashtable.
Поле __VIEWSTATE может стать довольно большим (порядка десятков килобайт), например, когда в форме присутствует DataGrid или GridView. Эти элементы управления хранят в состоянии отображения все свое содержимое. И вся эта информация путешествует с клиента на сервер и обратно. Увеличивает это поле и элемент Wizard, и TreeView. В общем, чем больше возможностей и свойств, тем дороже приходится за это платить. Поэтому рассмотрим методы сокращения размера поля __VIEWSTATE. У каждого элемента управления есть свойство EnableViewState, которое по умолчанию равно True. Если установить его в False, то состояние данного элемента управления не будет записано в объект ViewState. Это свойство можно отключить и у всей страницы — с помощью атрибута EnableViewState директивы Page или программно:
Page.EnableViewState = false;
Такой же атрибут есть у директив MasterPage, Control.
Атрибут директивы Page EnableViewStateMac определяет, проводится ли машинный контроль аутентификации (MAC). Это контроль, гарантирующий, что состояние отображения не сфальсифицировано злонамеренными пользователями.
Хотя отключение EnableViewState позволяет уменьшить количество передаваемой информации, не всегда это можно делать безнаказанно. Если на странице есть DataGrid, который заполняется во время события Page_Load при условии if (!Page.IsPostBack), то есть при первой загрузке страницы, то после постбэка он просто исчезнет со страницы. Следовательно, при выключенном EnableViewState каждый раз необходимо читать данные из источника заново. Что выбрать, зависит от ситуации. В одних случаях бывает важнее сэкономить на времени загрузки страницы, в других — на соединении с базой данных.
Web-приложение и сессия, обработка глобальных событий
Понятие приложения только тогда можно применить к проекту, когда все его страницы работают с общей информацией. Когда пользователь регистрируется на сайте, все страницы подстраиваются под его настройки. Например, если приложение — электронный магазин, то выбранные товары помещаются в "корзину", которая "путешествует" вместе с пользователем и позволяет добавлять в нее новые товары.
Однако известно, что протокол HTTP изначально не поддерживает сессии. Обычно сервер посылает страницу в ответ на запрос, и на этом соединение обрывается. Хотя HTTP 1.1 поддерживает режим keep-alive, сервер не в состоянии определить, что запросы идут с одного и того же клиента. В ASP .NET при каждом соединении на сервере создается сессия, идентификатор которой обычно хранится в файле-cookie (или передается в командной строке, если это невозможно).
До сих пор мы рассматривали работу ASP .NET в пределах одной страницы. Нажали кнопку — получили результат. На практике при работе с web-приложениями к цели ведут десятки взаимосвязанных запросов, делающихся на разных страницах. Что объединяет страницы приложения в одно целое?
В ASP .NET есть специальный класс — HttpApplication, представляющий все приложение. Он контролирует его общее состояние и обрабатывает глобальные события.
В основном этот класс используется для хранения объектов уровня приложения. Он предоставляет словарь для хранения объектов, который доступен в любое время с любой страницы.
Также в ASP.NET присутствует другой тип окружения — сессия (объект Session класса HttpSessionState).
Понятие приложения только тогда можно применить к проекту, когда все его страницы работают с общей информацией. Когда пользователь регистрируется на сайте, все страницы подстраиваются под его настройки. Например, если приложение — электронный магазин, то выбранные товары помещаются в "корзину", которая "путешествует" вместе с пользователем и позволяет добавлять в нее новые товары.
Однако известно, что протокол HTTP изначально не поддерживает сессии. Обычно сервер посылает страницу в ответ на запрос, и на этом соединение обрывается. Хотя HTTP 1.1 поддерживает режим keep-alive, сервер не в состоянии определить, что запросы идут с одного и того же клиента. В ASP .NET при каждом соединении на сервере создается сессия, идентификатор которой обычно хранится в файле-cookie (или передается в командной строке, если это невозможно).
До сих пор мы рассматривали работу ASP .NET в пределах одной страницы. Нажали кнопку — получили результат. На практике при работе с web-приложениями к цели ведут десятки взаимосвязанных запросов, делающихся на разных страницах. Что объединяет страницы приложения в одно целое?
В ASP .NET есть специальный класс — HttpApplication, представляющий все приложение. Он контролирует его общее состояние и обрабатывает глобальные события.
В основном этот класс используется для хранения объектов уровня приложения. Он предоставляет словарь для хранения объектов, который доступен в любое время с любой страницы.
Также в ASP.NET присутствует другой тип окружения — сессия (объект Session класса HttpSessionState).
Сессия объединяет серию запросов с одного адреса в течение некоторого времени. В пределах сессии можно контролировать текущего пользователя, так что именно в сессии удобно отслеживать последовательность его действий. В сессии можно хранить данные, полученные из разных источников, которые относятся к пользователю, или даже объекты классов приложения.
Текущая сессия и приложение доступны с любой страницы через свойства Session и Application, так что получить доступ к ним очень просто.
Параметры сессии также доступны в виде словаря через индексатор со строковым параметром. Область видимости переменной сеанса — весь сеанс взаимодействия посетителя с приложением в конкретном окне браузера. Сеансом является период времени, когда пользователь находится на сайте. Он начинается, когда посетитель впервые заходит на сайт. Пользователь может закрыть браузер, и сервер не будет знать об этом. Поэтому в сессии существует таймаут, который по умолчанию равен 20 минутам. Если в течение этого времени пользователь не совершал активных действий на сайте, сессия считается закрытой. Для приложений, где потеря данных критична (например, финансовых), обычно таймаут уменьшают.
С каждой сессией связан 120-битный идентификатор. Он передается от сервера браузеру и обратно через cookie или через командную строку. В приложениях электронной коммерции в переменных сеанса может храниться корзина — то, что уже выбрал пользователь.
Так добавляется переменная сервера:
Session.Add("Username", "Tom"); Session["Username"]= "Tom";
Эти присваивания равносильны.
В сессии могут храниться переменные любых типов, в том числе пользовательские.
Запрос к данным сессии возвращает тип object, поэтому после получения переменной необходимо привести его к нужному типу:
Username= Session["Username"].ToString();
Таймаут страницы можно поменять:
Session.TimeOut = 5;
Явно завершить сеанс позволяет метод Abandon:
Session.Abandon;
Приложение выполняется на сервере. Новое приложение создается, когда хотя бы один пользователь обращается к сайту. Приложение завершается, когда сервер перезагружается или меняется его конфигурация. Следующая строка кода создает переменную приложения с именем Name:
Application["Name"] = "Myname"
Сессия объединяет серию запросов с одного адреса в течение некоторого времени. В пределах сессии можно контролировать текущего пользователя, так что именно в сессии удобно отслеживать последовательность его действий. В сессии можно хранить данные, полученные из разных источников, которые относятся к пользователю, или даже объекты классов приложения.
Текущая сессия и приложение доступны с любой страницы через свойства Session и Application, так что получить доступ к ним очень просто.
Параметры сессии также доступны в виде словаря через индексатор со строковым параметром. Область видимости переменной сеанса — весь сеанс взаимодействия посетителя с приложением в конкретном окне браузера. Сеансом является период времени, когда пользователь находится на сайте. Он начинается, когда посетитель впервые заходит на сайт. Пользователь может закрыть браузер, и сервер не будет знать об этом. Поэтому в сессии существует таймаут, который по умолчанию равен 20 минутам. Если в течение этого времени пользователь не совершал активных действий на сайте, сессия считается закрытой. Для приложений, где потеря данных критична (например, финансовых), обычно таймаут уменьшают.
С каждой сессией связан 120-битный идентификатор. Он передается от сервера браузеру и обратно через cookie или через командную строку. В приложениях электронной коммерции в переменных сеанса может храниться корзина — то, что уже выбрал пользователь.
Так добавляется переменная сервера:
Session.Add("Username", "Tom"); Session["Username"]= "Tom";
Эти присваивания равносильны.
В сессии могут храниться переменные любых типов, в том числе пользовательские.
Запрос к данным сессии возвращает тип object, поэтому после получения переменной необходимо привести его к нужному типу:
Username= Session["Username"].ToString();
Таймаут страницы можно поменять:
Session.TimeOut = 5;
Явно завершить сеанс позволяет метод Abandon:
Session.Abandon;
Приложение выполняется на сервере. Новое приложение создается, когда хотя бы один пользователь обращается к сайту. Приложение завершается, когда сервер перезагружается или меняется его конфигурация. Следующая строка кода создает переменную приложения с именем Name:
Application["Name"] = "Myname"
и глобальные объекты позволяют работать
Конфигурационные файлы, состояние отображения и глобальные объекты позволяют работать с приложением как с единым целым.
Основы ASP.NET 2.0
Пользование web-службой
В Интернете существует множество готовых web-служб. Сайты http://uddi.microsoft.com, http://www.webservicelist.com/ — каталоги различных сервисов. Чтобы получить информацию от web-службы, нужно только послать HTTP-запрос, в теле которого находится SOAP-сообщение. Запрос к службе http://www.webservicex.net/globalweather.asmx на получение прогноза погоды в Москве выглядит так:
POST /globalweather.asmx HTTP/1.1 Host: www.webservicex.net Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://www.webserviceX.NET/GetWeather"
Заголовок запроса отличается от запросов, которые обычно посылают браузеры, прежде всего полем Content-Type — text/xml; а не text/html; В теле запроса находится SOAP-сообщение.
Сервис в ответ оправляет XML-документ:
Hg (1011 hPa)
Чтобы сделать проект ASP .NET потребителем web-сервиса, первым делом в проекте надо создать web-ссылку на удаленный объект — web-сервис. Выберите в меню Website пункт Add Web Reference. Появится диалоговое окно.

увеличить изображение
Рис. 16.1.
Введите URL web-сервиса с параметром wsdl в текстовое поле www.webservicex.net/globalweather.asmx?WSDL. В файл web.config добавляется настройка приложения:
Чтобы определить доступные по этому адресу web-сервисы, используется алгоритм DISCO.
При этом создается файл globalweather.wsdl. WSDL (Web Service Discovery Language) — это язык описания web-сервисов. Это еще один тип XML-документов.
Создание web-ссылки добавляет в конфигурационный файл еще одну запись:
Чтобы облегчить работу с web-сервисами, используют прокси-классы. Они предоставляют разработчикам удобные функции и берут на себя преобразование их параметров в элементы XML, после чего посылают запрос web-сервису через Интернет.
Утилита wsdl поможет преобразовать его в прокси-класс:
wsdl globalweather.wsdl
Прокси-класс необходимо поместить в папку App_Code, после чего объекты этого класса можно создавать в коде любой страницы.
Программу wsdl можно запустить и удаленно:
wsdl http://www.webservicex.net/globalweather.asmx?wsdl
В созданном файле объявлен класс GlobalWeather, наследник System.Web.Services.Protocols.SoapHttpClientProtocol. Функции этого класса предназначены как для синхронного, так и для асинхронного вызова. Например, синхронная функция GetWeather запрашивает строковые параметры с названием города и страны и возвращает строку с XML-документом. В сервисе есть и другая функция, с помощью которой можно узнать доступные города для каждой страны:
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http:/ /www.webserviceX.NET/GetWeather", RequestNamespace="http://www.webserviceX.NET", ResponseNamespace="http://www.webserviceX.NET", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wr apped)] public string GetWeather(string CityName, string CountryName) { object[] results = this.Invoke("GetWeather", new object[] { CityName, CountryName}); return ((string)(results[0])); }
Это текст можно использовать на странице:
protected void Button1_Click(object sender, EventArgs e) { // создание экземпляра прокси-класса GlobalWeather gw = new GlobalWeather(); // запрос функции web-сервиса string xmlstring = gw.GetWeather("Moscow", "Russia"); XmlDocument doc = new XmlDocument(); // загрузка ответа в документ doc.LoadXml(xmlstring); // doc.ChildNodes.Item(0) — это XML-заголовок // doc.ChildNodes.Item(1) — тело XmlNode child = doc.ChildNodes.Item(1); XmlElement el = child["Temperature"]; lblTemp.Text += el.InnerText; }
SOAP
Для взаимодействия с web-сервисами применяется протокол SOAP, основанный на XML. Можно было бы использовать просто XML, но это слишком свободный формат, в нем каждый документ фактически создает свой язык. SOAP — это соглашение о формате XML-документа, о наличии в нем определенных элементов и пространств имен.
SOAP позволяет публиковать и потреблять сложные структуры данных, например DataSet. В то же самое время его легко изучить. Текущая версия SOAP — 1.2.
SOAP — это Простой Протокол Обмена Данными (Simple Object Access Protocol). SOAP создан для того, чтобы облегчать взаимодействие приложениям через HTTP. Это особый независимый от платформы формат обмена сообщениями через Интернет. Сообщение SOAP — это обычный XML-документ. Стандарт SOAP разрабатывает консорциум W3C.
SOAP-сообщение состоит из конверта (envelope), заголовка (header) и тела (body). Элементы body и envelope должны присутствовать всегда, а header необязателен. Элемент envelope — корневой. Элемент header может содержать специфичную для данного приложения информацию. В документе, сгенерированном web-сервисом, может присутствовать элемент ault, который описывает ошибку работы.
POST /WebSite5/WebService.asmx HTTP/1.1 Host: localhost Content-Type: application/soap+xml; charset=utf-8 Content-Length: length
В ASP .NET можно легко как создать web-службу, так и пользоваться готовой.
Создание web-сервиса
Создание web-сервиса немногим отличается от создания обычной страницы. Есть два варианта: можно создать отдельный проект или вставить web-сервис в существующий проект. В первом случае другие проекты должны создавать web-ссылку, чтобы обращаться к сервисам этого проекта. Файл web-сервиса имеет расширение asmx. Файл web-сервиса должен начинаться с директивы WebService. Класс web-сервиса может быть потомком класса System.Web.Services.WebService.
Если при объявлении web-сервиса вы породили его от класса System.Web.Services.WebService, то вы автоматически получаете доступ к глобальным объектам приложения ASP .NET Application, Context, Session, Server и User. Если же вы создавали класс web-сервиса как-то иначе — ничего страшного. Вы все равно можете получить доступ к вышеперечисленным свойствам с помощью соответствующих свойств статического HttpContext.Current.
Методы, которые сервис предоставляет для вызова с помощью SOAP-запросов, должны иметь атрибут WebMethod. У атрибута WebMethod существует 6 свойств, влияющих на работу метода.
Создадим новое приложение в VS .NET и добавим к нему файл web-сервиса Customers.asmx.
Файл nw.asmx содержит единственную строку — директиву WebService, которая утверждает, что этот файл — web-сервис. Этот файл меняться не будет:
<%@ WebService Language="C#" CodeBehind="~/App_Code/Customers.cs" Class=" Customers " %>
У директивы WebService всего 4 возможных атрибута. CodeBehind, который раньше был атрибутом и директивы Page, определяет физический путь к файлу отделенного кода.
Атрибут Class обязателен и определяет класс, который реализует функциональность web-сервиса. Debug и Language аналогичны тем же атрибутам директивы Page:
Файл с расширением .asmx — точка входа создаваемого web-сервиса.
Класс System.Web.Services.WebService, которые обычно наследуется класс сервиса, предоставляет доступ к глобальным объектам Application и ViewState.
Весь код web-сервиса будет располагаться в codebehind-файле Service.asmx.cs. Изначально этот файл (созданный в Visual Studio .NET) имеет следующий вид:
<%Class="WebService" %>
using System; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols;
///
public WebService () {
//Uncomment the following line if using designed compo- nents //InitializeComponent(); }
[WebMethod] public string HelloWorld() { return "Hello World"; }
}
Атрибут WebServiceBinding удостоверяет соответствие откликов web-сервиса WS-I Basic Profile 1.0 release требованиям организации WS-I (Web Services Interoperability organization), которая занимается вопросами межплатформенной совместимости web-сервисов.
Метод HelloWorld создан Visual Studio в качестве примера начинающим разработчикам.
Web-сервис может состоять из множества классов.
Однако только один класс в web- сервисе может иметь методы, помеченные атрибутом WebMethod (которые можно вызывать через SOAP-запросы).
Когда страница web-сервиса запрашивается в браузере, он возвращает автоматически генерируемую страницу помощи по данному сервису. Откроем в браузере страницу WebService.asmx. В браузере появится страница:

Рис. 16.2.
ASP .NET для отображения web-сервиса использует файл шаблона DefaultWsdlHelpGenerator.aspx, расположенный в папке <%SYSTEM_ROOT%\Microsoft.NET\Framework\
[WebService(Namespace = "http://Lection-16.asp2.intuit. org/")]
Кроме того, в атрибуте WebService можно задать свойства Name и Description, и они появятся на странице помощи по web-сервису.
Также представлены примеры ответов вызова web-метода.
Протестируем нашу работу с помощью страницы web-сервиса:
От такого web-сервиса нет особенной пользы, поэтому создадим новый сервис nw и вместо метода HelloWorld напишем метод, который обращается к базе данных Northwind и возвращает DataSet:
[WebService(Name="Northwind web service", Description = "Web-сер- вис для работы с клиентами", Namespace = "http://intuit.asp2.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class nw : System.Web.Services.WebService {
public nw() { } string strConn = @"Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True"; [WebMethod(MessageName = "Get Orders of Customers", Description = "Web-метод для работы с заказами", CacheDuration = 600)] public DataSet GetCustOrders(string CustomerID) { SqlConnection myConn = new SqlConnection(strConn); SqlDataAdapter myData = new SqlDataAdapter("CustOrdersOrdersDetails", myConn); myData.SelectCommand.CommandType = CommandType.StoredProcedure; myData.SelectCommand.Parameters.Add(new SqlParameter("@CustomerID", SqlDbType.Char, 5)); myData.SelectCommand.Parameters["@CustomerID"].Value = CustomerID;
DataSet ds = new DataSet(); myData.Fill(ds); ds.Tables[0].TableName = "Orders"; ds.Tables[1].TableName = "OrderDetails"; ds.Relations.Add(ds.Tables[0].Columns["OrderID"], ds.Tables[1].Columns["OrderID"]); return ds; }
Другие аргументы атрибуты WebMethod:
1. CacheDuration определяет промежуток времени в секундах, на которое кэшируется web-сервис. По умолчанию равно 0, что значит, что кэширование отключено.
В этом объявлении значение, возвращаемое методом GetCustOrders, кэшируется на 10 минут.
2. Description — описание метода, которое выводится на странице сервиса под ссылкой на страницу метода.
3. EnableSession позволяет включить поддержку сессий. По умолчанию поддержка сессий в web-сервисах отключена. Чтобы включить ее, определите web-метод следующим образом:
[WebMethod(EnableSession=true)]
4. MessageName определяет уникальное имя метода. Позволяет использовать перегруженные функции с одним именем, но разными сигнатурами.
5. TransactionOption управляет поддержкой транзакций. По умолчанию она отключена. Web-сервисы ограниченно поддерживают транзакции, то есть веб-сервис может порождать транзакцию, но при этом не может быть участником другой транзакции. Возможные значения аргумента — Disabled, NotSupported, Supported, Required, и RequiresNew. Если вызывается web-метод с TransactionOption, установленным в Required или RequiresNew, а в нем вызывается другой web-метод с такими же установками, каждый из этих методов инициирует свою транзакцию.
Метод GetCustOrders возвращает тип DataSet. Посмотрим, как он помещается в SOAP:
-
Это почти готовая схема xsd. Из нее можно, например, сгенерировать класс бизнес-логики.
Использовать наш сервис можно и удаленно, и из приложения, в котором он находится.
Создадим форму, которая будет отображать полученный DataSet в элементе управления GridView:
Имя компании выбирается из выпадающего списка. После нажатия на кнопку вызывается обработчик:
protected void Button1_Click(object sender, EventArgs e) { localhost.Northwindwebservice orders = new localhost.Northwindwebservice(); GridView1.DataSource = orders.GetCustOrders(DropDownList1.SelectedValue); GridView1.DataBind(); }
Стать потребителем этого сервиса могло бы и обычное Windows-приложение, написанное на C++, C# или Visual Basic.Web-сервисы тоже могут пользоваться услугами других web-сервисов.
Web-службы
В процессе эволюции Интернета появилась необходимость в создании распределенных приложений. Приложения, установленные на компьютере, обычно используют библиотеки, размещенные на нем. Одну библиотеку могут использовать несколько программ. Можно ли размещать аналоги библиотек в Интернете, чтобы разные сайты могли их вызывать? Оказывается, да.
Предприятия на своих страницах предоставляют разнообразную информацию. Например, со своего сайта www.Ford.com компания "Форд" публикует информацию о моделях и ценах. Дилер этой компании хотел бы иметь эту информацию и на своем сайте. Web-служба позволяет сайту-потребителю получать информацию с сайта-поставщика. Сайт-потребитель показывает эту информацию на своих страницах. Код для генерации этой информации написан один раз, но может использоваться многими потребителями. Данные представлены в простом текстовом виде, поэтому ими можно пользоваться независимо от платформы.
Web-сервисы широко используются и в Desktop, и в Интернет-приложениях. Они сами по себе являются не приложениями, а источниками данных для приложений. У них отсутствует пользовательский интерфейс. Web-сервисами необязательно пользоваться через сеть — они могут быть частью проекта, в котором используются.
Web-сервисы — это функциональность и данные, предоставляемые для использования внешними приложениями, которые работают с сервисами посредством стандартных протоколов и форматов данных. Web-сервисы полностью независимы от языка и платформы реализации. Технология Web-сервисов является краеугольным камнем программной модели Microsoft .NET.
Это дальнейшее развитие компонентного программирования CORBA и DCOM. Однако для использования таких компонентов необходимо регистрировать их в системе потребителя. Для web-служб это не требуется. Компоненты хорошо работают в локальных сетях. Протокол HTTP не приспособлен для вызова удаленных процедур (RPC). Даже в одной организации часто используются разные операционные системы, которые могут взаимодействовать только через HTTP.
Было предпринято несколько попыток создания языка коммуникации между разнородными системами — DCOM, CORBA, RMI, IIOP. Они не получили всеобщего распространения, так как каждый из них продвигался разными производителями и поэтому был привязан к технологиям конкретного изготовителя. Никто не хотел принимать чужой стандарт. Чтобы выйти из этой дилеммы, несколько компаний договорились выработать независимый от производителя стандарт обмена сообщениями через HTTP. В мае 2000 года компании IBM, Microsoft, HP, Lotus, SAP, UserLand и другие обратились к W3C и выдвинули SOAP в качестве кандидата на такой стандарт. SOAP произвел революцию в области разработки приложений, объединив два стандарта Интернета — HTTP и XML.
Эта лекция затронула основы создания
Эта лекция затронула основы создания и потребления web-сервисов ASP .NET. Web-сервисы помогают обмену данными между фирмами и в локальных сетях, независимо от операционной системы.
Основы ASP.NET 2.0
Аутентификация и авторизация
Важная часть многих web-приложений — возможность контролировать доступ к ресурсам. Безопасность проекта вращается вокруг двух концепций — аутентификации и авторизации. Аутентификация — процесс определения личности пользователя. Авторизация — процесс определения прав пользователя на доступ к определенным ресурсам, на просмотр некоторых разделов, на возможность редактирования информации и так далее.
Для авторизации пользователь вводит пользовательское имя, под которым зарегистрирован(а), и пароль. После этого приложение определяет возможность доступа к ресурсам, а также может видоизменять как внешний вид с помощью тем, так и содержание генерируемых страниц. К примеру, в форуме записи могут показываться в виде дерева или линейно.
В ASP .NET 2.0 аутентификацией управляют с помощью службы Membership, которая позволяет определить различные виды членства на сайте. Информацию о членах можно хранить в различных местах — в базах данных, текстовых файлах или даже в учетных записях Windows. Конфигурировать членство можно индивидуально для каждого пользователя или на основе ролей с помощью сервиса Role Manager. Роли облегчают конфигурирование, так как можно создавать роли и потом добавлять пользователей к готовым ролям. Любому пользователю может принадлежать любое количество ролей.
По умолчанию службы используют провайдера AspNetSqlProvider. В таком случае ASP .NET автоматически создает базу данных ASPNETDB.MDF в директории проекта App_Data, когда запускается команда ASP.NET Configuration — или программно, или с помощью элементов управления группы Login задействуются службы Membership или Role Manager.
Служба Membership также обеспечена провайдером, работающим с Active Directory. Role Manager может работать с провайдером, связанным с Authorization Manager операционной системы Widnows 2003. API, связанное со службой, позволяет настроить ее и на использование пользовательского провайдера.
Роли имеют определенные права. Например, администратор сайта может изменять настройки, редактировать членство других пользователей. Обычный пользователь с ролью Friend может просмотреть частные альбомы администратора, а неавторизованный пользователь — только публичные. Эта модель реализована в приложении Starter Kit. В этом приложении роли создаются во время первого запуска:
void Application_Start(object sender, EventArgs e) { SiteMap.SiteMapResolve += new SiteMapResolveEventHandler(AppendQueryString); if (!Roles.RoleExists("Administrators")) Roles.CreateRole("Administrators"); if (!Roles.RoleExists("Friends")) Roles.CreateRole("Friends"); }
Из этого примера видно, что доступ к ролям можно получить с помощью класса Roles. Это не глобальная переменная, а статический класс, доступный из любого файла проекта. Создание роли выражается в том, что в базе ASPNETDB.MDF в таблице Roles появляется новая запись.
Создать пользователей и назначить им роли можно во встроенном приложении ASP .NET Configuration. Информация о пользователях хранится в таблицах aspnet_Users, aspnet_UsersInroles, aspnet_Membership. Пароли хранятся в зашифрованном с помощью хэш-функции виде.
Даже администратор не может его подсмотреть. Пароль, который вводится в момент аутентификации, тоже хэшируется и сравнивается со значением в базе. Хранение в незашифрованном виде — это угроза безопасности.
Любой пользователь может зарегистрироваться, но при этом не получит роли и у него не будет новых прав, пока администратор не назначит ему роли.
В этом приложении можно также создавать правила доступа.
Настройки конфигурации служб Membership и Role Manager, конечно же, записываются в файл Web.config:
Таким образом включается служба Role Manager.
Элемент authentication mode определяет способ аутентификации. Если это Forms, то свои имя и пароль пользователь вводит в форме. В локальной сети (интранет) можно аутентифицировать пользователей по их учетной записи, тогда его значение ставится как Windows.
С помощью элемента authentication запускается служба Membership:
Другие доступные значения — Passport и None.
При значении Passport пользователи авторизуются с помощью паспорта от Microsoft.
При аутентификации с помощью форм пользователи получают доступ к страницам в зависимости от данных, введенных на форме. До входа на сайт пользователь считается анонимным и используется анонимная аутентификация. После того, как он прошел аутентификацию, пользователь получает файл-cookie, который используется для последующих запросов.
Всего у элемента forms 8 возможных атрибутов:
| name | Определяет имя файла- cookie, который посылается пользователям после аутентификации. По умолчанию он называется .ASPXAUTH |
| loginUrl: | URL страницы, с которой можно войти в систему. По умолчанию это Login.aspx |
| protection: | Уровень защиты файла- cookie на пользовательской машине. Возможные значения — All, None, Encryption, и Validation |
| timeout: | Время, по истечении которого cookie устаревает. Значение по умолчанию — 30 минут |
| path: | Путь к файлам cookie |
| requireSSL: | Нужно ли шифровать данные по протоколу SSL |
| slidingExpiration: | Если True, то cookie устаревает через период времени timeout после последнего запроса. Иначе — через период времени timeout после создания |
| cookieless: | Место хранения идентификатора пользователя. Значение по умолчанию useDeviceProfile |
В данном случае это одна страница Admin.aspx. Первая часть авторизации разрешает доступ к ней пользователям в роли администратора Admin. Вторая запрещает доступ всем остальным пользователям.
Если элемент system.web находится в корневом узле файла, то вложенный в него узел authorization определяет настройки доступа ко всему сайту.
Когда неавторизованный пользователь пытается получить доступ к странице, открывается форма, определенная в атрибуте forms loginUrl. Если он введет имя и пароль пользователя, который имеет доступ к странице, то она откроется, иначе опять ему или ей будет показана форма логина.
Часто бывает нужно сконфигурировать с точки зрения безопасности систему навигации. Это значит, что меню не должно показывать те страницы, для просмотра которых пользователь не авторизован:
Здесь атрибут securityTrimmingEnabled, установленный в true, заставляет провайдера карты сайта фильтровать узлы в зависимости от роли пользователя. Это значит, что в элементах навигации будут видны только доступные страницы.
Член User страницы позволяет получить доступ ко всей информации, касающейся текущего пользователя.
Метод IsInRole определяет, принадлежит ли пользователь к роли:
if (User.IsInRole("Admin")) Page.Title = "Hello, Administrator!";
Свойство Identity дает информацию об аутентификации пользователя:
if (User.Identity.IsAuthenticated) //выполнить код, если пользователь легален
User.Identity.AuthenticationType показывает способ авторизации, установленный в Web.config.
Можно ограничить доступ не только к страницам, но и к частям страниц.
Элементы управления группы Login
Мы уже создавали формы регистрации. Это было только упражнение, так как элементы управления этой группы могут брать на себя регистрацию и авторизацию пользователей, восстановления пароля и другие функции, взаимодействуя при этом с системой Membership и Roles. Группа Login находится в панели инструментов.
Элемент управления LoginName позволяет показать имя пользователя:
Заходите еще,
Отображаемый текст можно форматировать с помощью FormatString:
LoginStatus — это умный элемент управления. Если пользователь не аутентифицирован, отображается гиперссылка Login на страницу входа на сайт. Если пользователь авторизован, это ImageButton с командой Logout. Если ее нажать, то пользователь выходит из системы. Текст ссылок можно менять в свойствах LoginText и LogoutText или использовать изображения:
Нажатие на ссылку Logout в этом случае перенаправит пользователя на страницу Default.aspx.
Элемент управления LoginView состоит из двух шаблонов: AnonymousTemplate и LoggedInTemplate.
Который из них используется для отображения, зависит от того, просматривает ли страницу анонимный пользователь или авторизованный. На странице default.aspx Starter Kit это единственный элемент на странице Registration.aspx:
Анонимному пользователю предоставляется возможность зайти или зарегистрироваться, а авторизованный видит приветствие со своим именем.
Кроме того, с помощью
Шаблоны групп просматриваются по порядку, и показывается тот из них, что найден первым из групп, в которые входит пользователь. Например, если она принадлежит к группам Moderator и ClubMember, будет показан шаблон Moderator. Роли можно перечислять через запятую, тогда шаблон применим ко всем указанным группам:
Остальные элементы управления этой группы — формы и мастера — Login, PasswordRecovery, ChangePassword.
CreateUserWizard позволяет создавать пользователей, используя службу Membership. Естественно, в нем происходит валидация введенных данных. Например, длина пароля должна быть не меньше 7 знаков и в нем должен присутствовать хотя бы один символ — не буква и не цифра. Обязательно заполнение контрольного вопроса и ответа, по которым можно будет восстановить пароль, если он забыт, или изменить пароль:
ChangeUser
Персонализация
Многие сайты собирают информацию о пользователях, чтобы подстроить показ информации под их личные вкусы. Часто для этого используют файлы-cookie, объекты приложения и сессии.
В ASP .NET 2.0 появились новые удобные способы хранить пользовательскую информацию. Это функция персонализации. Механизм персонализации позволяет установить прямую связь между пользователем и всеми данными, относящимися к нему. При этом его настройки хранятся не в файлах-cookie на компьютере пользователя, которые он может стереть, а на сервере. Их можно поместить в любое хранилище данных.
Модель персонализации проста и расширяема.
В файле web.config содержится информация о том, какие данные о пользователе необходимо хранить. Она записывается в секции
Профиль персонализации может хранить данные об авторизированном пользователе, но может обслуживать и анонимного пользователя. По умолчанию анонимная персонализация выключена. Чтобы ее включить, нужно в файле web.config создать запись
(так же в секции
Когда анонимная персонализация включена, ASP .NET хранит уникальный идентификатор для каждого анонимного пользователя.
Он посылается вместе с любым запросом. Идентификатор хранится в файле-cookie пользователя, а дополнительные данные, которые удалось собрать о его предпочтениях, — на сервере. По умолчанию имя файла-cookie — .ASPXANONYMOUS. Его можно поменять с помощью атрибута cookieName элемента anonymousIdentification:
Время хранения файла-cookie в минутах определяется атрибутом cookieTimeout.
По умолчанию оно равно 100 000 минутам (69,4 дня).
От использования cookie можно отказаться, например, написав
cookieless="UseUri"
В таком случае идентификатор передается через строку URL:
cookieless="AutoDetect"
В этом случае определяются настройки пользователя. Если возможность хранить cookie выключена, используется строка URL.
Анонимный идентификатор по своей сути представляет собой GUID (32-байтное число, алгоритм генерации которого гарантирует глобальную уникальность). Свойство AnonymousId объекта Request страницы позволяет получить к нему доступ.
Для того чтобы определить, какие данные можно хранить для анонимного пользователя, в элемент add name определяют атрибут allowAnonymous:
Ресурсы проекта
"Для каждого предусмотрен его личный конец света."
Хенрик Ягодзиньский
Создание многоязычных web-сайтов имеет особенно большое значение в неанглоговорящих странах. Изначально ASP .NET настроена на английский язык, причем на его американскую разновидность. Причины этого очевидны. Но платформа .NET поддерживает концепцию информации о культуре, а строки хранятся в формате Unicode, что позволяет писать их на множестве языков. Глобализация — это создание приложений, способных работать в разных культурных средах. Локализация — создание ресурсов для работы с конкретной культурой. Ресурсы должны быть отделены от программного кода.
Классы для работы с информацией о культурах заключены в пространстве имен Globalization. Класс CultureInfo содержит свойство CurrentCulture, которое позволяет узнать все данные о текущей культуре — форматы отображения, календарь, кодовую страницу и другие.
Файлы ресурса содержат строки, которые могут быть написаны на разных языках для различных культурных сред. Формат этих файлов — XML, следующий специальной схеме Microsoft ResX. Файлы .resx автоматически включаются в сборку для использования на страницах. Кроме строк, файлы ресурса могут содержать картинки и другие файлы. Их можно использовать для создания многоязычных приложений. В отличие от предыдущих версий, ресурсы не нужно компилировать вручную в сборку-сателлит — ASP .NET 2.0 делает это сама.
В папке App_GlobalResources хранятся файлы ресурсов, названия которых соответствуют культурной схеме.
Например, ресурс для русской культуры называется Resource.ru-ru.resx, для финской — Resource.fi-FI.resx. Ресурс с нейтральной культурой называется просто Resource.resx. Ресурсы доступны для всех страниц и пользовательских элементов управления. Промежуточное расширение следует стандарту .NET на региональные стандарты — состоит из главного и вспомогательного тегов.
В папке \App_LocalResources хранятся локальные файлы ресурсов для конкретных страниц. Название файла ресурса формируется из имени страницы, кода культурной среды и расширения resx. Например, default.aspx.de.resx — это файл ресурса на немецком языке для страницы default.aspx.
Протокол HTTP позволяет браузерам посылать список предпочитаемых языков на сервер. В браузере можно настроить предпочтительные языки web-страниц. ASP .NET позволяет автоматически модифицировать культуру страницы в зависимости от первого языка в списке. Для этого атрибуту Culture директивы Page нужно присвоить значение auto. Так же обстоит дело у атрибута UICulture — он определяет культуру пользовательского интерфейса. Менеджер ресурсов ищет строки и другие ресурсы в файле с тем расширением, которое определено в атрибуте UICulture. Формат отображения дат, чисел и денежной информации определяется атрибутом Culture.
Если поместить на страницу элемент управления Calendar, он будет в том формате, который соответствует культурной информации, связанной с данным языком. Числа и денежные единицы тоже будут выводиться в формате этой культуры.
Свойства Culture и UICulture — страницы строковые и принимают значения в длинном формате, например, "English (United States)":
<%@ Page Language="C#"Culture="Auto" UICulture="Auto" %>
Если первый язык в списке соответствует культуре, которую поддерживает ASP .NET, в самом начале жизненного цикла страницы эта культура становится текущей. Если есть файлы ресурса на этом языке, с помощью класса Resource можно получить доступ к строкам файла ресурсов с соответствующим расширением, иначе ResourceManager будет читать из файлов ресурсов по умолчанию.
Загрузить строку из файла ресурсов можно по-разному. Первый способ — использовать класс Resource. Предварительно в App_Global Resources нужно создать файлы Resource.resx и Resource.ru-RU.resx со строками.
Resource.resx
| Name | Value |
| Answer | Good morning, |
| PageTitle | Sample Globalization Page |
| Question | What is your name? |
| Name | Value |
| Answer | Привет |
| PageTitle | Пример глобализации ASP .NET |
| Question | Как Вас зовут? |
Второй способ позволяет статически выводить информацию из локальных файлов ресурсов:
<%@ Page Language="C#" AutoEventWireup="true" Culture="auto:en- US" meta:resourcekey="PageResource1" UICulture="auto:en-US" %>
В LocalizeImp_cs.aspx.resx содержится строка ButtonResource1.Text со значением Convert, в LocalizeImp_cs.aspx.de.resx со значением Konvertieren, в файлах ресурсов для других языков — перевод слова на эти языки.
Посмотрите пример полностью в QuickStart: C:\Program Files\ Microsoft Visual Studio 8\SDK\v2.0\QuickStart\aspnet\samples\localization\LocalizeImp_cs.
и профили пользователей, несомненно, облегчат
Возможности глобализации, авторизации и профили пользователей, несомненно, облегчат жизнь программистам, создающим web-сайты. Они решают важную задачу индивидуальной работы для каждого пользователя. Все то, что раньше приходилось делать вручную, теперь реализовано и отлажено самими создателями ASP .NET.
Основы ASP.NET 2.0
Callback и его отличие от Postback
Перед тем как рассмотреть примеры новой возможности обратного вызова, посмотрим на работу механизма возврата данных формы на сервер (Postback) типичной страницы ASP .NET.
Когда на странице инициируется событие отправки данных, запускается большой и сложный механизм.
- Init
- Load State
- Process Postback Data
- Load
- Postback Events
- Save State
- PreRender
- Render
- Unload
В обычной ситуации постбэка событие на странице, например, щелчок на кнопке формы, вызывает отправку запроса HTTP POST web-серверу. Сервер обрабатывает запрос обработчиком IPostbackEvent Handler и запускает весь жизненный цикл страницы заново. Она загружает состояние страницы, обрабатывает введенные данные, обрабатывает события отправки, сохраняет состояние страницы, генерирует страницу заново и отправляет ее браузеру клиента. Страница полностью перезагружается, это занимает время и использует дополнительный трафик.
С другой стороны, можно задействовать возможность обратного вызова, как показано на рисунке.
В этом случае событие (например, нажатие на кнопку) вызывает выполнение скрипта-обработчика у клиента (функция JavaScript), который посылает асинхронный запрос web-серверу.
На сервере обработчик ICallbackEventHandler пропускает запрос через процесс, похожий на тот, который используется при постбэке, но некоторые крупные этапы этого процесса (например, отрисовка страницы) пропускаются. После того как информация загружена, результат возвращается к объекту, вызвавшему обратный вызов. Код скрипта вставляет эти данные в web-страницу, используя возможности JavaScript делать это без обновления страницы. Количество фаз жизненного цикла сокращается до 6:
- Init
- Load State
- Process Postback Data
- Load
- CallBack Event
- Unload
Чтобы понять, как это работает, посмотрите на простой пример в следующем разделе.
Callback с параметрами
Теперь создадим страницу, которая использует обратный вызов с параметром. Наверху страницу поставим выпадающий список городов, который заполняется из web-сервиса, кнопку и строку ввода только для чтения для результата обратного вызова.
Страница просит выбрать город и вызывает серверный скрипт, чтобы запустить запрос к XML web-сервису на сервере. Web-сервис возвращает прогноз погоды для данной местности в текстовом формате:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Callback.aspx.cs" Inherits="Callback" %>
using System; using System.Xml;
public partial class Callback : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler { string _callbackResult; protected void Page_Load(object sender, EventArgs e) { GlobalWeather ws = new GlobalWeather(); string results = ws.GetCitiesByCountry("Russia"); XmlDocument doc = new XmlDocument(); doc.LoadXml(results); XmlNode child = doc.ChildNodes[0]; foreach (XmlElement el in child.ChildNodes) { XmlElement city = el["City"]; DropDownListCity.Items.Add(city.InnerText); } string cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "GetTempFromServer", "context"); string cbScript = "function UseCallback(arg, context)" + "{" + cbReference + ";" + "}"; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallback", cbScript, true); } public void RaiseCallbackEvent(string eventArg) { GlobalWeather ws = new GlobalWeather(); _callbackResult = ws.GetWeather(eventArg, "Russia").ToString(); XmlDocument doc = new XmlDocument(); doc.LoadXml(_callbackResult); XmlNode child = doc.ChildNodes.Item(1); XmlElement el = child["Temperature"]; _callbackResult = el.InnerText; } public string GetCallbackResult() { return _callbackResult; } }
Для работы этого примера нужно создать web-ссылку на сервис "http://www.webservicex.net/globalweather.asmx". Как работать с web-сервисами, описывалось в лекции 15.
Разница с клиентским обратным вызовом в том, что этот пример отправляет функции обратного вызова параметр.
Это делается в функции JavaScript GetTemp() на странице .aspx:
function GetTemp() { var City = document.forms[0].DropDownListCity.value; UseCallback(City, ""); }
Функция JavaScript читает значение, выбранное в DropDownListCity, и использует в качестве аргумента функции обратного вызова. Этот пример, как и предыдущий, обновляет страницу не полностью, а только необходимые ее части.
Использование JavaScript
В лекции 1 мы создали страницу, которая показывала время на сервере. Если пользователь находится в другом часовом поясе, время на его часах будет другое. Можно ли ее переделать, чтобы время совпадало с часами клиента? Ответ на этот вопрос — положительный. В страницу можно встроить код на JavaScript, который будет работать при загрузке страницы. Текст у метки менять нельзя, поэтому используем TextBox. Так как он — только для чтения и ширина границы равна 0, отличить его от метки сложно:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="time.aspx.cs" Inherits="time" %>
Свойство класса Page ClientScript позволяет определять для страницы клиентские сценарии.
Метод RegisterClientScriptBlock задает скрипт, который будет встроен в текст страницы:
protected void Page_Load(object sender, EventArgs e) { string myScript = @"function Show() { document.forms[0]['ClientTime'].value=Date(); }"; if (!Page.ClientScript.IsClientScriptBlockRegistered("MyScript")) Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyScript", myScript, true); }
Первый аргумент — тип данной страницы, второй — идентификатор скрипта, который позволит отличить его от других скриптов, третий — текст сценария. Четвертый параметр — булевский, если он равен True, то теги будут автоматически окружать текст функции. Страница, которая получится, обновляет время при каждом нажатии на кнопку.
Ее HTML-код выглядит так:
Скрипт заключен в комментарии, чтобы все работало на старых браузерах. Он включен в текст до элементов управления.
Метод RegisterStartupScript похож на предыдущий, и отличие заключается в том, что скрипт выполняется при загрузке страницы, но после отображения всех элементов. Сам скрипт находится в конце описания формы. Парсер JavaScript не может обратиться к элементам, если они не описаны до функции. Если мы напишем скрипт, которые читает данные из формы, то попытка отображения страницы вызовет ошибку времени выполнения:
string myScript1 = @"alert(document.forms[0]['ClientTime'].value);"; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "AlertScript", myScript1, true);
Значение поля в момент отображения скрипта еще не определено.
Поэтому нужно вызывать RegisterStartupScript:
string myScript1 = @"function Message() {alert(document.forms[0]['ClientTime'].value);}"; Page.ClientScript.RegisterStartupScript(this.GetType(), "AlertScript", myScript1, true);
Метод RegisterClientScriptInclude позволяет подключить внешний файл JavaScript. Например,
Page.ClientScript.RegisterClientScriptInclude("myKey", "ExternJavaScriptCode.js");
создает на выданной странице код
В этих примерах мы использовали не серверные командные кнопки, а элементы управления HTML. Причина заключается в том, что нажатие на командную кнопку отправляет форму на сервер. Событие OnClick выполняется на сервере. А в JavaScript существует свой OnClick. Как же его вызвать? Свойство Attributes позволяет обратиться к атрибутам элемента, даже тем, которые не соответствуют встроенным свойствам:
return false нужно писать обязательно, иначе форма будет отправлена на сервер.
Эти функции можно применить к любым серверным элементам:
public static void AddConfirmMessage(WebControl ctl, string message) { ctl.Attributes.Add("onclick", "if ( ! confirm( '" + message + "' )) return false; "); }
public static void AddPopupMessage(WebControl ctl, string mes- sage) { ctl.Attributes.Add("onclick", "alert( '" + message + "'); "); }
Элемент управления FileUpload
Формы HTML позволяют загружать пользовательские файлы на сервер. Для этого нужно установить атрибут enctype как "multipart/form-data" и в нем должен находиться элемент . Элемент управления FileUpload облегчает эту работу. Нужно вставить его в форму, а enctype установится автоматически. Элемент состоит из строки ввода и кнопки с надписью Browse. Процесс загрузки начинается после подачи формы на сервер, обычно для этого вставляют еще одну кнопку:
После того как файл загружен, FileUpload позволяет узнать его свойства. Файл находится в кэше сервера, пока не будет сохранен на диск методом SaveAs:
protected void UploadButton_Click(object sender, EventArgs e) { if (this.FileUpload1.HasFile) { try { FileUpload1.SaveAs("c:\\Uploads\\" + FileUpload1.FileName); Message.Text = "Имя файла: " + FileUpload1.PostedFile.FileName + "
" + FileUpload1.PostedFile.ContentLength + " кб
" + "Content type: " + FileUpload1.PostedFile.ContentType; } catch (Exception ex) { Message.Text = "Ошибка: " + ex.Message.ToString(); } } }
Процесс сохранения может вызвать исключения, поэтому он заключен в блок try-catch.
Свойство PostedFile имеет тип HttpPostedFile. Можно перенаправить содержимое загруженного файла в файловый поток с помощью свойства InputStream.
MultiView
Элемент управления MultiView позволяет создавать несколько представлений одной страницы и переключаться с одного на другой. MultiView состоит из элементов View, в которых находится часть страницы. В каждый момент времени видимым является один из элементов View. Это определяется свойством ActiveViewIndex.
Например, можно создать многоязычную страницу. Пользователь сам выбирает нужный ему язык:
Information about over 8800 products and services.
Wir stellen zur Eur VerfЯgung Informationen von Яeber 8800 Waren und Leistungen.
Предоставляем информацию о свыше чем 8800 товарах и услугах!
Переключение между представлениями происходит в обработчике списка переключателей RadioButtonList1:
protected void RadioButtonList1_SelectedIndexChanged(object sender, EventArgs e) { MultiView1.ActiveViewIndex = RadioButtonList1.SelectedIndex; }
Простой пример использования Callback
Посмотрим на простую страницу ASP .NET, которая использует эту возможность. В этом примере на странице есть кнопка HTML и серверный элемент управления TextBox.
Идея примера в том, что когда пользователь щелкает на кнопке на форме, запускается служба обратного вызова и в текстовое поле записывается случайное число:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SimpleCallback.aspx.cs" Inherits="SimpleCallback" %>
Суть происходящего в том, что страница посылает асинхронный запрос функции класса страницы. Получив ответ от этой функции, клиентский скрипт помещает полученное значение в строку ввода, не обновляя при этом страницы.
Запускает весь процесс функция JavaScript GetNumber — обработчик щелчка на кнопке.
Функция GetRandomNumberFromServer() находится на обратном конце процесса и записывает результат обратного вызова в Textbox1.
Класс этой страницы не только наследуется от Page, но и реализует интерфейс System.Web.UI.ICallbackEventHandler:
public partial class SimpleCallback : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler { private string _callbackResult = null; protected void Page_Load(object sender, EventArgs e) { string cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "GetRandomNumberFromServer", "context"); string cbScript = "function UseCallback(arg, context)" + "{" + cbReference + ";" + "}"; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallback", cbScript, true); } public void RaiseCallbackEvent(string eventArg) { Random rnd = new Random(); _callbackResult = rnd.Next().ToString(); } public string GetCallbackResult() { return _callbackResult; } }
В этом интерфейсе определены 2 метода, которые необходимо реализовать, — RaiseCallbackEvent и GetCallbackResult, обе работают с запросами клиентских скриптов.
RaiseCallbackEvent позволяет получить со страницы данные, правда, только строкового типа. GetCallbackResult возвращает результат клиентскому скрипту, в данном случае GetRandomNumberFromServer — именно она зарегистрирована в качестве получателя результата.
Обработчик Page_Load включает создание функции, которая будет управлять запросами и ответами на стороне клиента.
Функция, которая ставится на клиенте для возможности обратного вызова, называeтся UseCallback(). Эта строка затем помещается на web-страницу, используя функцию Page.ClientScript.RegisterClientScriptBlock. Убедитесь, что имя, которое вы применяете здесь, такое же, как и в клиентской функции JavaScript:
В результате получается страница, которая при нажатии на кнопку обновляет содержание текстовой строки, но не отрисовывает всю страницу. Есть лишь одно ограничение — здесь используется XmlHTTP и поэтому клиентский браузер должен его поддерживать (Internet Explorer 6.0, Mozilla FireFox 1.5 и Opera 9.0 поддерживают). Так это или нет, можно узнать с помощью свойств SupportsCallBack и SupportsXmlHTTP:
if (Page.Request.Browser.SupportsXmlHTTP == true) { }
Wizard
Как и MultiView, элемент управления Wizard (Мастер, Волшебник) может создать последовательность шагов. Элемент управления Wizard позволяет вводить информацию в нескольких формах последовательно. Например, при регистрации основные сведения — имя и пароль — вводятся на первой форме. После того как эти данные успешно введены и прошли проверку на валидность, собираются дополнительные данные — адрес, телефон. На последней форме введенные данные можно показать в обобщенном виде для подтверждения.
Wizard описывается с помощью тега asp:Wizard, в который вложены элементы WizardStep.
Внутри элемента управления Wizard находится MultiView, но в нем есть готовая функциональность по переключению представлений. Это дополнительная панель слева и набор кнопок внизу. В боковой панели находится список заголовков всех шагов, который позволяет произвольно переключаться на любой шаг.
Кнопки для перехода с шага на шаг — First, Next, Previous, Finish. На первой странице отображается только кнопка Next, на следующих — Previous и Next, и на последней — Previous и Finish. Если установить свойство DisplayCancelButton, к ним добавится кнопка отмены Cancel. Можно задать адрес страниц, куда будет перенаправлена форма при нажатии на кнопки Finish и Cancel. Как боковую панель, так и кнопочную панель навигации можно превратить в шаблоны. Показ боковой панели можно отключить свойством DisplaySideBar, установленным в False. Кнопки могут быть обычными или с любым изображением. Текст кнопок можно установить с помощью свойств CancelButtonText, FinishStepButtonText, FinishStepPreviousButtonText, NextStepButtonText, PreviousStepButtonText и the StartStepNextButtonText.
Заголовок тоже можно превратить в шаблон.
Например, превратим простую форму регистрации (из лекции 5) пользователей в мастера. В отличие от предыдущего примера, в форме создавать кнопки не нужно, так как у Wizard кнопки есть. При этом, если в форме поставлены элементы-валидаторы, переход на следующий шаг кнопкой Next невозможен:
| | | | ||
| | | |||
| | | | ||
| | | | ||
| | ||||
| | |
| | |
| | |
| | |
| | |
| | |
| | |
Для того чтобы на третьем шаге отображались данные, собранные в предыдущих шагах, перехватывается событие ActiveStepChanged:
protected void Wizard1_ActiveStepChanged(object sender, EventArgs e) { if (Wizard1.ActiveStep.ID == "Step3") { Label8.Text = ((TextBox)Wizard1.Controls[0].FindControl("txtName")).Text; Label10.Text = ((TextBox)Wizard1.Controls[0].FindControl("TextBox1")).Text; Label12.Text = ((TextBox)Wizard1.Controls[0].FindControl("TextBox2")).Text;
} }
Если у шага свойство AllowReturn установлено в False, то возврат к этому шагу будет невозможен. Другое интересное свойство — StepType. Оно позволяет заменить данный по умолчанию набор кнопок навигации. Шаг, у которого StepType равен Complete, не виден в боковой панели и будет показан после того, как в последнем шаге будет нажат Finish:
В данном шаге какие-либо кнопки отсутствуют.
В этом курсе мы затронули
В этом курсе мы затронули только часть возможностей ASP .NET 2.0. В последнее время широко пропагандируется технология Ajax и основанная на ней технология Atlas от Microsoft. Объявлено о выходе .NET Framework 3.0. Поэтому и мне, и вам предстоит еще многому научиться.
Бизнес в интернете: Сайты - Софт - Языки - Дизайн
- Киберсантинг
- Киберсантинг как бизнес
- Виды Киберсантинга
- Создание игр
- Дизайн как бизнес
- Dreamweaver
- PHP
- Homesite
- Frontpage
- Studio MX
- Сайтостроительство
- Citrix MetaFrame
- Стили сайта
- ActiveX на сайте
- HTML как основа сайта
- Adobe GoLive
- Что такое WEB
- Мобильные WAP сайты
- 3D графика на сайтах
- 3DS MAX графические решения
- Графика в 3D Studio MAX и на сайте
