Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
75
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

3. Модификация веб-приложения asp.Net: реализация различной функциональности

На этот раз будем работать на странице Default.aspx. Перейдём к конструктору страницы. Нажмём Enter после последней строчки с текстом. Добавиться новый тэг «p». С панели элементов перетащим TextBox и изменим свойства:

Width:

300px

ReadOnly:

True

Откроем событие Page_Load для этой страницы (файл Default.aspx.cs) и впишем:

TextBox1.Text = "Московское время: " + DateTime.Now.TimeOfDay.ToString();

// Response.Write("Сейчас: " + DateTime.Now); // Функция выводит строку в левом верхнем углу страницы

Ещё несколько слов о ViewState и серверных элемента управления:

В Visual Studio есть два раздела с похожими компонентами Например такие как TextBox (текстовое поле для редактирования). Один элемент находится в разделе «Стандартные» (TextBox) другой находится в разделе HTML «Input (Text)». В чём же их отличие? Для начала добавим на страницу два этих элемента управления:

<p>

<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>

<input id="Text1" type="text" />

</p>

Кроме того, что они объявляются по-разному, в TextBox добавлен параметр runat="server", который он говорит компилятору о том, что исполнение данного элемента будет происходить на сервере. Похоже на TextBox в Windows Forms, то есть элемент имеет свойства, методы и события.

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

В случае PHP или HTML: у пользователя всегда была нужная переменная на каждой странице, и её надо все время передавать через запросы (речь не о «cookie»), например через «input type=hidden».

В ASP.NET есть механизм, который называется ViewState. На самом деле ViewState это тот-же input type=hidden в который добавляются все свойства серверных элементов управления. По умолчанию все свойства элементов «серелизуются» в ViewState.

Таким образом, задав например цвет элемента красным — он будет красным на всех страницах после каждого «постбэка» (посылки запроса) пользователя.

При инициализации страницы все доступные свойства из ViewState подставляются в наш серверный элемент.

Для HTML-элементов такое разумеется не выполняется.

При всех своих плюсах ViewState имеет минус — размер. При большом количестве элементов на странице и большом изменении их свойств ViewState может сильно раздуваться. Необходимо позаботиться о пользователях с низкими скоростями соединения с интернетом.

Можно удалить ViewState двумя способами:

1. Удалять для всей странице целиком, указав директиву EnableViewState="false".

<%@ Page Title="Домашняя страница" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" EnableSessionState="False"

CodeBehind="Default.aspx.cs" Inherits="LWP18ASPNET._Default" %>

2. Выключить для отдельных элементов:

<asp:TextBox ID="TextBox2" runat="server" EnableViewState="false"></asp:TextBox>

Global.asax:

Иногда, нужно обработать события, которые возникают в момент первого посещения сайта пользователем. Например, хотим знать когда пользователь зашёл или когда вышел или просто факт того что он был на сайте и прочее. Как же это сделать?

Но начнём не с пользователя, а с приложения.

В совокупности все страницы ASP.NET входят в приложение. Оно загружается, как только к нему происходит обращение. Для того чтобы об этом первом обращении, а также о других события используется файл Global.asax. Откроем этот файл с кодом.

1. Application_Start отрабатывается, когда загружается приложение, допишем туда код (одну строку после комментария):

void Application_Start(object sender, EventArgs e)

{

// Код, выполняемый при запуске приложения

Application["users"] = 0;

}

2. Application_End — приложение завершается.

3. Application_Error — ошибка в приложении.

4. Session_Start — начинается сессия для нового пользователя. Код наш выполняет увеличение счётчика на единицу:

void Session_Start(object sender, EventArgs e)

{

// Код, выполняемый при запуске нового сеанса

Application["users"] = Convert.ToInt32(Application["users"]) + 1;

}

5. Session_End — завершается сессия. Событие Session_End вызывается только в том случае, если для режима sessionstate задано значение «InProc» в файле Web.config. Если для режима сеанса задано значение StateServer или SQLServer, событие не порождается. Код выполняет уменьшение счётчика на едениу при завершении сессии:

void Session_End(object sender, EventArgs e)

{

// Код, выполняемый при запуске приложения.

// Примечание: Событие Session_End вызывается только в том случае, если для режима sessionstate

// задано значение InProc в файле Web.config. Если для режима сеанса задано значение StateServer

// или SQLServer, событие не порождается.

Application["users"] = Convert.ToInt32(Application["users"]) - 1;

}

Добавим на страницу Default.aspx новый элемент TextBox с HTML-кодом:

<p>

<asp:TextBox ID="TextBox3" runat="server" ReadOnly="True"

Width="300px"></asp:TextBox>

</p>

Код для события Page_Load файла Defualt.aspx.cs:

TextBox3.Text = "Число пользователей на сайте: " + Application["users"].ToString();

Button:

В веб-приложениях кнопка делает «PostBack» (в HTML это называется submit) на какую-либо страницу (чаще всего на свою же). Основное отличие ASP.NET заключается в том, что по кнопке идёт не только постбэк (передача POST и GET параметров), но так же ещё отрабатывает событие Click которое обрабатывается каким либо методом, то есть после нажатия кнопки не только перезагрузиться страница, но и отработает метод, подвязанный на событие Click.

У кнопки имеются следующие интересные свойства:

1. CssClass — указывает имя класса стилей из CSS-файла.

2. Text — надпись на кнопке.

3. Enabled — когда true кнопка активна. То есть её возможно нажать.

4. EnableViewState — хранить или нет состояние элемента в ViewState.

5. OnClientClick — указывается инструкция JavaScript, которая выполнится при нажатии по кнопке.

6. PostBackUrl — страница на которую будет выполнен постбэк (передача параметров). Аналог action в тэге form.

7. ToolTip — всплывающая подсказка.

8. ValidationGroup — группа для проверки значений перед постбэком.

9. Visible — когда false кнопка не отображается.

Практически все перечисленные выше параметры являются общими для всех элементов.

Посмотрев на генерируемый ASP.NET HTML-код видно как DropDownList превращается в select, или как TextBox становится «input type="text”», но также можно заметить и как ASP.NET формирует имена HTML элементов. То-есть формируемые имена имеют другой ID (а не тот, что указан в коде при написании приложения). И при задаче проверки или выполнения какого либо JavaScript кода можно зайти в тупик, какое же будет имя элемента управления. Но об этом позаботились. У каждого элемента есть свойство ClientID которое и содержит генерируемое имя.

Посмотрим пример, который на JavaScript будет выводить HTML имя кнопки. Добавим на страницу Default.aspx кнопку со следующим кодом (свойства кнопки уже указаны в коде):

<p>

<asp:Button ID="Button1" runat="server" Text="Узнать имя этой кнопки"

OnClientClick="alert(this.name);" />

</p>

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

Создаём TabControl:

В Windows Forms приложениях есть элемент управления TabControl который представляет собой панель с закладками. К сожалению в веб-приложениях такого нет, но можно сделать. Для этого будем использовать элементы: Menu (панель элементов, группа Переходы), MultiView, View. Вначале на новой строке в конструкторе разместим Menu, после добавления нажмём на смарт-тэг «Правка элементов меню...». Создаём три вкладки:

Рис. 3. 1. Редактор элементов меню: «Вкладка № 1»

Последовательно добавим три меню элемента с разными свойствами Text и Value:

Первый элемент меню:

Text:

Вкладка № 1

Value:

0

Второй элемент меню:

Text:

Вкладка № 2

Value:

1

Третий элемент меню:

Text:

Вкладка № 3

Value:

2

Применим какой-нибудь шаблон для меню. Например, Профессиональный (смарт-тэг для элемента Menu — «Автоформат...»):

Меню разместим горизонтально. Нажмём мышкой на код:

<asp:Menu ... >

И на панели свойств изменим свойство:

Orientation:

Horizontal

После меню добавим элемент MultiView и внутри размести последователь (три раза) три элемента View. В каждом view что-нибудь напишем. Получим HTML-код:

<p>

<asp:MultiView ID="MultiView1" runat="server">

<asp:View ID="View1" runat="server">

Вкладка № 1

</asp:View>

<asp:View ID="View2" runat="server">

Вкладка № 2

</asp:View>

<asp:View ID="View3" runat="server">

Вкладка № 3

</asp:View>

</asp:MultiView>

</p>

Теперь проинициализируем событие нажатия на элемент меню. Для этого дважды щёлкнем на представлении «Конструктор» на элементе управления Menu нашей страницы. Будет создан обработчик события MenuItemClick. Запишем туда код:

protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)

{

MultiView1.ActiveViewIndex = Convert.ToInt32(Menu1.SelectedValue);

}

Теперь при выборе любого меню «Вкладка № ...» будет отображена соответствующая вкладка:

DropDownList:

Аналогом ComboBox В ASP.NET является DropDownList В коде HTML он будет выглядеть как «select». Добавим его на страницу и свяжем с базой данных сайта. Добавим следующий HTML-код после последнего закрывающего элемента </p>:

<p align="right">

Зарегистрированные пользователи:

</p>

Переместим курсор выделения после двоеточие и перетащим DropDownList. После добавления нажмём на смарт-тэг «Выбрать источник данных...». В открывшемся окне в поле Выберите источник данных выберем <Новый источник данных>. В следующем окне выберем База данных (иконка с надписью «SQL»), в единственном поле редактирования впишем «ASPNETDB»:

Рис. 3. 2. Мастер конфигурации источника данных: выбор истопника и ввод префикса

Жмём ОК. В следующем окне в выпадающем списке выбираем ApplicationServices, жмём «+» чтобы посмотреть строку соединения с базой:

Рис. 3. 3. Настроить источник данных – ASPNETDB: выбор соединения данных

Жмём Далее. В следующем окне в поле имя выбираем из списка таблицу vw_aspnet_Users. В поле Столбцы щёлкаем по UserName:

Рис. 3. 4. Настроить источник данных – ASPNETDB: запрос из базы

Жмём Далее. В следующем окне можно протестировать запрос на выполнение (получим все имена зарегистрированных пользователей). Жмём Готово, это вернёт нас к первому, открывшемуся по цепочке окну:

Там уже автоматически настроятся оставшиеся поля для DropDownList (как на кусочке рисунка выше). Жмём ОК. Теперь элемент «списка» будет отображать на странице сайта всех зарегистрированных пользователей:

Panel:

Panel используется в качестве контейнера для нескольких элементов и может выполнять групповые операции, например скрытия объектов. Добавим две панели и разместим в первой текстовое поле и кнопку, а во второй панели создадим Label и будем выводить в него текст введенный в текстовое поле После нажатия на кнопку на странице должна быть только введённая надпись Первоначально установим свойство Visible для второй панели как false. Всё это реализует простым HTML-кодом (элементы были добавлены переносом, свойства изменены на панели свойств):

<p>

 <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px">

<asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>

<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Нажми меня!" /></asp:Panel>

<asp:Panel ID="Panel2" runat="server" Height="50px" Visible="False" Width="125px">

<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label></asp:Panel>

</p>

Событие Click для кнопки с Button3:

protected void Button2_Click(object sender, EventArgs e)

{

Label1.Text = TextBox4.Text;

Panel1.Visible = false;

Panel2.Visible = true;

}

Literal:

Literal используется в качестве контейнера для HTML. Иногда бывает ситуация при которой нет возможности использовать ASP.NET элементы управления или просто такого элемента нет. Добавляем в то место, куда хотим вывести HTML блок элемент Literal и в свойство Text записываем HTML-код. В новый блок «p» перетаскиваем этот элемент:

<p>

<asp:Literal ID="Literal1" runat="server"></asp:Literal>

</p>

Добавляем следующие строчки к событию Page_Load страницы:

String table = "<table border=\"1\"><tr>";

for (int i = 0; i < 10; i++) table += "<td>" + i + "</td>";

table += "</tr></table>";

Literal1.Text = table;

Этот код нарисует табличку:

Wizard:

При реализации многостраничной регистрации, или списка вопросов, которые не умещались на одну страницу и прочее, возникает задача разнести вопросы по нескольким последовательно связанным страницам. Можно делать через множество страниц и передавть все предыдущие ответы через поля «hidden», можно через GET, возможно, объединять элементы в Panel и затем их скрывать. В ASP.NET 2.0 появился элемент управления Wizard. В Wizard настраивается: количество шагов, формат кнопок, надписи на них, внешний вид и прочее. Всё что необходимо, это добавить нужные элементы внутрь шага Wizard.

Перетащим Wizard на новую сточку на странице (новый тэг «p»). Это создаст HTML-код:

<p>

<asp:Wizard ID="Wizard1" runat="server">

<WizardSteps>

<asp:WizardStep ID="WizardStep1" runat="server" Title="Step 1">

</asp:WizardStep>

<asp:WizardStep ID="WizardStep2" runat="server" Title="Step 2">

</asp:WizardStep>

</WizardSteps>

</asp:Wizard>

</p>

Для визуального редактирования элементов можно воспользоваться смарт-тэгом Добавить/удалить шаги WizardStep...:

Рис. 3. 5. Редактор коллекции WizardStep: добавляем три шага и указываем Title

В результате создания шагов и заполнения вкладок, а также применения автоформата Профессиональный, код получим такой:

<p>

<asp:Wizard ID="Wizard1" runat="server" ActiveStepIndex="0" BackColor="#F7F6F3"

BorderColor="#CCCCCC" BorderStyle="Solid" BorderWidth="1px"

Font-Names="Verdana" Font-Size="0.8em" >

<HeaderStyle BackColor="#5D7B9D" BorderStyle="Solid" Font-Bold="True"

Font-Size="0.9em" ForeColor="White" HorizontalAlign="Left" />

<NavigationButtonStyle BackColor="#FFFBFF" BorderColor="#CCCCCC"

BorderStyle="Solid" BorderWidth="1px" Font-Names="Verdana" Font-Size="0.8em"

ForeColor="#284775" />

<SideBarButtonStyle BorderWidth="0px" Font-Names="Verdana" ForeColor="White" />

<SideBarStyle BackColor="#7C6F57" BorderWidth="0px" Font-Size="0.9em"

VerticalAlign="Top" />

<StepStyle BorderWidth="0px" ForeColor="#5D7B9D" />

<WizardSteps>

<asp:WizardStep ID="WizardStep1" runat="server" Title="Шаг № 1">

<asp:TextBox ID="TextBox5" runat="server"></asp:TextBox>

</asp:WizardStep>

<asp:WizardStep ID="WizardStep2" runat="server" Title="Шаг № 2">

<asp:CheckBox ID="CheckBox1" runat="server" Text="Выдели меня!" />

</asp:WizardStep>

<asp:WizardStep ID="WizardStep3" runat="server" Title="Шаг № 3">

Готово!

</asp:WizardStep>

</WizardSteps>

</asp:Wizard>

</p>

Это создаст следующее:

Application (глобальные переменные веб-приложения):

Наверное, задач хранения глобальных переменных в ASP.NET да и вообще в веб технологиях не так и много, но они все таки есть. Есть они в том числе и в ASP.NET Хранятся переменные через HttpApplicationState. Итак, данные в Application хранятся на протяжении жизни приложения ASP.NET и доступны из любого места приложения. Об использовании Application уже было рассказано ранее в данной лабораторной работе.

Session (глобальные переменные сессии):

Наряду с хранением переменных в Application, также можно их хранить и в сессии пользователя. Отличие будет в том, что эти переменные будет видеть только пользователь-владелец сессии (браузер одного ПК). Воспользуемся одним из TextBox уже установленных на странице и добавим только код в событие Page_Load страницы:

Session["myBrowser"] = Request.Browser.Browser + " " + Request.Browser.Version;

if (Session["myBrowser"] != null) { TextBox2.Text = "Ваш браузер: " + Session["myBrowser"].ToString(); }

Организовать выход пользователя с сайта, а, следовательно, удалить все переменные в его сессии можно с помощью статического метода Abandon. Добавим в файл Global.asax.cs в метод Session_End следующий код:

Session.Abandon();

При запуске страницы из Internet Explorer версии 9.0 получим:

FileUpload (загрузка файлов на сервер):

FileUpload позволяет пользователю загрузить файл на сервер. Разместим этот элемент на страница, а также рядом поместим кнопку и текстовое поле:

<asp:FileUpload ID="FileUpload1" runat="server" />

 <asp:Button ID="Button4" runat="server" Text="Загрузить файл" onclick="Button4_Click" />

 <asp:Label ID="Label3" runat="server" Text="Label" Visible="False"></asp:Label>

Событие Click кнопки Button4:

String SavePath = @"D:\";

// Метод MapPath возвращает полный физический путь для виртуального пути, который можно передать в метод.

// Например, следующий код возвращает путь к файлу с корневого каталога веб-узла:

// String SavePath = Server.MapPath("~"); //

if (FileUpload1.HasFile)

{

SavePath += FileUpload1.FileName;

FileUpload1.SaveAs(SavePath);

Label3.Visible = true;

Label3.Text = "Файл сохранён в, путь: " + SavePath + ". Размер файла: " + (FileUpload1.FileBytes.Length/(1024)).ToString() + "Кб";

}

В итоге, жмём кнопку обзор, выбираем любой файл и жмём Загрузить файл. Файл копируется на диск D (это может быть корневой каталог сервера и соответственно абсолютный путь до директории сайта на сервере). Пример работы загрузки в корневой каталог «веб-сайта» (метод MapPath):

Файл был загружен в каталог запуска веб-приложения.

ServerVariables (узнаём параметры клиента):

Часто встречается задача определения некоторых параметров клиента, например таких как его IP адрес, клиентское приложение, ссылка с которой клиент пришёл на данную страницу и прочее. Вся эта информация хранится в ServerRequest HTTP запроса Для получения всех параметров клиента сделаем следующее. Добавим DropDowList на «Вкладку № 1» (изменим код вкладки View1):

<asp:View ID="View1" runat="server">

Сведения о клиенте:<br />

<asp:DropDownList ID="DropDownList2" runat="server">

</asp:DropDownList>

</asp:View>

А также перепишем событие нажатия на элемент Menu:

protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)

{

MultiView1.ActiveViewIndex = Convert.ToInt32(Menu1.SelectedValue);

foreach (string key in Request.ServerVariables.AllKeys)

{

if (key == "ALL_HTTP" || key == "ALL_RAW") { }

else { DropDownList2.Items.Add(key + " = " + Request.ServerVariables[key]); }

}

}

Данный код выводит все параметры клиента, кроме самых длинных (записываются в одну строку):

Рис. 3. 4. Результат работы веб-приложения ASP.NET: получений сведений о клиенте на стороне клиента

Кэширование:

Для увеличения производительности имеет смысл кэшировать некоторые страницы на определённый период времени. При кэшировании страница помещается в определённое место хранения и вызывается от туда каждый раз пока не пройдёт время её жизни. Тем самым мы можем огородить сервер от периодически повторяющихся запросов, которые возвращают всегда (или большое количество времени) один и тот же ответ.

В ASP.NET кэширование добавляется с использованием директивы страницы OutputCache. Поместим в HTML-код нашей страницы в самом верху после первой строчки следующий код:

<%@ OutputCache Duration="10" Location="server" VaryByParam="*" %>

Duration указывает, на какой интервал времени (в секундах) кэшировать страницу.

Location указывает, где будет храниться кэш.

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

Откомпилируем страницу, и попробуем «побегать» по меню навигации и нажимать F5. Время не будет менять в текстовом поле в течение 10 минут (на серверные кнопки не распространяется).

Создаем пользовательский элемент:

При многократном использовании каких либо элементов управления, можно создать свой собственный и использовать его в любом месте веб-приложения. Создаём. Выполним Проект -> Добавить новый элемент...: ищем в открывшемся окне Пользовательский веб-элемент управления. Вводим Имя: MyControl.ascx, жмём ОК.

Открываем HTML-код элемента, перемещаем курсор на пустое место внутри кода и последовательно перетаскиваем DropDownList, Button и TreeView (группа Переходы панели элементов). Настраиваем «дерево» элементов TreeView (смарт-тэг «Правка узлов...»):

Рис. 3. 5. Редактор узла TreeView: создаём «дерево» по своему вкусу

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

Также, изменяем стиль «дерева» (смарт-тэг «Автоформат...») на стиль «MSDN». Основные свойства элемента TreeView которые будут также изменены (показываем линии «дерева» и ставим CheckBox около каждого элемента:

ShowLines:

True

ShowCheckBoxes:

All

HTML-код пользовательского элемента будет таким:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="LWP18ASPNET.MyControl" %>

<asp:DropDownList ID="DropDownList1" runat="server">

</asp:DropDownList>

<asp:Button ID="Button1" runat="server" Text="Показать выделенные узлы"

onclick="Button1_Click" />

<asp:TreeView ID="TreeView1" runat="server" ImageSet="Msdn" NodeIndent="10"

ShowCheckBoxes="All" ShowLines="True">

<HoverNodeStyle BackColor="#CCCCCC" BorderColor="#888888" BorderStyle="Solid"

Font-Underline="True" />

<Nodes>

<asp:TreeNode Text="Корень № 1" Value="Корень № 1">

<asp:TreeNode Text="1, 1" Value="1, 1"></asp:TreeNode>

</asp:TreeNode>

<asp:TreeNode Text="Корень № 2" Value="Корень № 2">

<asp:TreeNode Text="2, 2" Value="2, 2"></asp:TreeNode>

<asp:TreeNode Text="2, 1" Value="2, 1"></asp:TreeNode>

</asp:TreeNode>

<asp:TreeNode Text="Корень № 3" Value="Корень № 3">

<asp:TreeNode Text="3, 1" Value="3, 1">

<asp:TreeNode Text="3, 1, 1" Value="3, 1, 1"></asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

<asp:TreeNode Text="Корень № 4" Value="Корень № 4">

<asp:TreeNode Text="4, 1" Value="4, 1">

<asp:TreeNode Text="4, 1, 1" Value="4, 1, 1">

<asp:TreeNode Text="4, 1, 1, 1" Value="4, 1, 1, 1"></asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

<asp:TreeNode Text="Корень № 5" Value="Корень № 5">

<asp:TreeNode Text="5, 1" Value="5, 1">

<asp:TreeNode Text="5, 1, 1" Value="5, 1, 1">

<asp:TreeNode Text="5, 1, 1, 1" Value="5, 1, 1, 1">

<asp:TreeNode Text="5, 1, 1, 1, 1" Value="5, 1, 1, 1, 1"></asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

</asp:TreeNode>

</Nodes>

<NodeStyle Font-Names="Verdana" Font-Size="8pt" ForeColor="Black"

HorizontalPadding="5px" NodeSpacing="1px" VerticalPadding="2px" />

<ParentNodeStyle Font-Bold="False" />

<SelectedNodeStyle BackColor="White" BorderColor="#888888" BorderStyle="Solid"

BorderWidth="1px" Font-Underline="False" HorizontalPadding="3px"

VerticalPadding="1px" />

</asp:TreeView>

Событие Click для кнопки Button1 пользовательского элемента будет добавлять в DropDownList значения всех выделенных элементов в TreeView:

protected void Button1_Click(object sender, EventArgs e)

{

DropDownList1.Items.Clear();

for (int i = 0; i < TreeView1.Nodes.Count; i++) Check(TreeView1.Nodes[i]);

}

private void Check(TreeNode tn)

{

if (tn.Checked) DropDownList1.Items.Add("[" + tn.Value + "] ");

if (tn.ChildNodes.Count > 0)

{

for (int i = 0; i < tn.ChildNodes.Count; i++) Check(tn.ChildNodes[i]);

}

}

Зарегистрируем элемент управления, используя директиву Register (регистрировать необходимо на страницах, на которых будем использовать наш элемент) на странице Default.aspx:

<%@ Register Src="~/MyControl.ascx" TagPrefix="My" TagName="SpecialControl" %>

И используем элемент управления на странице:

<p><my:specialcontrol ID="My1" runat="server" /></p>

Что получилось в итоге:

Cookie:

Мы уже рассматривали как можно хранить переменные отдельного пользователя в сессии, но чаще возникает желание хранить нечто, что сразу будет ассоциироваться с пользователем ранее посещавшим сайт. За дело берутся «cookie». «Куки» сохраняются не в сессии, а на компьютере пользователя. При первом обращении к сайту мы посылаем «кук» на машину клиента; при следующем заходе (или когда нам потребуется) мы можем запросить кук и идентифицировать пользователя или установить на сайте настройки, которые пользователь выбирал в прошлом и прочее. Итак, пользователь вводит в текстовое поле свои данныеи передаёт информацию на сервер. В ответ на это сервер отправляем ему кук с этой информацией. Воспользуемся кнопкой Button2 и полем TextBox4 (которые были созданы для работы с Panel):

Текст события Click кнопки Button2 перепишем, добавив строчку кода, которая отправляет написанное в TextBox4 в cookie-файл пользователя:

protected void Button2_Click(object sender, EventArgs e)

{

Panel1.Visible = false;

Panel2.Visible = true;

Response.Cookies["TextC"].Value = TextBox4.Text;

Label1.Text = TextBox4.Text;

}

Добавим следующий код в событие Page_Load:

Response.Cookies["Text"].Expires = DateTime.Now.AddHours(1); // Время жизни cookie

if (Request.Cookies["TextC"] != null) // Получаем значение cookie

{

Panel2.Visible = true;

Label1.Text = Request.Cookies["TextC"].Value;

TextBox4.Text = Request.Cookies["TextC"].Value;

}

Код при загрузке страницы проверяет наличие cookie с полем TextC, если не пустое и существует, заполняем TextBox4. Также этот код устанавливает «время жизни» cookie с нашего сайта (1 час). В результате, вводим данные в текстовое поле, открываем ещё одну страницу браузера и видим введённое нами число в нужном поле:

Для проверки можно переключиться между страницами сайта и убедиться, что другие элементы управления сбрасываются после обновления страницы.

Web.config:

В ASP.NET реализован интересный механизм, который позволяет перекрывать практически все настройки веб сервера: файл Web.config. В данном файле описываются все свойства веб приложения. Благодаря этому файлу больше не потребуется обращаться, например, к хостинг провайдеру, где лежат файла сервера для изменения параметров веб-сервера, всё можно описать в этом файле. Файл представляет собой XML документ, рассмотрим некоторые секции.

Код ниже, позволяет указать выводить или нет отладочную информацию на страницу при возникновении ошибки (секция <system.web> ... </system.web>):

<compilation debug="true" targetFramework="4.0" />

Код ниже устанавливает способ авторизации:

<authentication mode="Forms">

<forms loginUrl="~/Account/Login.aspx" timeout="2880" />

</authentication>

Код ниже устанавливает режим хранения сессии:

<sessionState mode="StateServer"></sessionState>

Код ниже устанавливает параметры глобализации:

<globalization

fileEncoding="utf-8"

requestEncoding="utf-8"

responseEncoding="utf-8"

culture="ru-RU"

uiCulture="ru-RU" />

Код ниже позволяет настраивать стандартные ошибки HTTP:

<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">

<error statusCode="403" redirect="NoAccess.htm" />

<error statusCode="404" redirect="FileNotFound.htm" />

</customErrors>

И последнее в данной части работы. Контроль ошибок ввода на стороне пользователя:

Зачем? Можно проверять все введённые пользователем данные и на сервере, но лучше этого избегать: во-первых затрачиваются лишние ресурсы сервера, во-вторых пользователю лучше сразу показать, где ошибка, экономя его время. Итак, на стороне клиента правильность заполнения кода можно проверить на JavaScript. В ASP.NET есть несколько элементов управления, которые генерируют JavaScript с целью проверки правильного заполнения формы. Находятся в группе Проверка:

Начнём:

RequiredFieldValidator проверяет, заполнено поле или нет. Свойства элемента таковы:

  • ControlToValidtae — имя элемента, который необходимо проверить

  • Text — сообщение, об ошибке которое, покажется, в случае если поле не заполнено.

  • ErrorMessage — сообщение, об ошибке которое, покажется, в списке всех ошибок (summary).

  • ValidationGroup — задаёт имя группы проверки. Актуально если на странице две кнопки, которые могут делать постбэк. И две группы элементов, которые хотим проверять.

Добавим на страницу следующий HTML-код (элемент проверки расположен после текстового поля, шрифт ошибки изменён):

<p>

<asp:TextBox ID="TextBox6" runat="server"></asp:TextBox>

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"

ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox6"

Text="[ пожалуйста, заполните текстовое поле ]" Font-Size="Large" ForeColor="#FF3300" Font-Bold="True"></asp:RequiredFieldValidator><br />

<asp:Button ID="Button5" runat="server" Text="Выполнить" />

</p>

Запустим, нажмём серверную кнопку «Выполнить», не заполняя текстовое поле:

Второй элемент проверки: RangeValidator проверяет, входит ли введенное значение в диапазон. Ключевые свойства:

  • MaximumValue — максимальное значение.

  • MinimumValue — минимально значение.

Изменим добавленный HTML-код:

<p>

<asp:TextBox ID="TextBox6" runat="server"></asp:TextBox>

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"

ErrorMessage="RequiredFieldValidator" ControlToValidate="TextBox6"

Text="[ пожалуйста, заполните текстовое поле ]" Font-Size="Large" ForeColor="#FF3300" Font-Bold="True">

</asp:RequiredFieldValidator>

<br />

<asp:RangeValidator ID="RangeValidator1" runat="server"

ErrorMessage="RangeValidator" ControlToValidate="TextBox6"

Text="[ значение поле не в диапазоне от 0 до 100 ]" Font-Size="Large"

ForeColor="#FF3300" Font-Bold="True" MaximumValue="100" MinimumValue="0">

</asp:RangeValidator>

<br />

<asp:Button ID="Button5" runat="server" Text="Выполнить" />

</p>

RegularExpressionValidator проверяет заполнение поля по шаблону (регулярному выражению). Очень удобно, например, проверять правильность введенного E-mail адреса, тем более что в Visual Studio уже есть шаблон «e-mail».

Свойства:

  • ValidationExpression — регулярное выражение проверки.

Рис. 3. 6. Редактор регулярных выражений: редактируем свойство ValidationExpression и выбираем выражение

Добавим новый код на страницу:

<p>

<asp:TextBox ID="TextBox7" runat="server"></asp:TextBox>

<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"

ErrorMessage="RegularExpressionValidator" ControlToValidate="TextBox7"

Text="[ пожалуйста, введите корректный адрес E-mail ]" Font-Size="Large"

Font-Bold="True" ForeColor="Red"

ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"></asp:RegularExpressionValidator>

<br />

<asp:Button ID="Button6" runat="server" Text="Выполнить" />

</p>

CompareValidator сравнивает значения введённые в разные элементы управления. Таким образом, можно проверить правильность ввода пароля в два поля. Свойства:

  • ControlToCompare — элемент для сравнения.

<p>

<asp:TextBox ID="TextBox8" runat="server"></asp:TextBox>

<asp:TextBox ID="TextBox9" runat="server"></asp:TextBox>

<asp:CompareValidator ID="CompareValidator1" runat="server"

ErrorMessage="CompareValidator" ControlToValidate="TextBox8"

ControlToCompare="TextBox9" Font-Size="Large" Font-Bold="True"

Text="[ значения в текстовых полях не совпадают ]" ForeColor="Red"></asp:CompareValidator>

<br />

<asp:Button ID="Button7" runat="server" Text="Выполнить" />

</p>

CustomValidator позволяет проверить то, что не смог ни один предыдущий компонент. Для этого нужно написать стороннюю функцию роверки на стороне клиента. Свойства:

  • ClientValidationFunction — скрипт на стороне клиента.

Если полей на форме достаточно много, то имеет смысл показывать все ошибки вместе, например, вверху или внизу страницы. Для этого существует ValidationSummary. Свойства:

  • DisplayMode — определяет стиль отображения списка.

  • HeaderText — определяет заголовок списка.

  • ShowMessageBox — показывает сообщение об ошибке в JavaScript-окне.

<asp:ValidationSummary ID="ValidationSummary1" runat="server"

Font-Bold="True" Font-Size="Large" ForeColor="Red"

HeaderText="Ошибки ввода:" ShowMessageBox="True" />

Также «облагородим» свойство ErrorMessage остальных «валидаторов» (именно этот текст ловит ValidationSummary, например для CompareValidator:

<asp:CompareValidator ID="CompareValidator1" runat="server"

ErrorMessage="Значения в текстовых полях не совпадают." ControlToValidate="TextBox8"

ControlToCompare="TextBox9" Font-Size="Large" Font-Bold="True"

Text="[ значения в текстовых полях не совпадают ]" ForeColor="Red"></asp:CompareValidator>

И всплывающее окно:

С этой частью работы закончили.