ASP.NET

Reviews
Shared by: shanti12
Categories
Tags
Stats
views:
537
rating:
not rated
reviews:
0
posted:
1/8/2008
language:
pages:
0
Учебник по ASP.NET Обзор вебформ Вебформы - это новая для ASP технология. Вебформы введены для удобства разработки приложений. Они позволяют создавать компоненты интерфейса пользователя для многократного использования, что упрощает работу разработчика. Вебконтролы инкапсулируют html код, что позволяет писать код с более четкой логической структурой. Наконец, контролы упрощают создание средств WYSIWYG разработки. Из всех средств, тестировавшихся нами ранее для ASP, только Dreamweaver UltraDev позволял это в приемлемой мере, и то, по сравнению со средствами RAD разработки, его возможности по быстрому созданию качественного кода не впечатляли. Веб формы - это обычные страницы. Помимо динамического содержания, создаваемого вашим кодом, вы можете включать в них вебконтролы.

Заметьте, что у формы стоит свойство runat="server". При запросе страницы, сервер обрабатывает такие контролы и выдает клиенту соответствующий html код. Здесь же был написан простейший обработчик событий для вебформ. При нажатии на кнопку, когда форма отправляется на сервер, ASP.NET выполняет наш метод SubmitBtn_Click. Это задается в свойстве OnClick кнопки submit. Наш же метод присваивает полю Text созданного нами контрола Message текст. 48 контролов поставляется с ASP.NET, они включают в себя различные компоненты от календаря до валидаторов. Кроме того, вы всегда можете написать свои для повторного использования, а также использовать созданные другими. Наиболее часто вы, скорее всего, будете применять валидаторы и котролы, связанные с отображением данных. DataGrid позволит вам быстро вывести содержание выборки пользователю, в то время как DataList и Repeater позволят вам сделать это любым способом через шаблоны (поддерживаются шаблоны заголовков, футеров, самого куска данных и разделителя). Покажем также пример использования валидатора. form_validation.aspx


В данном примере имеется одно текстовое поле и RequiredFieldValidator. Это самый простой из валидаторов, он проверяет, имеются ли в заданном ему поле (в данном случае оно называется Text) какие-нибудь данные. Если нет, и пользователь нажмет submit, то при проверке перед отправкой, скрипт выведет сообщение об ошибке заполнения (вы сами указываете это сообщение) и форма не будет отправлена. Если же у пользователя старый броузер, то проверка будет произведена на сервере. В вашем коде вы можете проверить правильность заполнения всех полей с помощью поля Page.IsValid и вывести суммарное сообщение об ошибках с помощью ValidationSummary. Упомянем о замечательной возможности - разделение кода и представления, что позволит разделить процессы разработки, упростить локализацию приложения и полностью использовать объектно-ориентированный подход. В данном случае нашу простейшую вебформу можно было бы переписать так: form.aspx <%@ Page Inherits="SimpleCode" Src="form.cs" %>


form.cs using using using using System; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls; public class SimpleCode : Page { public Label text; public void SubmitBtn_Click(Object sender, EventArgs e) { text.Text = "text"; } } Структура ASPX-файла ASPX-файл является, по сути, обычным HTML, в котором можно использовать специальные теги. Дополнитеьные теги делатся на две категории: служебные, задающие параметры страницы и позволяющие внедрять код, и теги контролов, которые представляют собой новые интерфейсные конструкции, настройка которых инкапсулирована в тег. Первому типу принадлежат серверные директивы, теги <%= %>, <% %>,<%# %>, . Сначала рассмотрим директивы. Их синтаксис имеет вид <%@ Directive %> Базовой директивой является @ Page, которая описывает основные параметры страницы, такие как файл с исходным текстом, язык кода, параметры трассировки. Также используются директивы @ Import, @ Assembly, @ OutputCache и другие... Теги <%= %> используются для выставки вычисляемых значений. Например, конструкция <%= System.DateTime.Now %> после компиляции будет вместо себя подставлять текущее время. Теги <% %> позволяют вставлять код в страницу - то, что в основном используется в ASP и JSP. Например, <%if (User.Identity.Name == "Admin") { %> Перейти к странице администрирования <% } %> отображает ссылку только для пользователя Admin. Конструкция <%= %> является аналогом <%= %> для компонент с привязкой к данным. Они подставляют вместо себя значение, зависящее от текущего контекста данных. Приведем пример, который, однако, здесь подробно разобран не будет - привязка к данным будет обсуждена в отдельной главе. <%# (Container.DataItem as DateTime).ToShortDateString() %> Также в страницу можно вставлять дополнительные методы с помощью тега Параметр language тега script задает язык, на котором он написан. Теперь рассмотрим теги контролов - они позволяют вставлять в страницу различные элементы управления. Многие из вас сразу вспомнят про стандартные элементы управления вроде кнопок или полей ввода. На самом деле контролы ASP.NET могут представлять не только стандартные элементы, кодируемые одним HTML-тегом, но и довольно сложные DHTML-конструкции. При этом если при написании таких конструкций в обычном HTML вы получаете громоздкий и нерасширяемый код, то при использовании ASP.NET все это для вас инкапсулировано в одном теге. При этом код, который будет подставляться генерируется на сервере, что позволяет изменять его в зависимости, например, от типа броузера. Теги серверных контролов допустимы только внутри серверных форм - конструкций вида
...
. Сами теги контролов пишутся в XML-стиле - с обязательным закрыванием и пространствами имен. Общий вид такого тега: <пространство_имен:имя_тега runat="server" > ... Пространства имен используются для того, чтобы случайно не совпали имена тегов. Стандартные элементы управления от Microsoft находятся в пространстве имен asp: , и т.п. Архитектура ASP.NET также позволяет самим создавать новые элементы управления, но об этом позже. Установка ASP.NET Введение. Мы много говорим об ASP.NET, обсуждаем, проводим встречи. Но есть большое количество пользователей, которые хотели бы изучать данную технологию, но пока не знают как к ней подойти. Это большое количество PHP и Perl программистов, начинающие ASP разработчики и многие другие, включая тех, для кого ASP.NET станет первой платформой разработки веб-приложений. Системные требования. Вам понадобится операционная система с NT ядром и IIS/Peer-Web-Services (Win NT4 SP 6, Win 2K SP2, Win XP) Инсталляция SDK. Установка начинается со скачивания дистрибутива .NET Framework SDK (ссылка на текущую версию в разделе quicklinks на первой странице .SITE). Размер дистрибутива достигает 90 МБ; однако поддерживается возможность загрузки SDK в виде набора маленьких файлов. После чего вы запускаете закачанный файл(setup.exe) и следуете инструкциям, указанным в нем. ASP.NET распространяется как составная часть .NET SDK - сборника всех технологий, необходимых для создания, сборки и тестирования приложений, основанных на .NET Framework. Перед установкой ASP.NET, необходимо установить Internet Explorer 6, который можно получить на сайте http://msdn.microsoft.com/isapi/gomscom.asp?TARGET=/windows/ie/default.htm. Вы также можете взять .NET SDK с компакт-диска Windows Component Update из Visual Studio.NET. Если Вы уже поставили VS.NET на серверную машину, то Вам не стоит беспокоиться - у Вас уже есть все, чтобы запускать ASP.NET приложения. Установка примеров. Если же Вы свободно читаете английскую документацию, то вместе с SDK на Ваш компьютер был размещен хороший учебник по ASP.NET со множеством примеров. Ниже следуют инструкции по установке .NET Framework QuickStart. Чтобы установить образцы Quickstart: 1. Откройте ссылку SDK Overview ('.NET Framework SDK Overview'), которая была добавлена на ваш Рабочий стол в процессе установки SDK. 2. Когда эта HTML страница откроется, щелкните ссылку " The .NET Framework Samples". 3. Следуйте указаниям чтобы установить примеры. 4. После завершения установки, примеры будут доступны по адресу http://localhost/quickstart/default.htm. 5. В конце, после изучения документа, вы можете выбрать ссылку ASP.NET сверху страницы. Там содержится список примеров по ASP.NET. Если же примеры по указанному адресу недоступны, это значит, что Вам необходимо создать виртуальный каталог QuickStart на своем сервере и назначить ему в соответствие каталог <путь к Framework SDK>\Samples\QuickStart. Источники информации. На .SITE мы следим за тем, чтобы поставлять Вам последнюю информацию и всеми силами страемся максимально помочь Вам в изучении ASP.NET и его практическом использовании. Вы ВСЕГДА можете задать интересующий Вас вопрос в форуме и наши эксперты, а также другие пользователи сайта помогут найти ответ на него. Часто задаваемые вопросы. Будет ли работать мое существующее приложение ASP если я установлю SDK и воспользуюсь ASP.NET? Да, приложения ASP.NET могут работать вместе с существующими приложениями ASP. Причем от Вас не требуется каких-либо дополнительных действий. Это осуществляется за счет того, что ASP и ASP.NET приложения обрабатываются разными ISAPI DLL. А так как расширения исходных файлов ASP и ASP.NET не пересекаются, у Вас спокойно могут существовать и существующие и новые приложения. Предостережение: Не забывайте про то, что приложения ASP.NET и ASP не связаны. Например, информация в объектах Session у них разная, и за обработку событий масштаба приложения у них отвечают разные файлы (global.asax и global.asa соответственно). Как создавать ASP.NET страницы? Сначала мы рекомендуем воспользоваться обычным текстовым редактором. После того, как Вы освоитесь с технологией рекомендуем пользоваться VS.NET (Visual Studio 7). Работает ли ASP.NET на базе Windows 95, Windows 98 и Windows Me? Нет. Вы, естественно, можете использовать одну из этих платформ для разработки, но ваше приложение ASP.NET должно запускаться на Веб сервере, на базе Windows 2000, Windows NT 4.0 или Windows XP, с установленным пакетом IIS. Директивы В предыдущей части мы обсудили структуру .aspx-страницы и отметили наличие директив, задающих параметры страницы. Мы уже использовали одну (самую важную) из дмректив - @ Page. В этой части мы познакомимся с остальными директивами и расскажем для чего они применяются. Итак, начнем с уже знакомой нам @ Page, но на более высоком уровне. @ Page Синтаксис всех директив сводится к указанию набора аттрибутов, им соответствующих. Так что не будем каждый раз напоминать. что синтаксис таков: <%@ Directive {attribute = value} %> , а просто будем описывать названия основных аттрибутов и их назначение. Название аттрибута Назначение Примеры Если этот аттрибут установлен в true, то обработчики сообщений страницы (Page_Init и AutoEventWireup Page_Load) вызываются автоматически без явной привязки. Включает/выключает буферизацию потока ответа Buffer - кода страницы при отсылке на сервер. Задает имя класса для страницы, который будет ClassName использован при автоматической компиляции. Здесь не нужно указывать пространство имен. Задает кодировку, в которой написан контент CodePage страницы Указывает класс, от которого будет унаследован класс страницы. Этот прием является обычным при разработке ASP.NET приложений. Так как Inherits сам класс страницы генерируется автоматически, он перекомпилируется каждый раз при изменении страницы. Чтобы отдельно контролировать код, создается класс, от которого AutoEventWireup=true ClassName="MyPage" CodePage="1251" Inherits="MyPage" Language Src Trace затем наследуется класс страницы. Задает язык, который используется в блоках <% Lanugage="C#" %> и <%= %>. Задает файл, в котором находится код страницы. Visual Studio .NET вместо этого аттрибута Src="MyPage.aspx.cs" использует механизм наследования через аттрибут Inherits. Включает/выключает трассировку. При включенной трассировке в конец страницы автоматически дописыватся информация об Trace="true" обработке запроса. Также в нее может быть добавлена дополнительная информация с помощью члена Trace класса Page. @ Import Аналог директивы using в C# - делает доступными члены указанного пространства имен без явного указания этого пространства. Синтаксис следующий: <%@ Import namespace="пространство_имен" %> @ Implements Указывает, что класс страницы или элемента управления наследует данный интерфейс. Синатксис: <%@ Implements interface="имя_интерфейса" %> @ Assembly Директива @ Assembly позволяет подключить к странице указанную сборку, чтобы использовать раннее связывание на этапе компиляции. Синатксис: <%@ Assembly Name="имя_сборки" %> или для указания сборки через исходный текст (указанный файл будет скомпилирован и связан): <%@ Import Src="имя_файла" %> Остальные директивы (Control, OutputCache) будут разобраны в соответствующих разделах. Разделение кода и представления Важной особенностью ASP.NET является простое разделение кода и представления. Важность такого разделения сложно переоценить при разработке больших и средних систем. Это, в частности, позволяет создавать намного более гибкую архитектуру и параллелизовать работы по программированию и дизайну. В ASP.NET, благодаря объектно-ориентированной архитектуры, проблему удалось решить очень элегантно. При генерации класса страницы он наследуется от указанного класса, в котором находтся вся логика. Это позволяет писать логику страницы в файле класса, а интерфейс - в .aspx-файле. Покажем пример такого разделения: Separate.aspx <%@ Page Src="separate.cs" Inherits="Separate" %>
Separate.cs using using using using System; System.Web; System.Web.UI; System.Web.UI.WebControls; public class Separate : Page { protected Label lblMessage; protected Button btnSubmit; public void btnSubmit_Click( object sender, EventArgs e ) { lblMessage.Text = "Hello, world"; } } При этом страницу не нужно даже специально компилоровать - все будет произведено автоматически. Здесь мы сделаем несколько пояснений касательно доступа к элементам страницы из кода. Первое - это как работать с серверными элементами управления. Для доступа к ним проще всего объявить члены класса с именами, соответствующими идентификаторам контролов на форме. Они будут автоматически связаны. Разумеется, члены класса должны быть соответствующего типа из System.Web.UI.WebControls. Чтобы достичь того же эффекта самостоятельно, при инициализации страницы нужно добавить делегата в список обработчиков сообщения. Код выглядит подобным образом: btnSubmit.Click += new EventHandler(btnSubmit_Click); Также обработчик можно прописать прямо в коде страницы, как было сделано в примере выше. Более подробно события будут разобоаны в следующей части. Обработка событий Мы живем в эпоху инетерактивных Веб-приложений. Это значит, что мы не только доставляем информацию пользователю, но и позволяем ему контролировать процесс. В настольных приложениях все решается просто, ибо весь код приложения непосредственно доступен. В интернет-приложениях все сложнее - мы не можем непосредственно вызывать код на сервере с клиента. Код на сервере может быть запущен только в ответ на некоторый запрос с клиента. Рассмотрим сначала как осуществляется обработка пользовательского ввода в настольных приложениях. При нажатии на кнопку, смену активного пункта меню генерируется сообщение о совершении этого действия. Механизм сообщений является очень удобным, в частности, из-за его асинхронности. При разработке ASP.NET Microsft перенесла идеологию сообщений на Webприложения. Передача сообщений осуществляется через специальные аттрибуты в запросе. На сервере они декодируются и на основании информации о сообщении вызываются соответствующие обработчики. При всем этом надо заметить, что со стороны разработчика весь этот механизм крайне прост - во-первых, потому что процесс передачи сообщения скрыт и мы просто говорим "мы хотим обработать это сообщение", а во-вторых благодаря наличию механизма обработки сообщений в .NET Framework, что позволяет обрабатывать эти сообщения как и все другие, к тому же в .NET-языках обработка сообщений интегрирована на уровне синтаксиса. Разумеется, перенос сообщений на страницы интернет накладывает некоторые ограничения на свободу действия. Например, не стоит обрабатывать сообзщение о перемещении мыши - оно возникает слишком часто. Для пояснения о том, как обрабатывать сообщения, рассмотрим пример обработки сообщения Click для кнопки. Рассмотрим страницу со следующим кодом: <%@ Page Src="separate.cs" Inherits="Separate" %>
К ней прилагается файл с кодом: Using using using using System; System.Web; System.Web.UI; System.Web.UI.WebControls; public class Separate : Page { protected Label lblMessage; protected Button btnSubmit; public void btnSubmit_Click( object sender, EventArgs e ) { lblMessage.Text = "Hello, world"; } } Мы ее уже рассматривали в предыдущей части, но сейчас мы на нее посмотрим с точки зрения обработки сообщений - а именно - обработка нажатия на кнопку submit. В этой странице продемонстрирован первый способ привязки обработчиков к сообщениям указание имени обработчика в соответствующем аттрибуте серверного элемента управления. В данном случае - onclick. Но есть и второй способ (и намного более удобный и гибкий) - привязка обработчиков в коде. Это осуществляется единожды при инициализации страницы. Поясним все в коде - модифицируем нашу страницу, чтобы она использовала второй способ. <%@ Page Src="separate.cs" Inherits="Separate" %>
Вот код: using using using using System; System.Web; System.Web.UI; System.Web.UI.WebControls; public class Separate : Page { protected Label lblMessage; protected Button btnSubmit; override protected void OnInit( EventArgs e ) { btnSubmit.Click += new EventHandler(btnSubmit_Click); } public void btnSubmit_Click( object sender, EventArgs e ) { lblMessage.Text = "Hello, world2"; } } Как видно, мы теперь не прописываем аттрибут. а при инициализации страницы добавляем делегата для обработки сообщения. Привязка данных в ASP.NET В .NET-формах есть замечательная возможность - привязка данных (data binding). Эта технология позволяет нароямую связывать свойства контролов на формах с данными. В Веб-формах он используется, в основном, для вывода таблиц и списков. Например, нам нужно вывести список книг в виде таблицы. С использованием data binding код такой формы может выглядеть так: Default.aspx <%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Bind ing_Application._Default" %> Default
Default.aspx.cs using using using using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.Web; System.Web.SessionState; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Binding_Applic ation { /// /// Summary description for _Default. /// public class _Default : System.Web.UI.Page { protected System.Web.UI.WebControls.DataGrid grdBooks; private ArrayList books; private void Page_Load(object sender, System.EventArgs e) { if (!Page.IsPostBack) { books = new ArrayList(); books.Add(new Book("The Catcher In The Rye", "J.L. Salinger", 183)); books.Add(new Book("Programming Windows", "Charles Petzold", 300)); books.Add(new Book("Design Pattterns: Elements Of Reusable ObjectOriented Software", "Gamma et el.", 200)); grdBooks.DataSource = books; DataBind(); } } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.grdBooks.SelectedIndexChanged += new System.EventHandler(this.grdBooks_SelectedIndexChanged); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void grdBooks_SelectedIndexChanged(object sender, System.EventArgs e) { } } } Book.cs using System; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Binding_Applic ation { /// /// Summary description for Book. /// public class Book { private string _title; private string _author; private int _pages; public string Title { get { return _title; } set { _title = value; } } public string Author { get { return _author; } set { _author = value; } } public int Pages { get { return _pages; } set { _pages = value; } } public Book( string title, string author, int pages ) { Title = title; Author = author; Pages = pages; } } } На самом деле из всего этого кода нам важен кусок: Books = new ArrayList(); books.Add(new Book("The Catcher In The Rye", "J.L. Salinger", 183)); books.Add(new Book("Programming Windows", "Charles Petzold", 300)); books.Add(new Book("Design Pattterns: Elements Of Reusable Object-Oriented Software", "Gamma et el.", 200)); grdBooks.DataSource = books; DataBind(); Здесь мы создаем некоторый набор данных и привязываем его к Data Grid одной строчкой. Компонент сам определяет названия колонок и заполняет сетку данными. Причем вместо ArrayList мы можем передать, например, массив или DataSet. В результате мы получим следующее. Также можно вывести тот же список, но в том формате, который удобен в данном случае. Для этого можно применить контрол DataList или Repeater: Default.aspx <%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Bind ing_Application_2._Default" %> Default
<%# DataBinder.Eval(Container.DataItem, "Title") %>
by <%# DataBinder.Eval(Container.DataItem, "Author") %>
Default.aspx.cs using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Binding_Applic ation; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Working_with_data.Data_Binding_Applic ation_2 { /// /// Summary description for _Default. /// public class _Default : System.Web.UI.Page { protected System.Web.UI.WebControls.DataList DataList1; private void Page_Load(object sender, System.EventArgs e) { if (!Page.IsPostBack) { ArrayList books = new ArrayList(); books.Add(new Book("The Catcher In The Rye", "J.L. Salinger", 183)); books.Add(new Book("Programming Windows", "Charles Petzold", 300)); books.Add(new Book("Design Pattterns: Elements Of Reusable ObjectOriented Software", "Gamma et el.", 200)); DataList1.DataSource = books; DataBind(); } } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } } Посмотрим как реализуется кустомизация формата вывода. Для этого задается так называемый шаблон элемента (item template) в теге . В нем задается ASP.NET-код, который будет выведен для каждого элемента списка. Чтобы варьировать код в зависимости от реального содержания элеиента, применяется тег <%# .. %>. Внутри него можно указывать программный код, который будет выполняться индивидуально для каждого элемента. Доступ из такого кода к текущему элементу осуществляется через свойство Container.DataItem. Идеология решения В ASP.NET представлено новое и очень удобная идеология организации страниц серверные контролы. Это простой способ инкапсуляции части системы как на уровне логики так и на уровне представления. На уровне логики каждый контрол инкапсулирован в отдельный класс, на уровне представления - в тег. Соответственно, работать с ними легко и приятно - можно и в коде настроить их поведение с помощью свойств, либо прямо в .aspx-странице указать свойства с помощью атрибутов и тегов, что позволяет создавать более логичную и последовательную структуру. Взаимодействие с контролами возможно по трем "каналам" - изменение свойств, вызов методов и обработка сообщений, что позволяет всю связанную функциональность сконцентрировать в одном компоненте. По сути, на контролы можно смотреть с двух сторон. Со стороны программиста это некоторый компонент, который реализует определенную функциональность на сайте, и не имеет значения, как именно на клиенте он будет работать. С другой стороны, на клиенте контрол разворачивается в HTML/JavaScript - код, в котором реализуется его интерфейсная часть. Стандартно в ASP.NET входит 47 контрола - от надписи до календаря. И все они используются аналогично - нет ничего принципиально различного в работе с ними. Единственная "обособленная" группа контролов - это те, поведение которых основано на наборах данных (data-driven controls). Например, чтобы вставить кнопку в страницу, нужно всего лишь написать следующий код: Код всей страницы таков: <%@ Page language="C#" %>
В этом примере нужно отметить 3 вещи:    Серверные элементы должны находится внутри тега
Они оформляются в XML-стиле У них должен быть атрибут runat="server" Пример использования В этой части мы покажем как использовать серверные контролы. Для этого мы продемонстрируем код формы, представляющей собой форму для передачи элементов из одного списка в другой и обратно. Приложение создавалось в Visual Studio .NET, так что код не очень качественный, но тем не менее мы его вам представим. Default.aspx: <%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Web_Forms.Using_Server_Cont rols.Sample_Application._Default" %> Default
Default.aspx.cs: using using using using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.Web; System.Web.SessionState; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Web_Forms.Using_Server_Controls.Sampl e_Application { /// /// Summary description for _Default. /// public class _Default : System.Web.UI.Page { protected System.Web.UI.WebControls.ListBox lstLeft; protected System.Web.UI.WebControls.ListBox lstRight; protected System.Web.UI.WebControls.Button btnRightToLeft; protected System.Web.UI.WebControls.Button btnLeftToRight; protected System.Web.UI.WebControls.TextBox txtNewItem; protected System.Web.UI.WebControls.Button btnAdd; protected System.Web.UI.WebControls.Button btnRemove; private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.btnRightToLeft.Click += new System.EventHandler(this.btnRightToLeft_Click); this.btnLeftToRight.Click += new System.EventHandler(this.btnLeftToRight_Click); this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion // Обрабатывается нажатие кнопки "Add" private void btnAdd_Click(object sender, System.EventArgs e) { // Добавляем новый элемент в список lstLeft.Items.Add(txtNewItem.Text); // И очищаем поле ввода txtNewItem.Text = ""; } // Это вызывается при нажатии кнопки "Remove" private void btnRemove_Click(object sender, System.EventArgs e) { // Если есть выбранный элеиент, удаляем его if (lstLeft.SelectedItem != null) lstLeft.Items.Remove(lstLeft.SelectedItem); } // Перемещение элемента из левого списка в правый private void btnLeftToRight_Click(object sender, System.EventArgs e) { // Если выбран какой-то элемент в левом списке if (lstLeft.SelectedItem != null) { // Копируем его в правый lstRight.Items.Add(lstLeft.SelectedItem.Text); // И удаляем в левом lstLeft.Items.Remove(lstLeft.SelectedItem); } } // Аналогично предыдущему методу private void btnRightToLeft_Click(object sender, System.EventArgs e) { if (lstRight.SelectedItem != null) { lstLeft.Items.Add(lstRight.SelectedItem.Text); lstRight.Items.Remove(lstRight.SelectedItem); } } } } В принципе, из комментариев все понятно. Разбор этого приложения предоставим читателю в качестве упражнения. Валидация данных в приложении При создании серьезных веб-приложений почти наверняка возникнет проблема валидации - проверки правильности введенных данных. Например, что при регистрации пользователь ввел свое имя или что пароли совпадают. В веб-приложениях делать это можно с двух сторон - со стороны клиента и со стороны сервера. Каждый подход имеет свои достоинства и недостатки: при проверке на клиенте пользователь тут же получает информацию о неверном вводе, но позволяет искусственно отправить некорректные данные на сервер, при проверке на сервере информация точно будет корректна, но придется ждать результата проверки и для этого будет перегружена вся страница. В идеале, конечно, было бы совместить оба способа. Но при применении традиционных технологий это являлось довольно трудоемкой задачей. В ASP.NET проблема валидации решена очень просто - валидация инкапсулиорована в серверные контролы. Каждый валидатор представляет собой контрол, который проверяет другой контрол (точнее, его значение) на соответствие определенному условию перед отсылкой формы и по прибытии ее на сервер. Для валидации на клиенте используется JavaScript-код (если JavaScript не поддерживается, валидация производится только на сервере). Если проверка не прошла, валидатор выводит сообщение об ошибке. К тому же есть специальный контрол ValidationSummary - сводка валидации. Он выводит список не прошедших проверок в одном месте. Различных валидаторов предоставлено довольно много - они отличаются тестовыми условиями. RequiredFieldValidator, например, проверяет, заволнено ли поле ввода. Для задания параметров проверки у валидаторов есть несколько общих атрибутов: ControlToValidate задает идентификатор контрола, подлежащего проверке. ErrorMessage сообщение об оштбке. Text - выводимое сообщение (если он не указан, выводится сообщение об ошибке). В заключение предоставим пример, демонстрирующий валидацию во всей красе. <%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Web_Forms.Using_Server_Cont rols.Validation_Application._Default" %> Default
User name: *
User email: *
*
User password: *
Confirm password: *
*
using using using using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.Web; System.Web.SessionState; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Web_Forms.Using_Server_Controls.Valid ation_Application { /// /// Summary description for _Default. /// public class _Default : System.Web.UI.Page { protected System.Web.UI.WebControls.Label Label2; protected System.Web.UI.WebControls.Label Label3; protected System.Web.UI.WebControls.Label Label4; protected System.Web.UI.WebControls.TextBox txtName; protected System.Web.UI.WebControls.TextBox txtEmail; protected System.Web.UI.WebControls.TextBox txtPassword; protected System.Web.UI.WebControls.TextBox txtConfirmPassword; protected System.Web.UI.WebControls.Button Button1; protected System.Web.UI.WebControls.ValidationSummary ValidationSummary1; protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator1; protected System.Web.UI.WebControls.RegularExpressionValidator RegularExpressionValidator1; protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator2; protected System.Web.UI.WebControls.CompareValidator CompareValidator1; protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator3; protected System.Web.UI.WebControls.RequiredFieldValidator RequiredFieldValidator4; protected System.Web.UI.WebControls.Label Label1; private void Page_Load(object sender, System.EventArgs e) { // Put user code to initialize the page here } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } } Веб-приложение и сессия, обработка глобальных событий До сих пор мы рассматривали работу ASP.NET в пределах одного запроса. Нажали кнопку - получили результат. На практике при работе с Web-приложениями к цели ведут десятки вщаимосвязанных запросов, делающихся на разных страницах. Что объединяет страницы приложения в одно целое? В ASP.NET есть специальный класс - HttpApplication, представляющий все приложение. Он контролирует его общее состояние, и обрабатывает глобальные события. В основном этот класс используется для хранения объектов уровня приложения. Он предоставляет словарь для хранения обънетов, который доступен в любое время с любой страницы. Также в ASP.NET присутствует другой тип окружения - сессия. Сессия объединяет серию запросов с одного адреса в течении некоторого времени. В пределах сессии можно контролировать текущего пользователя, так что именно в сессии удобно отслеживать последоавтельность действий. Параметры сессии также доступны в виде словаря через индексатор со строковым параметром. Текущая сессия и приложение доступны с любой страницы через свойства Session и Application, так что получить доступ к ним очень просто. Еще одной глобальной вещью является обработка событий уровня приложения. Это события вроде: "на одной из страниц приложения началась обработка запроса" или "на какой-то странице произошла ошибка". Такие события обрабатываются в коде файла global.asax. Вот пример такого файла: Global.asax <%@ Application Codebehind="Global.asax.cs" Inherits="Global" %> Global.asax.cs using using using using using System; System.Collections; System.ComponentModel; System.Web; System.Web.SessionState; /// /// Summary description for Global. /// public class Global : System.Web.HttpApplication { public Global() { } protected void Application_Start(Object sender, EventArgs e) { // Обработка старта приложения } protected void Session_Start(Object sender, EventArgs e) { // Обработка открытия сессии } protected void Application_BeginRequest(Object sender, EventArgs e) { // Обработка начала запроса } protected void Application_EndRequest(Object sender, EventArgs e) { // Обработка окончания запроса } protected void Application_Error(Object sender, EventArgs e) { // Обработка ошибки приложения } protected void Session_End(Object sender, EventArgs e) { // Обработка закрытия сессии } protected void Application_End(Object sender, EventArgs e) { // Обработка останова приложения } } Введение в ADO.NET ADO.NET (ActiveX Data Object.NET) - набор классов, используемый для доступа к источникам данных в платформе .NET. Название ADO.NET означает, что данный набор классов - это логическое развитие предыдущей объектной модели доступа к данным ADO. Но ADO.NET не просто следующая версия ADO. ADO.NET представляет собой новую объектную модель, которая использует стандарт XML для передачи данных. ADO.Net развивает идею использования отсоединенных массивов данных, переводя ее из разряда дополнительных возможностей в разряд реально используемых, более того основных способов работы. По сравнению с ADO, ADO.NET обещает более легкое программирование, лучшую производительность и масштабирование, меньшую зависимость от особенностей источников данных и большую способность взаимодействовать с другими платформами. В предыдущих версиях ADO основным объектом для работы с данными был объект Recordset, хранящий результат выполнения запроса - набор строк и колонок. Хотя ADO и позволял создавать отсоединенные наборы данных, это не было его основной задачей. Он был предназначен для работы с данными, использующей постоянное соединение с источником данных. В ADO.NET все изменилось. Теперь ключевой объект, который хранит данные в ADO.NET - DataSet. Это экземпляр CLR-класса System.Data.DataSet, представляющий моментальный снимок части базы данных, размещенный в памяти. В ADO объект Recordset использует другие объекты ADO для соединения с источником данных. DataSet - независимый от источника данных объект, который не имеет собственных средств для работы с источниками данных. Связующую роль между DataSet и источником данных в ADO.NET выполняют управляемые (managed) провайдеры. Каждый управляемый провайдер представляет набор объектов, с помощью которых можно подключиться к источнику данных, считать данные и заполнить ими DataSet. Это позволяет DataSet не знать ничего про соединения с источниками данных. ADO.NET создан для использования в управляемых (managed) проектах. Старый ADO основан на технологии COM и при использовании из управляемых приложений требует дополнительных затрат на выполнение прокси-кода. К тому же ADO имеет меньшие возможности при работе с отключенными наборами данных и XML. Например, в ADO было непросто сохранить изменения, произведенные в отключенном курсоре. Вот некоторые преимущества ADO.NET в сравнении с ADO: Масштабируемость При использовании DataSet работа происходит с отсоединенными наборами данных. Это означает, что вы используете соединение с источником данных очень короткое время. Во многих системах количество подключений к базам данных является самым узким местом в плане масштабируемости. И для этих систем ADO.NET является очень хорошим решением, резко повышающим их масштабируемость. Отключенный набор данных может использоваться несколькими частями программы (или пользователями) одновременно. Независимость от источника данных В ADO возможности объекта Recordset сильно зависели от используемого источника данных. Хотя теоретически ADO обеспечивал доступ к данным независимо от источника данных, на практике всегда необходимо было иметь хорошее представление о возможностях провайдера. В ADO.NET DataSet действительно независим от источника данных, и изменение провайдера, с помощью которого заполняется DataSet, не влияет на функциональность DataSet-а. А то, что данные читаются целиком или последовательно, снижает планку требований, предъявляемых к провайдеру. Так что в большинстве случаев изменение кода будет состоять в изменении используемого управляемого провайдера данных и строки подключения. Способность к взаимодействию Так как ADO.NET использует XML как стандартный формат передачи данных, программа, которой необходимо получить данные из компонента ADO.NET, не обязана сама быть компонентом ADO.NET. В общем случае она вообще может не быть Windowsпрограммой. Единственное требование - эта программа должна понимать XML. И это позволяет ADO.NET-компонентам при использовании других компонентов и сервисов, входящих в VS.Net, легко взаимодействовать с любой программой на любой платформе. Кеширование в ASP.NET Одним из ключевых отличий ASP.NET является поддержка кеширования. То есть при определенных обстоятельствах для ответа на запрос не будет заново отрабатываться код страницы, а вернется результат такого же запроса, выполненного ранее. Если текст страницы не зависит ни от каких параметров запроса, он кешируется без проблдем. Но что делать, если у вас есть страница, которая, например, выдает текст статьи по ее номеру. Для этого есть специальная директива @ OutputCache, которая контролирует кеширование. Разберем вариенты ее использования. Эта директива позволяет, во первых, настроить время хранения страницы в кеше, то есть то время, в течении которого сохраненный контент актуален. Остальные параметры задают, какие запросы считать разными. Наиболее часто используемым является параметр VaryByParam. В этом случае запросы считаются различными, если разлючаются значения указанного параметра. Также можно различать запросы по заголовку, типу броузера и параметрам контрола. Например, на стрнице показа статьи директива может быть следующей: <%@ OutputCache Duration="50" VaryByParam="ID" %> Она указывает. что страница кешируется по параметру ID - то есть, считаются что если запросы имеют одинаковое значение ID, результат будет одинаковым. И страница в кэше будет храниться 50 секунд. Локализация в ASP.NET. Здесь можно выделить два направления: поддержку различных кодировок и различных 'культур'. Культура - термин ASP.NET, обозначающий в совокупности характеристики, присущие конкретным государствам. Культурой определяется, например, формат вывода даты и времени. Помимо календаря культура еще определяет язык и систему написания. Под системой написания я имею в виду, что культурой определяется работа со строками, например их сортировка и сравнение. Еще один важный момент: Культура определяется клиентом при установке свойства locales во время инсталляции системы. Чтобы определить, какая культура используется в данный момент, нужно проделать следующее: Сначала добавить директиву <%@Import Namespace="System.Globalization"%> Теперь можно обращаться к подключенному пространству имен и использовать его классы. Ниже показано, как можно получить требумое свойство: <%=CultureInfo.CurrentCulture.NativeName%> Мы можем также устанавливать новую культуру по своему желанию. Для этого нам понадобится создать новый объект класса CultureInfo. MyCulture = new CultureInfo(CultureName); При этом передаваемый параметр должен представлять из себя предопределенную строковую константу. Теперь осталось присвоить полученное значение необходимому свойству CultutureInfo: Thread.CurrentThread.CurrentCulture = MyCulture; Итак, мы можем узнать, какая культура в данный момент используется или установить используемую культуру по собственному желанию. Это позволит программно выбирать, что и как будет выводиться на экран. Такой метод выигрывает по сравнению с простым переводом и хранением нескольких версий страницы, каждая из которых локализована под отдельную культуру, так как позволяет сохранить динамичность в обновлении сайта. Действительно, вся программная логика хранится в одном экземпляре, и, значит, при необходимости потребуется коррекция только одного документа. Теперь обратимся к формату даты и времени, о котором я уже упоминал. Устранить существующие проблемы, связанные с представлением дат поможет использование DateTime.Now.Format("f", null); Этот метод принимает два параметра: строку, определяющую, в каком виде возвращается дата, и второй параметр, определяющий формат, специфичный для конкретной культуры. В случае передачи null берется текущая культура потока. Если же хочется задать определенную культуру, то следует вызвать что-то типа DateTime.Now.Format("f", new System.Globalization.CultureInfo("ru"))% Для России это будет ru или ru-RU. Теперь мы спокойны за даты и уделим немного времени кодировке. В принципе, здесь стоит упомянуть только одну директиву, которая позволяет установить кодировку выходного файла. <%@Page Language="C#" ResponseEncoding="UTF-8"%> Еще одна интересная возможность, включенная в ASP.NET - работа с региональными установками (Regional Settings). Она полностью аналогична работе с культурой и классом CultureInfo, за исключением имени - теперь это RegionInfo. В свойствах RegionInfo хранится полное, английское, национальное имена региона, знак валюты, признак использования метрической системы и другие характеристики. Ниже приведен пример, показывающий как извлечь текущие установки. <%@Page Language="C#" ResponseEncoding="utf-8" %> <%@Import Namespace="System.Threading"%> <%@Import Namespace="System.Globalization"%> <% RegionInfo region = null; region = RegionInfo.CurrentRegion; %>

Мы живем в стране <%=region.DisplayName%>, а валюта у нас <%= region.CurrencySymbol %> - вот так.

На машине, где тестировался код, с установленным всем английским за исключением региона и locales мы получили результат: Мы живем в стране Russia, а валюта у нас р. - вот так. Самое важное отличие RegionInfo от CultureInfo заключается в том, что свойства RegionInfo определяются сервером , а потому не зависят от настроек пользователя. Обсудив RegionInfo и CultureInfo перейдем к заключительной части и поговорим о настройках в конфигурационных файлах Config.web. Отдел служит основным средством управления локализацией через конфигурационные файлы и содержит следующие атрибуты: requestencoding - ожидаемая кодировка входищих запросов responseencoding - кодировка по умолчанию для исходящих запросов fleeencoding - кодировка по умолчанию для программных файлов ASP.NET culture - культура по умолчанию для обработки входящих запросов uiculture - культура по умолчанию для поиска ресурсов Конфигурирование ASP.NET приложений. Обзор config.web В предыдущих частях мы уже упоминали про файл web.config. Не сложно догадаться, для чего он нужен - для конфигурирования приложения. Однако более подробно о действии установок файла, его структуре и возможном составе складывается противоречивое впечатление. Здесь мы опишем возможности и правила применения web.config. Для начала заметим, что какой-либо из файлов web.config всегда применяется к asp.net приложению. Разница заключается лишь в том, какой из существующих система будет использовать. При установке dotNET создается конфигурационный файл по умолчанию, который и будет применяться, если не указан конкретный web.config. Поясним, как система определяет местопоожение конфига и в какой последовательности она просматривает каталоги. Итак, при запуске Вашего приложения система начинает поиск.Сначала просматривается тот виртуальнй каталог, где находится приложение. Если файл не обнаружен, то система будет обследовать все виртуальные директории, содержащие текущий. Интересно, но то же самое произойдет и в случае обнаружения файла. Это довольно удобно, так как в случае большого приложения можно задатьобщие настройки (например, в ...\my APP\), а затем уточнять их и расширять для более мелких частей (директории вида ...\my APP\Concrete Part\).Файлы, находящиеся ниже в дереве каталогов переопределяют параметры, указанный в конфигурационных файлах более высокого уровня.. Наконец, последний файл, который будет просмотрен находится в папке WinNT\Microsoft.NET\Framework\\config.web. Теперь поговорим о формате конфигурационного файла. Как и почти все текстовые файлы в dotNET конфиг имеет XML синтакс и должен быть легко читаем человеком. Понятно, что, благодаря XML, как простота работы, так и удобство программной обработки будут обеспечены. Вся информация размещается между парой тегов Внутри этих тегов находятся две глобальные части. Первая задается внутри тега и указывает, какие параметры будут определены в данном конфигурационном файле. Здсь же указывается, какие классы несут ответсвенность за обработку этих параметров. Приведем пример: Здесь определяется секция globalization и обработчик для нее. Для ограниченного набора частей web.config, считающихся стандартными, соответствющие обработчики уже прописаны в "системном" web.config и будут унаследованы во всех остальных файлах. Если же вы определяете собственные значения, то для их обработки рекомендуется использовать System.Web.Configuration.DictionarySectionHandler. С помощью этого класса будете получать хзш таблицу, где будут храниться все требуемые пары имя/значение. Возможность добавлять нестандартные секции в конфигурационный файл позволяет хранить там необходимую статическую информцию, такую как строки соединений с базой данных или необходимые URL. Пример (взят из документации Microsoft):
Здесь определена секция databases, не являющаяся стандартной. Я упомянул про стандартную часть web.config. Она включает следующие секции: Отвечает за глобализационные установки приложения. Отвечает за все, свяанное с компиляцией приложений.. Отвечает зы настройку отладочных служб ASP.NET.. Отвечает за настройки, связанные с безопасностью приложений. Последнее, о чем мы еще не поговорили - как получать значения, хранящиеся в config.web программно. Здесь все очень просто. Все что надо - вызвать GetConfig класса System.Web.HttpContext. На что следует обратить внимание, так зто возвращаемое при этом значение. Оно зависит от сопоставленного обработчика, а потому надо знать, к какому типу привести полученный результат. Написание пользовательских элементов управления под ASP.NET Введение Уже множество разработчиков, перейдя на ASP.NET, смогли убедиться в том, что новая платформа для разработки Web-приложений от Microsoft является наиболее мощной и гибкой из всех имеющихся на рынке. Очень удобна прозрачное использование серверных элементов управления, но, хотя набор стандартных элементов велик - есть даже календарь, иногда хочется сделать что-то свое. Причем, даже не "иногда". Потребность в написании своих элементов управления возникает (пусть часто и неосознанно) в написании любого мало-мальски крупного webприложения. Пусть это даже будет обычная система новостей. Причем, должна быть отдельная страница со списком всех новостей и последние новости на главной странице. Причем все это должно быть продублировано для нескольких тем новостей. Конечно, можно воспользоваться старым добрым Copy and Paste и сделать отдельный код на каждой странице, но представьте, что вы через некоторое время решили, например, изменить стиль списка новостей или, скажем, добавить поле "Автор". В этом случае придется менять код каждой копии. В этом случае очень хочется чего-то вроде шаблона - параметризуемого куска HTML-кода, который (с соответствующими параметрами) можно было бы быстро вставить в любое место. Эта возможность реализуется в ASP.NET с помощью пользовательских элементов управления (user controls). Пользовательский элемент управления как раз и является тем самым шаблоном, который можно вызывать в любом месте aspx- страницы. Его код тоже пишется на ASP.NET и хранится в .ascx - файле. Только его код не вставляется напрямую в код страницы, а создается html-код для элемента управления и уже он вставляется в html-код страницы при его генерации. Простейший элемент управления Для начала я предлагаю написать вместе простейший элемент управления. Для этого создайте новое web-приложение и в нем файл simple_control.ascx со следующим содержанием: <%@ Control Language="c#"%>

Hello, <%= Name %>!

Вот и готов наш первый элемент управления - довольно просто. Теперь давайте попробуем использовать его в какой-нибудь .aspx - странице Создадим страницу control_test.aspx со следующим кодом: <%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %> <%@ Page language="c#" %>
То есть, оно работает! Конечно, это простой пример, но и он может показать, насколько эффективными могут оказаться пользовательские элементы управления. Допустим, мы хотим "поздороваться" сразу с кучей людей и напишем для этого следующий код: <%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %> <%@ Page language="c#" %>
А теперь мы вдруг захотели слово "Hello" покрасить в зеленый цвет, а имена - в красный. Для этого нужно всего лишь поменять код у элемента на следующий: <%@ Control Language="c#"%>

Hello, <%= Name %>!

Если бы мы явно писали код для каждого вызова элемента, нам пришлось бы изрядно потрудиться. Конечно, можно сказать, что такой вопрос решается стилями, но, во-первых, если бы это не было предусмотрено заранее, все равно пришлось бы прописывать стили в каждой строчке, а во-вторых, это, конечно, простой пример. Формат файлов пользовательских элементов управления Файлы пользовательских элементов управления во многом похожи на файлы вебформ. Но, конечно, есть отличия. В качестве основного декларативного тега используется тег @ Control. Все его параметры аналогичны параметрам тега @ Page, хотя многих параметров страницы он не имеет. Но мы опишем назначение наиболее часто используемых параметров тега @ Control: Параметр Назначение ClassName Имя класса, которое будет использовано при создании элемента управления Language Язык, на котором написан весь inline-код страницы Указывает базовый класс для элемента управления. Эта техника используется Inherits Visual Studio.NET при работе с ASP.NET страницами и элементами управления. Далее может следовать любой ASP.NET код. Результат выполнения этого кода вставляется в текст получаемой в итоге страницы. Также могут использоваться специальные теги, такие как @ Inherits и скрипты (как клиентские, так и серверные). Использование пользовательских элементов управления в ASP.NET страницах Для использования пользовательского элемента в веб-форме, нужно сделать две вещи: 1) Зарагистрировать элемент. Для этого есть специальный тег @ Register. Причем, есть два способа его использования - для регистрации сразу всех элементов, объявленных в некоторой сборке и индивидуальной регистрации. В первом случае синтаксис такой: <% @ Register TagPrefix="префикс" Namespace="пространство_имен" Assembly="имя_сборки" %> Он регистрирует все элементы, объявленные в пространстве имен пространство_имен сборки имя_сборки и сопоставляет им префикс префикc (что это значит, будет объяснено позже) Этот способ удобен, когда есть целая библиотека элементов управления и из нее используется множество элементов. В случае же, когда предпочтительнее индивидуальная регистрация, пользуются следующим синтаксисом: <%@ Register TagPrefix="префикс" TagName="тег" Src="исходник" %> Эдесь тег сопоставляет элементу, описанному в файле исходник тег с именем тег и префиксом префикс. Именно этот синтаксис был использован в нашем примере: <%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %> 2) Использовать элемент Для обращения к элементу используется формат тега <префикс:тег>, где префикс - это префикс, заданный в теге Register, а тег - это, в первом случае, имя класса, а во втором - заданное имя. В нашей странице элемент был использован следующим образом: Конфигурирование пользовательских элементов управления Пользовательские элементы управления ничего особого не стоили бы, если не было бы возможности настраивать их вывод в зависимости от ситуации. В нашем примере мы для каждого экземпляра настраивали имя, которое выводил элемент. Для того, чтобы задать свойство пользовательского элемента управления, нужно (в простейшем случае) объявить общедоступное (public) поле. Например, в нашем случае мы объявили поле Name: Затем это поле можно использовать в коде элемента как обычную переменную:

Hello, <%= Name %>!

Чтобы задать значение поля в странице, использующей элемент управления, их можно просто указать как атрибуты соответствующего тега: При чем свойства могут быть самых различных типов - от строковых, до временнЫх. Рассмотрим расширенную версию нашего элемента: <%@ Control Language="c#"%>

Hello, <%= Name %>! <% if (Age != 0) { %> (<%= Age %>) <% } %> <%= BirthDate %>

и соответствующей страницы: <%@ Register Src=" simple_control.ascx" TagPrefix="Simple" TagName="Control" %> <%@ Page language="c#" %>
Здесь видно, что мы используем строковые, числовые параметры и параметр типа DateTime. Конечно, это простейший способ настройки страниц. Для большей гибкости используются свойства и методы. Использование свойств позволяет настраивать какое-то внутреннее поведение в зависимости от их значений или передавать их вложенным элементам управления. Рассмотрим такой элемент: <%@ Control Language="c#"%> Используем этот элемент в нашей странице: <%@ Register Src="simple_control.ascx" TagPrefix="Simple" TagName="Control" %> <%@ Register Src="text_control.ascx" TagPrefix="Simple" TagName="Text" %> <%@ Page language="c#" %>
Конечно, задавать свойства элементов можно также из кода страницы: <%@ Register Src="simple_control.ascx" TagPrefix="Simple" TagName="Control" %> <%@ Register Src="text_control.ascx" TagPrefix="Simple" TagName="Text" %> <%@ Page language="c#" %>
runat="server" runat="server" runat="server" runat="server" Name="Alice"/> Name="Don"/> Name="Michael"/> Name="Afric"/>
Методы элементов управления Для работы с элементами управления также можно использовать методы. Для примера такого элемента возьмем миниатюрный напоминатель - элемент, выводящий список назначенных событий на данную дату. При выборе даты на календаре выводится список событий на этот день. Теперь давайте посмотрим его код. Reminder.ascx: <%@ Control Language="c#" AutoEventWireup="false" Codebehind="Reminder.ascx.cs" Inherits="UserControlsDemo.Reminder" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%> <%# (Container.DataItem as RemindEvent).Text %> Reminder.ascx.cs: namespace { using using using using using using using UserControlsDemo System; System.Data; System.Drawing; System.Collections; System.Web; System.Web.UI.WebControls; System.Web.UI.HtmlControls; /// /// Пользовательский контрол, представляющий собой простой "напоминатель" /// public class Reminder : System.Web.UI.UserControl { protected System.Web.UI.WebControls.DataList lstEvents; protected System.Web.UI.WebControls.Calendar Calendar; private ArrayList _events; public Reminder() { _events = new ArrayList(); } /// /// Добавляет новое событие /// /// Событие, которое должно быть добавлено public void Add( RemindEvent e ) { _events.Add(e); UpdateEvents(); } /// /// Удалает событие /// /// Событие, которое будет удалено public void Remove( RemindEvent e ) { _events.Remove(e); UpdateEvents(); } /// /// Очищает список событий /// public void Clear() { _events.Clear(); UpdateEvents(); } private void Page_Load(object sender, System.EventArgs e) { UpdateEvents(); } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.Calendar.SelectionChanged += new System.EventHandler(this.Calendar_SelectionChanged); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Calendar_SelectionChanged(object sender, System.EventArgs e) { UpdateEvents(); } private void UpdateEvents() { ArrayList events = GetEventsByDate(Calendar.SelectedDate); lstEvents.DataSource = events; DataBind(); lstEvents.Visible = true; } /// /// Представляет собой событие для напоминания /// public class RemindEvent { private DateTime _date; private string _text; /// /// Дата, когда произойдет событие /// public DateTime Date { get { return _date; } set { _date = value; } } /// /// Описание события /// public string Text { get { return _text; } set { _text = value; } } /// /// Конструктор события /// /// Дата события /// Описание события public RemindEvent( DateTime date, string text ) { _date = date; _text = text; } } private ArrayList GetEventsByDate( DateTime date ) { ArrayList res = new ArrayList(); foreach (RemindEvent e in _events) if (e.Date.Equals(date)) res.Add(e); return res; } } } Как видно, здесь все просто. Хранится список всех событий, при смене даты идет поиск. И ко всему этому прикручен интерфейс из трех методов: Add, Remove и Clear. Покажем как они используются: ReminderTest.aspx: <%@ Register Src="Reminder.ascx" TagPrefix="Demo" TagName="Reminder" %> <%@ Page language="c#" Codebehind="ReminderTest.aspx.cs" AutoEventWireup="false" Inherits="UserControlsDemo.ReminderTest" %> ReminderTest
ReminderTest.aspx.cs: using using using using using using using using using using System; System.Collections; System.ComponentModel; System.Data; System.Drawing; System.Web; System.Web.SessionState; System.Web.UI; System.Web.UI.WebControls; System.Web.UI.HtmlControls; namespace UserControlsDemo { /// /// Summary description for ReminderTest. /// public class ReminderTest : System.Web.UI.Page { protected Reminder Reminder1; private void Page_Load(object sender, System.EventArgs e) { Reminder1.Add(new Reminder.RemindEvent(DateTime.Today, "Super event")); Reminder1.Add(new Reminder.RemindEvent(DateTime.Today, "Girlfriend birthday")); } #region Web Form Designer generated code override protected void OnInit(EventArgs e) { // // CODEGEN: This call is required by the ASP.NET Web Form Designer. // InitializeComponent(); base.OnInit(e); } /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.Load += new System.EventHandler(this.Page_Load); } #endregion } } Написание серверных элементов управления Последняя тема, которой мы немного коснемся - это создание собственных серверных элементов управления. Такие элементы обладают гораздо более широкими возможностями по сравнению с пользовательскими элементами управления. Так они могут более гибко встраиваться в среду разработки, у них шире потенциальные возможности (в частности использование шаблонов). Серверные элементы наследуются напрямую от System.Web.UI.Control и осуществляет вывод своего кода не с помощью .ascs-шаблона, а напрямую при вызова метода Render. Мы не будем подробно рассматривать написание серверных контролов - эта тема очень обширная, лишь покажем небольшой пример: контрол, который просто выводит указанный текст CustomLabel.cs using using using using System; System.Web.UI; System.Web.UI.WebControls; System.ComponentModel; namespace ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Writing_custom_controls.Simple_Server _Control { /// /// Summary description for CustomLabel. /// [DefaultProperty("Text"), ToolboxData("<{0}:CustomLabel runat=server>")] public class CustomLabel : System.Web.UI.WebControls.WebControl { private string text; [Bindable(true), Category("Appearance"), DefaultValue("")] public string Text { get { return text; } set { text = value; } } /// /// Render this control to the output parameter specified. /// /// The HTML writer to write out to protected override void Render(HtmlTextWriter output) { output.Write(Text); } } } Default.aspx <%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Writing_custom_controls.Sim ple_Server_Control._Default" %> <%@ Register TagPrefix="cc1" Namespace="ru.spb.dotSITE.Portal.Tutorials.ASP.NET.Writing_custom_controls.Si mple_Server_Control" Assembly="ru.spb.dotSITE.Portal" %> Default

Related docs
Master Pages in ASP.NET 2.0
Views: 667  |  Downloads: 173
Better Web Experience with ASP.NET
Views: 434  |  Downloads: 132
ASP.Net Development
Views: 53  |  Downloads: 12
asp.net tutorials
Views: 703  |  Downloads: 148
asp.net validators
Views: 48  |  Downloads: 22
ASP.Net Bible
Views: 1474  |  Downloads: 185
ASP.NET MVC
Views: 250  |  Downloads: 17
ASP.NET Tutorial Presentation #1
Views: 306  |  Downloads: 80
ASP.NET AJAX Improvements in ASP.NET
Views: 108  |  Downloads: 39
ASP.Net 4 all
Views: 59  |  Downloads: 21
ASP.NET Client-Side Script
Views: 127  |  Downloads: 8
ASP.NET documents
Views: 314  |  Downloads: 29
premium docs
Other docs by shanti12
Globalisation Of Education
Views: 598  |  Downloads: 27
multinational financial management
Views: 623  |  Downloads: 30
Financial Ratios
Views: 3175  |  Downloads: 402
Financial model
Views: 2719  |  Downloads: 754
financial management
Views: 906  |  Downloads: 181
financial Analysis
Views: 1557  |  Downloads: 162
BUSINESS PLANNING AND FINANCIAL FORECASTING
Views: 1949  |  Downloads: 412
A Junior Software engineer
Views: 731  |  Downloads: 60
1st Sem-Operating systems_1
Views: 813  |  Downloads: 44
Useful Material
Views: 1188  |  Downloads: 135
Technological Trends
Views: 685  |  Downloads: 36
Professional Ajax
Views: 7767  |  Downloads: 307
msnet article
Views: 453  |  Downloads: 1
hoomanLibrary
Views: 822  |  Downloads: 4
AJAX
Views: 601  |  Downloads: 47