Разработка АРМ на ASP.NET - Казанский (Приволжский

advertisement
КАЗАНСКИЙ (ПРИВОЛЖСКИЙ) ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ
ПИНЯГИНА О.В.
Разработка
Web-АРМ
на ASP.NET
Казань – 2012
О.В. Пинягина
УДК 004.738.5
ББК 32.973.26-018.02
Печатается по решению Редакционно-издательского совета
ФГАОУВПО «Казанский (Приволжский) федеральный университет»,
Редакционно-издательского совета Института вычислительной
математики и информационных технологий
Протокол № __ от __,
заседания кафедры экономической кибернетики
Протокол № __ от __.
Рецензенты:
…………………………………..
………………………………….
Пинягина О.В. Разработка Web-АРМ на ASP.Net / О.В. Пинягина – Казань:
Казанский университет, 2012. – 92 с.
Данное учебное пособие разработано в поддержку
курсов
«Информационные
технологии
в
экономике»,
«Электронная
коммерция» и предназначено для проведения компьютерных
лабораторных занятий и для самостоятельной работы студентов,
обучающихся по специальности «Математические методы в экономике»
и направлениям «Бизнес-информатика», «Прикладная информатика».
В пособии поэтапно рассматривается процесс разработки
автоматизированных рабочих мест для сотрудников библиотеки на базе
технологии ASP.Net и СУБД SQL server.
Электронный ресурс по данному курсу находится на сайте кафедры
экономической кибернетики Казанского государственного университета по
адресу: http://kek.ksu.ru/EOS/ITE/index.html
 Казанский университет, 2012
 Пинягина О.В., 2012
2
Разработка Web-АРМ на ASP.Net
Содержание
СОДЕРЖАНИЕ .......................................................................................... 3
ПРЕДИСЛОВИЕ ........................................................................................ 5
ЭТАП 1. РАЗРАБОТКА КОНЦЕПТУАЛЬНОЙ СХЕМЫ WEBСАЙТА .......................................................................................................... 7
ЭТАП 2. РАЗРАБОТКА СТРУКТУРЫ БАЗЫ ДАННЫХ ............... 13
ER-МОДЕЛЬ ................................................................................................ 13
РЕЛЯЦИОННАЯ МОДЕЛЬ ............................................................................. 14
КОНФИГУРИРОВАНИЕ ПРИЛОЖЕНИЯ ........................................................ 15
СОЗДАНИЕ ТАБЛИЦ В SQL SERVER ........................................................... 18
ОБЗОР ASP.NET ....................................................................................... 21
ЭТАП 3. РАЗРАБОТКА СИСТЕМЫ РЕГИСТРАЦИИ И
АВТОРИЗАЦИИ ПОЛЬЗОВАТЕЛЕЙ ................................................. 24
АВТОРИЗАЦИЯ СОТРУДНИКОВ .................................................................. 24
ЛИЧНЫЙ КАБИНЕТ СОТРУДНИКА .............................................................. 27
РЕГИСТРАЦИЯ ЧИТАТЕЛЕЙ ........................................................................ 30
АВТОРИЗАЦИЯ ЧИТАТЕЛЕЙ ....................................................................... 34
ЭТАП 4. РАЗРАБОТКА МАСТЕР-СТРАНИЦ .................................. 37
ЭТАП 5. РАЗРАБОТКА СЦЕНАРИЕВ ПОИСКА И ПРОСМОТРА
ДАННЫХ ................................................................................................... 41
ПОИСК И ПРОСМОТР ЧИТАТЕЛЯ В АРМ БИБЛИОТЕКАРЯ .......................... 41
ПОИСК И ПРОСМОТР КНИГ В АРМ БИБЛИОТЕКАРЯ .................................. 48
ЭТАП 6. РАЗРАБОТКА СЦЕНАРИЕВ ДОБАВЛЕНИЯ,
РЕДАКТИРОВАНИЯ И УДАЛЕНИЯ ДАННЫХ .............................. 54
УПРАВЛЕНИЕ ИЗДАТЕЛЯМИ И КАТЕГОРИЯМИ........................................... 54
РЕГИСТРАЦИЯ НОВЫХ КНИГ ...................................................................... 57
ПОИСК КНИГ И СОЗДАНИЕ ЭКЗЕМПЛЯРОВ................................................. 59
ВЫДАЧА И ПРИЕМ КНИГ ............................................................................ 65
ЭТАП 7. ВЫГРУЗКА И ЗАГРУЗКА ДАННЫХ В ФОРМАТЕ XML
...................................................................................................................... 68
ЗАГРУЗКА ДАННЫХ ИЗ XML-ФАЙЛА В БАЗУ ДАННЫХ ............................. 68
ВЫГРУЗКА ДАННЫХ В XML-ФАЙЛ ........................................................... 70
3
О.В. Пинягина
ПРИЛОЖЕНИЕ 1. ВОПРОСЫ И ОТВЕТЫ ...................................... 74
ПРИЛОЖЕНИЕ 2. КАК ОБОЙТИСЬ БЕЗ ASP.NET
CONFIGURATION ................................................................................... 79
ПРИЛОЖЕНИЕ 3. WEB-СЕРВИСЫ ................................................... 82
ПРИЛОЖЕНИЕ 4. КРАТКИЙ СПРАВОЧНИК
ИСПОЛЬЗУЕМЫХ КЛАССОВ ............................................................ 86
ЛИТЕРАТУРА .......................................................................................... 92
4
Разработка Web-АРМ на ASP.Net
Предисловие
В данном учебном пособии подробно и поэтапно рассматривается
процесс разработки Web-сайта, представляющего собой группу
автоматизированных рабочих мест для сотрудников библиотеки на
базе технологии ASP.Net и СУБД SQL server. Процесс разработки
АРМ включает следующие этапы:
1. разработка концептуальной схемы сайта;
2. разработка структуры базы данных и конфигурирование
приложения;
3. разработка системы регистрации и авторизации
пользователей;
4. разработка мастер-страниц;
5. разработка сценариев поиска и просмотра данных;
6. разработка сценариев добавления, редактирования и
удаления данных;
7. выгрузка и загрузка данных в формате XML.
Основная цель учебного пособия – помочь в изучении технологии
ASP.Net на примере конкретного практического приложения.
Предполагается, что читатель:

успешно изучил курс «Базы данных» и имеет
представление о проектировании баз данных, языке SQL и СУБД SQL
server;

успешно изучил курс «Интернет-технологии» и имеет
представление о языке HTML, архитектуре динамических Интернетприложений, клиент-серверном взаимодействии web-сервера и
браузера;

успешно изучил язык C# как основу технологии .Net в
рамках курса «Объектно-ориентированное программирование» и
имеет опыт разработки «настольных» .Net-приложений.
Эти технологии являются обязательными для понимания основ
ASP.Net и разработки на этой базе практических web-приложений.
Следует отметить, что ASP.Net представляет собой целый набор
разнообразных современных динамично развивающихся технологий, и
охватить их все в рамках одного курса не представляется возможным.
Наша программа-минимум – изучить основы. Заинтересованный
читатель может обратиться к списку литературы, приведенному в
конце пособия.
5
О.В. Пинягина
В качестве среды разработки мы будем использовать Visual
Studio 2005 и SQL server 2005 express или более поздние версии.
Среда разработки Visual Studio 2005 содержит встроенный web-сервер
для отладки проектов, его мы и будем применять. Устанавливать
полнофункциональный web-сервер MS IIS для отладки нет
необходимости, он нужен только для развертывания сайта в Интернет.
Для создания проекта в VS выберите File – New – Web site –
ASP.NET Website. Путь к сайту может быть любым, нежелательно
только в имени пути использовать русские буквы. Зададим, например,
путь C:\WebSite. Заготовка для нашего сайта создана.
На вкладке Solution мы видим структуру нашего проекта:

каталог App_data (пока он пустой),

главная страница default.aspx (и файл C#-кодов
default.aspx.cs).
Запустим проект на выполнение (в режиме Debug!) – мы увидим,
как в браузере Internet Explorer откроется главная страница нашего
сайта. После запуска в проекте появится файл конфигурации
web.config.
Задание для самостоятельной работы. Этап 0.
Выберите предметную область – область человеческой
деятельности, для которой вы будете разрабатывать АРМ. Выбирайте
такую тему, которую вы хорошо представляете себе или, по крайней
мере, знаете источник, у которого можно проконсультироваться.
Можете выбрать тему, по которой вы создавали проект в рамках курса
«Базы данных».
Очевидно, что разрабатываемый проект носит, главным образом,
учебный характер, но полученный результат должен быть достаточно
правдоподобным.
Создайте в Visual Studio заготовку для вашего сайта.
6
Разработка Web-АРМ на ASP.Net
Этап 1. Разработка концептуальной схемы web-сайта
Разработка любого проекта начинается с формулировки
требований. Итак, сформулируем в произвольной форме постановку
нашей задачи.
Требуется создать Web-сайт, представляющий собой группу
автоматизированных рабочих мест для сотрудников библиотеки.
Основная цель библиотеки – выдача книг читателям. Для
осуществления этой цели нужно вести базу книг, учитывать новые
поступления, списывать ветхие или утерянные экземпляры, вести учет
выдач и возврата книг читателями, рассылать напоминания о
просроченных книгах и т. п.
Определим, прежде всего, какие роли пользователей будут нужны
для нашего приложения (роли и пользователи являются стандартными
средствами ASP.Net и не требуют создания отдельных таблиц). Роли
обычно соответствуют некоторым должностям и характеризуется
разными уровнями доступа к разной рабочей информации. В нашей
библиотеке мы выделим роли:
 сотрудник отдела комплектования,
 сотрудник книгохранилища,
 библиотекарь;
 администратор.
Кроме того, выделим специфическую роль «читатель» (некий
«внешний» пользователь), для которой создадим отдельную таблицу.
Сотрудник отдела комплектования занимается учетом новых
поступлений. С точки зрения нашей системы он должен создавать
новые записи о книгах и заносить в базу данных подробную
информацию о них.
Сотрудник книгохранилища получает требования на выдачу книг
и регистрирует факт снятия книги с полки и возвращения на полку.
Библиотекарь занимается регистрацией новых читателей, а также
выдачей им лично в руки и возвратом книг, регистрацией просрочки
возврата, регистрацией потерянных книг, изменением информации о
читателях и удалением читателей из базы (например, по окончании
учебы).
Каждый пользователь имеет доступ к своей личной
регистрационной информации (кроме изменения логина).
7
О.В. Пинягина
Администратор занимается регистрацией пользователей и
настройкой параметров приложения.
Читатели могут просматривать каталог книг, проводить поиск
книг и оставлять заявки на нужные им книги. Кроме того, они могут
просматривать список взятых ими книг.
Теперь коротко перечислим, какая информация должна храниться
в базе данных. Для каждой книги должны быть представлены
название, автор(ы), цена, количество страниц, внешний вид обложки,
ISBN (международный код), издательство, категория, год издания,
место хранения, состояние книги. Следует учесть, что в библиотеке
часто бывает несколько экземпляров одной и той же книги. Книги
также различаются сроком выдачи – учебную литературу выдают
сроком на учебный год, прочие книги – на месяц.
Читатель характеризуется фамилией, именем, отчеством,
паспортом, датой рождения, адресом – почтовым и электронным. Для
авторизации читателя нужны логин и пароль. Читатель может
оставлять заявку на нужную ему книгу.
Факт выдачи книги характеризуется датой выдачи, сроком
возврата, датой фактического возврата, информацией о том, кто выдал
и кто принял книгу.
Для каждой роли изобразим основные режимы работы в виде
схем. Обратите внимание, что работа каждого сотрудника начинается с
авторизации.
Схема 1. Основные режимы работы читателя
Личные
данные
Просмотр
взятых книг
8
Главная страница:
авторизация
ое меню страница
Поиск
книги
Просмотр
заявок
Заявка на
книгу
Разработка Web-АРМ на ASP.Net
Схема 2. Основные режимы работы сотрудника отдела комплектования
Главная страница:
авторизация
ое меню страница
Работа с книгами
Списание
экземпляра
Создание книги
Поиск* и
просмотр книги
Поиск и просмотр
экземпляра
Создание
экземпляра
Редактирование
книги
Редактирование
экземпляра
В языке UML подобные схемы называются Use case – варианты
использования. Пунктиром на схеме отмечен автоматический возврат
в соответствующий режим работы после завершения редактирования.
Схема 3. Основные режимы работы сотрудника книгохранилища
Главная страница:
авторизация
ое меню страница
Список книг
на выдачу
Обработка
требования –
выдача книги
Поиск*
книги
Список книг
на возврат
Прием
возвращенной
книги
____________________________________________________________________________
*Обратите внимание, что в современных библиотеках сотрудники имеют возможность
работать со штрих-кодами на читательских билетах и книгах. Это существенно ускоряет
процедуру поиска.
9
О.В. Пинягина
Схема 3. Основные режимы работы библиотекаря
Главная страница:
авторизация
ое меню страница
Работа с читателями
Регистрация
читателя
Работа с книгами
Поиск и
просмотр
читателя
Поиск и
просмотр
книги
Редактирование
Выдача
Возврат
Приведем эскизы основных страниц сайта.
Главная страница нашего сайта может иметь примерно такой вид:
10
Разработка Web-АРМ на ASP.Net
Поскольку эта страница загружается по умолчанию, оставим ее
название default.aspx, хотя содержание страницы представляет собой
исключительно HTML-код, без каких-либо серверных команд.
АРМ библиотекаря:
АРМ сотрудника отдела комплектования:
11
О.В. Пинягина
Задание для самостоятельной работы. Этап 1.
В произвольной форме разработайте концептуальную схему
вашего проекта. Коротко опишите требования к системе, определите
роли пользователей и режимы их работы. В рамках вашего проекта
должно быть не менее 2 ролей пользователей. База данных должна
содержать не менее 5 таблиц. Имейте в виду, что пользователями
вашей системы должны быть именно сотрудники некоторого
предприятия. Интерфейс для «внешнего» пользователя (покупателя,
читателя, клиента) разрабатывать не обязательно.
12
Разработка Web-АРМ на ASP.Net
Этап 2. Разработка структуры базы данных
ER-модель
На основе описания требований к проекту составим модель
сущностей–связей для базы данных.
Сущность «книга» характеризуется уникальным номером ISBN,
автором, названием, годом издания, ценой, количеством страниц,
обложкой. Атрибуты книги «издательство» и «категория» выделим в
отдельные сущности-справочники.
13
О.В. Пинягина
В библиотеке может быть несколько экземпляров одной и той же
книги. Чтобы избежать дублирования информации, выделим
отдельную сущность «экземпляр», которая связана с книгой связью
многие-к-одному. Свойство «статус» может принимать значения «в
хранилище», «на абонементе», «выдан». Свойство «состояние» может
принимать значения «годен», «списан», «утерян».
Сущность «читатель» содержит атрибуты: номер читательского
билета, ФИО, адрес, телефон, e-mail, номер паспорта, логин, пароль.
Сущность «сотрудник» содержит атрибуты: номер сотрудника,
ФИО, адрес, телефон, e-mail, должность, логин, пароль.
Для фиксации информации о заявках и выдачах книг создадим
слабую сущность «заявка(выдача)», которая будет содержать дату
заявки, а также информацию о выдаче книги: дату выдачи, срок
возврата, фактическую дату возврата, логин библиотекаря, выдавшего
и принявшего книгу.
Реляционная модель
Преобразуем ER-модель
следующие таблицы.
в
реляционную
модель.
Получим
Книга(ISBN, Название, Автор, Цена, Год, Страницы, Обложка, Тип,
НомИзд, НомКат) - ISBN будет внешним ключом для таблицы
Экземпляр.
Издатель(НомИзд, НазИзд)
ключом для таблицы Книга.
– столбец НомИзд является внешним
Категория(НомКат, НазКат) – столбец НомКат является внешним
ключом для таблицы Книга.
Экземпляр (НомЭкз, Статус, Состояние, ISBN) –
внешним ключом для таблицы Заявка.
НомЭкз будет
Сотрудник (Логин, Пароль, ФИОСотр, АдрСотр, ТелефСотр, EmailСотр, Должность) – на самом деле таблица пользователейсотрудников (точнее, несколько таблиц) автоматически создается в
14
Разработка Web-АРМ на ASP.Net
проекте ASP.Net, об этом мы будем говорить подробнее в дальнейшем,
а пока примем за первичный ключ сотрудника его Логин.
Читатель(НомБилета, Логин, Пароль, ФИОЧит, Паспорт, ДатаРожд,
АдрЧит, ТелефЧит, E-mailЧит) – логин тоже является уникальным, но
для удобства сделаем первичным ключом номер билета.
ЗаявкаВыдача(НомБилета,
НомЭкз, ДатаЗаявки, ДатаВыдачи,
СрокВозврата, ДатаВозврата, ЛогинВыдал, ЛогинПринял) – слабая
сущность в составе своего первичного ключа содержит все первичные
ключи своих сильных сущностей.
Конфигурирование приложения
Для создания базы данных воспользуемся визуальными
возможностями
Visual
Studio,
предусмотренными
для
администрирования приложения. Выберем в главном меню Web Site –
ASP.Net
Configuration,
запустится
web-страница
для
конфигурирования приложения. Перейдем на закладку Provider и
щелкнем по гиперссылке Select a single provider for all site
management data. Здесь указан единственно возможный провайдер
данных AspNetSqlProvider. Щелкнем по гиперссылке test. Получим
сообщение «Successfully established a connection to the database».
Теперь настроим тип аутентификации. Здесь есть два варианта:
либо использовать учетные записи Windows, либо создавать и хранить
пользователей, роли и полномочия в нашей собственной базе данных.
Используем второй вариант. Выберите закладку Security – Select
authentication type – From the internet и нажмите на кнопку Done. В
папке App_data нашего проекта появится файл aspnetdb.mdf – это и
есть файл базы данных SQL server.
Теперь будем создавать роли: на закладке Security щелкните по
гиперссылке Enable roles, а затем по гиперссылке Create or Manage
roles. Создадим 3 роли – librarian, collector, warehouse. Роль читателя
будем обрабатывать отдельно.
Для каждой роли нужно назначить права доступа. Сначала в
нашем проекте создадим для каждой роли отдельную папку, куда в
дальнейшем будем помещать файлы сценариев (если к каким-то
15
О.В. Пинягина
сценариям должны иметь доступ разные роли, для таких сценариев
тоже можно создать отдельную папку). Затем на вкладке Security
будем использовать ссылки Create access rules и Manage access rules.
Здесь можно разрешать (allow) или запрещать (deny) доступ разных
пользователей и ролей к папкам. Например, для папки librarian
(библиотекарь) назначение прав доступа будет выглядеть следующим
образом:
Права доступа назначаются в этой таблице снизу вверх. По
умолчанию разрешается доступ для всех пользователей (этот режим
невозможно отменить, так как он наследуется из родительского
каталога). Мы сначала запрещаем доступ для всех ролей, а затем
разрешаем доступ для библиотекаря. Таким образом, кроме
библиотекаря, никто другой не сможет запустить сценарии из этого
каталога.
При попытке доступа к этому каталогу из любой другой роли
будет выполняться автоматическая переадресация на страницу
авторизации (login.aspx).
16
Разработка Web-АРМ на ASP.Net
Назначенные нами права доступа
сохраняются в файле
конфигурации web.config соответствующего каталога и выглядят
примерно так:
<authorization>
<allow roles="librarian" />
<deny users="*" />
</authorization>
Теперь создадим, по крайней мере, по одному пользователю для
каждой роли. Обратите внимание, что по умолчанию пароль должен
содержать не менее 7 символов, и не менее чем одним символ должен
быть небуквенным и нецифровым. Не забудьте привязать пользователя
к роли, т.е., отметить соответствующий флажок в столбце “Roles”.
У вас может возникнуть вопрос – а где же, собственно, будут
сохраняться все эти данные? Для них Visual Studio автоматически
создает необходимые таблицы. Откройте в проекте вкладку Server и
посмотрите, какие таблицы имеются по умолчанию в нашей базе
данных:
17
О.В. Пинягина
 роли хранятся в таблице aspnet_Roles,
 пользователи – в таблицах aspnet_Users и aspnet_Membership,
 связь пользователей с ролями – в таблице apsnet_UsersInRoles.
Вы, наверное, обратили внимание, что у пользователей нет ни
ФИО, ни должности, ни адреса? Для этих и прочих дополнительных
полей мы будем в дальнейшем использовать такое понятие, как
Profile. Отложим этот вопрос до следующего этапа.
Создание таблиц в SQL server
Нам осталось создать остальные нужные нам для работы таблицы.
Выберите базу данных, папку Tables, щелкните правой кнопкой
мыши, выберите Add new table и создавайте структуру таблиц в
визуальном режиме. Для задания первичного ключа выберите нужное
поле таблицы (для составного ключа нужно выделить несколько
полей), щелкните правой кнопкой мыши и выберите пункт «Set
primary key». Рядом с названием появится изображение ключика.
Наши таблицы имеют следующую структуру:
Categories (Категории)
Имя столбца
Тип (размер)
Дополнительно
Id_cat
Int
Identity, первичный ключ
Name_cat
Nchar(100)
Not null
Publishers (Издатели)
Имя столбца
Тип (размер)
Дополнительно
Id_publ
Int
Identity, первичный ключ
Name_publ
Nchar(100)
Not null
Имя столбца
Тип (размер)
Дополнительно
ISBN
Nchar(20)
Not null, первичный ключ
Name_book
Nchar(100)
Not null
Author
Nchar(100)
Not null
Books (Книги)
18
Разработка Web-АРМ на ASP.Net
Price
Decimal(6,2)
Not null
Year
Decimal(4,0)
Not null
Pages
Int
Not null
Type
Smallint
Not null, 1 – учебная, 0– прочая
Id_cat
Int
Not null, default=1
Id_publ
Int
Not null, default=1
Image
Varchar(50)
Not null
Items (Экземпляры)
Имя столбца
Тип (размер)
Дополнительно
Id_item
Int
Identity, первичный ключ
State
Int
Not null, 0– годен, 1– списан, 2 –утерян.
Status
Int
ISBN
Nchar(20)
Not null, 0 – в хранилище, 1 – на
абонементе, 2 – на руках
Not null
Для удобства заполнения состояния и местонахождения
экземпляра книги создадим вспомогательные таблицы State и Status
State (Состояние)
Имя столбца
Тип (размер)
Дополнительно
Id_state
Int
Первичный ключ
Name_state
Nchar(20)
Not null
Status (Местонахождение)
Имя столбца
Тип (размер)
Дополнительно
Id_status
Int
Первичный ключ
Name_status
Nchar(20)
Not null
Readers (Читатели)
Имя столбца
Тип (размер)
Дополнительно
Id_reader
Int
Identity, первичный ключ
Login
Nchar(10)
Not null
Password
Nchar(10)
Not null
19
О.В. Пинягина
FIO_reader
Nchar(50)
Not null
Passport
Numeric(10)
DateBird
Datetime
Addr_reader
Nchar(100)
Tel_reader
Nchar(20)
Email_reader
Nchar(20)
Not null
Имя столбца
Тип (размер)
Дополнительно
Id_reader
Int
Not null, часть первичного ключа
Id_item
Int
Not null, часть первичного ключа
Date_order
Datetime
Not null, часть первичного ключа
Date_get
Datetme
Date_return
Datetime
Deadline
Datetime
Login_give
Nchar(10)
Login_take
Nchar(10)
Orders (Заявки)
Задание для самостоятельной работы. Этап 2.
Разработайте для вашей базы данных ER-модель, реляционную
модель, создайте таблицы в SQL server. Через интерфейс
администратора настройте конфигурацию сайта, создайте роли,
пользователей, назначьте им права доступа.
20
Разработка Web-АРМ на ASP.Net
Обзор Asp.Net
Как читателю уже известно, ASP.NET – это новая технология
компании Microsoft для создания серверных Web-приложений. Она
входит в состав платформы Microsoft .Net Framework, которая
представляет собой набор тесно связанных друг с другом новых
революционных технологий, от технологий доступа к базам данных
до технологий создания распределенных приложений. ASP.NET
является одним из самых важных компонентов .NET Framework и
позволяет разрабатывать современные высокопроиз-водительные
Web-приложения и Web-службы.
Семь важных фактов об ASP.NET [1]
1. ASP.Net интегрирована с .Net Framework.
Среда .Net Framework содержит обширную коллекцию классов,
структур, интерфейсов – более 7000 типов. Они сгруппированы в
пространства имен. Интересно отметить, что способ использования
классов в ASP.NET ничем не отличается от способа применения их в
любом другом типе приложения .NET (Windows-приложение,
Windows-служба, консольное приложение и т.п.)
2. ASP.NET компилируется, а не интерпретируется.
Приложения ASP.NET всегда компилируются – фактически
невозможно выполнить код C# или VB.NET без его предварительной
компиляции.
В действительности эти приложения проходят два этапа
компиляции. На первом этапе код C# (или другого языка)
компилируется в код промежуточного языка под названием Microsoft
Intermediate Language (MSIL, или IL). Этот этап может произойти
автоматически при первом запросе страницы, или его можно
выполнить заранее. Скомпилированный файл с кодом IL называется
сборкой.
Второй
этап компиляции наступает непосредственно перед
фактическим выполнением страницы. На этом этапе
код IL
компилируется в низкоуровневый машинный код. Этот этап называют
также Just-in-time компиляцией и он проходит одинаково для всех
приложений .NET.
21
О.В. Пинягина
3. ASP.NET поддерживает несколько языков.
Это языки Visual Basic, Visual C#, Visual J# (в Visual Studio 2005).
Какой бы язык не использовал разработчик .NET, код все равно
компилируется в MSIL. Фактически MSIL – это единственный язык,
который понимает среда выполнения Common Language Runtime.
4. ASP.NET функционирует внутри исполняющей среды CLR.
Возможно, наиболее важный аспект, касающийся ASP.NET – это
ее функционирование внутри исполняющей среды CLR. Основные
преимущества CLR: автоматическое управление памятью и сборка
мусора, безопасность типов, понятие метаданных, структурированная
обработка ошибок, многопоточность.
5. ASP.NET является объектно-ориентированной технологией.
Разработчик может в полной мере использовать многочисленные
классы и интерфейсы .NET Framework, а также разрабатывать
собственные.
Один из лучших примеров объектно-ориентированного мышления
в ASP.NET можно найти в так называемых «серверных элементах
управления». Серверные элементы управления представляют собой
инкапсуляцию в миниатюре. Разработчики могут программно
манипулировать объектами управления с использованием кода для
настройки их внешнего вида, предоставления данных для отображения
и даже реакции на события. Низкоуровневые подробности HTML
«спрятаны за сценой». Вместо того чтобы вынуждать разработчика
писать «сырой» HTML вручную, объекты управления преобразуются в
HTML по завершении визуализации страницы. Таким образом,
ASP.NET предлагает серверные элементы управления в качестве
способа устранения низкоуровневых подробностей программирования
на HTML и HTTP.
6. ASP.NET поддерживает множество устройств и браузеров.
Одна из самых сложных проблем для Web-разработчиков –
совместимость разрабатываемого приложения с большим количеством
современных браузеров. Различные браузеры, версии и конфигурации
по-разному поддерживают HTML. В ASP.NET серверные элементы
22
Разработка Web-АРМ на ASP.Net
управления способны генерировать
возможностям клиента.
HTML-код, адаптируясь к
7. ASP.NET легко развертывается и конфигурируется.
Еще одной сложной проблемой для разработчиков является
развертывание готового приложения на реальном web-сервере.
Необходимо не только переместить файлы Web-страниц, базы данных
и компоненты, но также повторно создать множество параметров
конфигурации. В ASP.NET этот процесс существенно упрощен.
Развертывание осуществляется обычным копированием. Большинство
установок конфигурации приложения или его отдельных каталогов
хранятся в специальных файлах ASP.NET web.config. Этот файл
содержит иерархически сгруппированные настройки приложения,
хранимые в удобочитаемом формате XML, который можно
редактировать с использованием простого текстового редактора,
подобного Notepad.
Итак, приступим непосредственно к разработке нашего ASP.NETприложения.
23
О.В. Пинягина
Этап 3. Разработка системы регистрации и авторизации
пользователей
Авторизация сотрудников
Наших сотрудников регистрирует администратор через
служебный web-интерфейс, поэтому начнем сразу с системы
авторизации сотрудников. На главной странице нашего сайта есть
гиперссылка «вход для сотрудников», которая ссылается на файл
login.aspx. Создадим этот файл: File – New – File, изменим имя файла
на login.aspx и обратим внимание на флажок «Place code in separate
file». Этот флажок означает, что на самом деле будет создан еще и
файл login.aspx.cs, в который мы будем помещать код программы на
C# – функции-обработчики, выполняемые на серверной стороне.
По умолчанию созданный aspx-файл содержит тег
<form id="form1" runat="server">
который представляет собой так называемую «серверную форму» – то
есть объект, для которого можно задавать функции-обработчики,
выполняемые на сервере перед отправкой в браузер. По умолчанию
сценарий вызывает сам себя. Запомните, что в пределах одной webстраницы можно разместить только одну серверную форму – иначе
возникнет ошибка компиляции. Обычных HTML-форм можно
размещать сколько угодно.
Выберем на вкладке Toolbox секцию Login, выберем в этой
секции объект Login и поместим на нашу форму. Он выглядит (в
режиме Design) следующим образом:
а его код выглядит так:
<asp:Login ID="Login1" runat="server">
</asp:Login>
24
Разработка Web-АРМ на ASP.Net
Очевидно, этот объект следует подкорректировать, хотя бы для
замены надписей на русские. Для этого щелкнем правой кнопкой на
объекте и выберем пункт «Convert to template». Теперь можно
изменять составные части объекта. Используйте для этого окно
Properties.
Если мы теперь заглянем в код страницы, то теперь увидим там
более подробные теги. Например, теги для имени пользователя будут
выглядеть так
<tr>
<td align="right">
<asp:Label ID="UserNameLabel" runat="server"
AssociatedControlID="UserName"> Логин:</asp:Label></td>
<td>
<asp:TextBox ID="UserName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="UserNameRequired"
runat="server" ControlToValidate="UserName"
ErrorMessage="Имя не может быть пустым."
ToolTip="Имя не может быть пустым."
ValidationGroup="Login1">*</asp:RequiredFieldValidator>
</td>
</tr>
Здесь сначала создается метка <asp:Label ...>, затем
текстовое поле <asp:TextBox ...>, а затем специальный объект для
проверки непустоты этого поля: <asp:RequiredFieldValidator ...>.
Этот объект проявит себя, если пользователь не заполнит поле имени и
нажмет кнопку Log In. Кстати, эта проверка выполняется на
клиентской стороне – сервер генерирует для этого специальные
клиентские обработчики.
Обработку ошибок объект-логин берет на себя. А вот в случае
успешной авторизации обработку придется написать самим. Если
сотрудник успешно авторизован, то его следует переадресовать на
главную страницу АРМ, соответствующего его роли. Для этого в
файле login.aspx.cs зададим обработку для события загрузки страницы:
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if(HttpContext.Current.User.IsInRole("librarian"))
Response.Redirect("~/librarian/Default.aspx");
else if
(HttpContext.Current.User.IsInRole("warehouse"))
Response.Redirect("~/warehouse/Default.aspx");
25
О.В. Пинягина
else if
(HttpContext.Current.User.IsInRole("collector"))
Response.Redirect("~/collector/Default.aspx");
}
}
Здесь сначала выполняется проверка, аутентифицирован ли
пользователь. Если да, то проверяем, относится ли пользователь к
одной из трех наших ролей. В случае положительного ответа
выполняем перенаправление с помощью объекта Response – это
специальный объект, который инкапсулирует информацию об ответе
сервера браузеру.
Для выхода из авторизованного режима создадим очень простой
сценарий. Он не имеет никаких визуальных элементов и содержит
только единственный обработчик загрузки страницы:
protected void Page_Load(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Session.RemoveAll();
Session.Clear();
Response.Redirect("default.aspx");
}
В этом обработчике мы выходим из авторизованного режима и
выполняем переадресацию на главную страницу сайта.
Примечание: для неавторизованных пользователей любая попытка
попасть на защищенную страницу приводит к автоматической
переадресации на страницу login.aspx. Поменяем это назначение на
страницу default.aspx. Для этого в корневом файле web.config найдем
строку
<authentication mode="Forms"/>
и заменим ее на:
<authentication mode="Forms">
<forms loginUrl="default.aspx"/>
</authentication>
26
Разработка Web-АРМ на ASP.Net
Личный кабинет сотрудника
Итак, авторизация нами успешно обработана. Создадим заодно
страничку для личного кабинета сотрудников, где они смогут
изменить свой пароль, а также заполнить дополнительные сведения о
себе: ФИО, адрес, телефон и т.п.
Для хранения дополнительных данных о сотруднике используем
такое понятие, как Profile. В файле web.config корневого каталога
внутри секции
<system.web> . . . </system.web>
создадим специальную секцию
<!-- добавляем поля пользователю -->
<profile enabled="true" >
<properties>
<group name="PersonalInfo">
<add name="UserFIO" type="string" />
<add name="UserAddr" type="string" />
<add name="UserTel" type="string" />
<add name="UserState" type="string" />
</group>
</properties>
</profile>
27
О.В. Пинягина
Теперь для авторизованного пользователя эти свойства будут
доступны (и для чтения, и для записи) через объект Profile, а
обращаться к ним можно будет так: Profile.PersonalInfo.UserFIO и
т.п.
Создадим файл cabinet.aspx, разместим в форме метки (label),
текстовые поля (textbox) и кнопку (button) из стандартной секции
панели Toolbox. Они выглядят так:
<asp:Label ID="Label1" runat="server" Text="ФИО"></asp:Label>
<asp:TextBox ID="txtFIO" runat="server"></asp:TextBox>
. . .
<asp:Button ID="Button1" runat="server" Text="Сохранить" />
Рядом c полем txtFIO разместим элемент для проверки непустоты
поля: элемент управления RequiredFieldValidator из вкладки Tools
секции Validation. Установим у него значение свойства
ControlToValidate=txtFIO и изменим свойство Text=Поле ФИО не
может быть пустым! В тексте сценария он будет выглядеть так:
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ErrorMessage="RequiredFieldValidator"
ControlToValidate="txtFIO">
Поле ФИО не может быть пустым!
</asp:RequiredFieldValidator>
Все эти элементы управления являются так называемыми
«серверными элементами управления», т.е., когда форма вызывает
сама себя, мы можем для элементов управления задавать серверные
функции-обработчики. Назначим на кнопку серверный обработчик:
запишем OnClick="Update" в коде кнопки на aspx-странице либо
назначим свойство Click=Update в окне Properties.
В файл
cabinet.aspx.cs поместим код этого обработчика, который записывает
значения из текстовых полей в профиль пользователя:
protected void Update(object s, EventArgs e)
{
Profile.PersonalInfo.UserFIO = txtFIO.Text;
Profile.PersonalInfo.UserAddr = txtAddr.Text;
Profile.PersonalInfo.UserTel = txtTel.Text;
Profile.PersonalInfo.UserState = txtState.Text;
}
Для чтения данных из профиля пользователя предусмотрим
обработчик загрузки страницы.
protected void Page_Load(object sender, EventArgs e)
28
Разработка Web-АРМ на ASP.Net
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
Response.Redirect("login.aspx");
if (!IsPostBack)
{
txtFIO.Text = Profile.PersonalInfo.UserFIO;
txtAddr.Text = Profile.PersonalInfo.UserAddr;
txtTel.Text = Profile.PersonalInfo.UserTel;
txtState.Text = Profile.PersonalInfo.UserState;
}
}
Этот обработчик сначала проверяет, аутентифицирован ли
пользователь, и если нет, то перенаправляет его на страницу
авторизации. Если же пользователь уже авторизовался, проверяем,
первый ли раз загружена страница. Если страница загружена первый
раз, то мы переписываем данные из профиля пользователя в текстовые
поля. Если же форма уже вызывала сама себя, то данные показаны на
экране и нам не нужно читать их из профиля.
Для изменения пароля создадим страницу changepass.aspx.
Добавим на страницу элемент управления ChangePassword из
секции Login. Для редактирования его составных частей в
контекстном меню выберем строкy «Convert to template». Измените
сообщения на русские, не забудьте также у объекта ChangePassword1
изменить свойство ChangePasswordFailureText на «Неверный пароль
или новый пароль. Длина пароля должна быть не менее {0}. Число
29
О.В. Пинягина
нецифросимвольных знаков: {1}.» и назначить страницу перехода
после успешного изменения пароля SuccessPageURL, например:
сabinet.aspx.
Регистрация читателей
Информация о читателях у нас хранится в отдельной таблице,
поэтому для регистрации и авторизации читателей придется создавать
отдельный интерфейс. Создадим сценарий RegReader.aspx в каталоге
библиотекаря Librarian, поскольку именно библиотекари занимаются
регистрацией новых читателей.
Нам нужно получить доступ к таблице readers. Технология
доступа к базам данных в .NET называется ADO.NET. Эта технология
содержит много разнообразных классов для доступа и представления
информации. Мы будем использовать только некоторые из них.
Заинтересованный читатель может обратиться, например, к книге [5],
полностью посвященной этой технологии.
30
Разработка Web-АРМ на ASP.Net
Поместим на страницу элемент управления SQLDataSource
(источник данных) из группы Data с вкладки Tools. Этот элемент
управления не имеет визуального представления в браузере
пользователя, поэтому его можно помещать в любое место нашей
страницы.
Теперь источнику данных нужно назначить свойство
ConnectionString, в качестве значения свойства можно выбрать имя
файла базы данных ASPNETDB.MDF. При этом автоматически
устанавливается свойство ProviderName = System.Data.SqlClient.
Разместим на нашей странице метки (label), текстовые поля
(textbox) и кнопку (button) из стандартной секции панели Toolbox.
(Если текстовые поля и прочие элементы не хотят
переименовываться в окне свойств, можете переименовать их прямо
в aspx-тексте сценария.)
Для каждого текстового поля зададим свой валидатор
RequiredFieldValidator (как мы это делали в личном кабинете
сотрудника).
Для поля почтового адреса зададим валидатор, проверяющий
регулярные выражения – RegularExpressionValidator. У него нужно
назначить свойство ControlToValidate=имя_текстового_поля_для_email и свойство ValidationExpression (выбрать из списка «Internet email address»). Напомним, что эти проверки будет выполнять браузер
без отправки данных на сервер.
Информация о нашем пользователе содержит такое поле, как дата
рождения. Поскольку для ввода даты мы используем текстовое поле,
следует организовать проверку корректности введенной даты. Для
этого зададим пользовательский валидатор CustomValidate, назначим
ему свойство ControlToValidate=имя_текстового_поля_для_даты_
рождения и зададим обработчик ServerValidate, например, с именем
DateValidate. Текст обработчика следует помещать в файл
RegReader.aspx.cs:
protected void DateValidate(object source,
ServerValidateEventArgs args)
{
string strdate = args.Value.ToString();
try
{
DateTime date = Convert.ToDateTime(strdate);
args.IsValid = true;
31
О.В. Пинягина
}
catch (FormatException ex)
{
args.IsValid = false;
}
}
Второй параметр этой функции представляет собой значение,
проверяемое на корректность. Мы пытаемся (try) преобразовать
значение параметра (строку) к типу данных DateTime и в зависимости
от результата устанавливаем его свойство IsValid, показывающее,
является ли корректным наше значение. В том случае, когда строку не
удается
преобразовать
корректно,
возникает
исключение
FormatException, которое мы и обрабатываем.
Обратите внимание – эта проверка выполняется не в браузере, а на
сервере, уже после отправки браузером данных.
Если значение было некорректным и мы выполнили действие
args.IsValid=false,
то автоматически назначается свойство
Page.IsValid=false для всей страницы в целом. Это свойство мы
будем использовать для дальнейшей обработки.
Нам нужно выполнить еще одну проверку: поле логина должно
содержать уникальное значение. Проверить это можно, разумеется,
только серверными средствами.
Создадим для логина
пользовательский валидатор CustomValidate, назначим ему свойство
ControlToValidate= имя_текстового_поля_для_логина и зададим
обработчик ServerValidate, например, с именем LoginValidate. Текст
обработчика помещаем в файл RegReader.aspx.cs:
protected void
LoginValidate(object source,
ServerValidateEventArgs args)
{
DataView DataView1;
SqlDataSource1.SelectCommand =
"SELECT * FROM Readers WHERE login=@login";
DataView1 = (DataView)SqlDataSource1.Select
(DataSourceSelectArguments.Empty);
if (DataView1.Count != 0)
{
args.IsValid = false;
}
}
32
Разработка Web-АРМ на ASP.Net
В этом обработчике нам нужно обратиться к базе данных и
проверить, не существует ли уже такого логина в таблице Readers. С
помощью уже заданного источника данных формулируем запрос на
выборку. Источник данных имеет соответствующие средства для
этого: свойство SelectCommand и метод Select.
В выполняемой команде в качестве значения логина используется
так называемый параметр команды SELECT с именем @login. Его
следует предварительно объявить в тексте сценария следующим
образом:
<SelectParameters>
<asp:ControlParameter ControlID="txtlogin" Name="login"
Type="String" />
</SelectParameters>
(можно также задать этот параметр запроса визуальным образом в
построителе запроса через свойство SelectQuery источника данных).
Чтобы получить значение из элемента управления на форме, параметр
связывается с элементом управления через свойство ControlID.
Для получения результатов запроса будем использовать объект
DataView. В этот объект сохраняем результаты запроса. Нам нужно
всего лишь проверить, пустая ли получилась выборка или нет. Если
выборка не пустая, значит, такой логин уже есть в базе, и пользователь
должен будет придумать себе другое имя.
Наконец, когда пользователь заполнит корректно все данные, мы
будем записывать их в базу данных. Создадим обработчик для кнопки
«Зарегистрировать» и назначим его на событие Click кнопки:
protected void Save_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
SqlDataSource1.InsertCommand = "INSERT INTO readers
(login, password, fio_reader, passport, datebird, addr_reader,
tel_reader, email_reader VALUES (@login, @password,
@fio_reader, @passport, @datebird, @addr_reader, @tel_reader,
@email_reader)";
SqlDataSource1.Insert();
}
}
В этом обработчике мы будем выполнять команду Insert, но
только в том случае, когда текущая страница (Page) является
корректной (IsValid).
33
О.В. Пинягина
Для добавления новой строки у источника данных есть удобные
свойство InsertCommand и метод Insert. Свойство InsertCommand
содержит код выполняемой команды, а метод Insert запускает эту
команду на выполнение.
В выполняемой команде в качестве значений полей используются
так называемые параметры команды insert: @login, @password и т. п.
Их следует предварительно объявить в тексте сценария следующим
образом (или задать в построителе запроса InsertQuery источника
данных):
<asp:SqlDataSource ... >
<InsertParameters>
<asp:ControlParameter ControlID="txtlogin"
Name="login" Type="String" />
<asp:ControlParameter ControlID="txtpassword"
Name="password" Type="String" />
...
</InsertParameters>
</asp:SqlDataSource>
Чтобы получить значения из элементов управления на форме,
каждый из параметров связывается с некоторым элементом
управления через свойство ControlID.
И, наконец, разработаем страницу для авторизации читателей.
Авторизация читателей
Сценарий для авторизации читателей будет несколько отличаться
от
сценария
авторизации
сотрудников.
Создадим
файл
34
Разработка Web-АРМ на ASP.Net
login_reader.aspx, разместим в нем метки, текстовые поля, валидаторы
непустоты и кнопку. Для того чтобы в поле пароля скрывать
набираемые символы, зададим у него свойство textMode= Password.
Ниже поместим метку красного цвета с именем Message, текстом
«Неверные логин/пароль» и установим у нее свойство visible=false.
Добавим на форму источник данных SQLDataSource, назначим
ему, как и раньше, ConnectionString и через построитель запроса
SelectQuery сформулируем запрос
Select * from readers where login=@login AND password=@password
Здесь же в построителе запроса добавим параметры запроса
@login и @password и свяжем их с элементами управления –
текстовыми полями для логина и пароля.
Свяжем с кнопкой следующий обработчик:
protected void Login_Click(object sender, EventArgs e)
{
DataView DataView1;
DataView1 = (DataView)SqlDataSource1.Select
(DataSourceSelectArguments.Empty);
if (DataView1.Count == 0)
{
Message.Visible = true;
}
else
{
Session.Add("reader", txtLogin.Text);
Response.Redirect("default_reader.aspx");
}
}
Так же, как и в сценарии регистрации, проверяем, есть ли в базе
данных пользователь с этим логином (добавляем только условие для
проверки пароля). Если такого пользователя нет, то на экран
показываем сообщение об ошибке.
Если же такой логин в базе имеется, то создаем переменную
сессии с именем этого пользователя и переадресуем его на главную
страницу интерфейса читателя.
Для выхода читателя из авторизованного режима создадим
сценарий logout_reader.aspx с единственным обработчиком, который
удаляет переменную сессии с именем читателя и выполняет
переадресацию на главную страницу сайта:
protected void Page_Load(object sender, EventArgs e)
{
35
О.В. Пинягина
Session.Remove("reader");
Response.Redirect("default.aspx");
}
Задание для самостоятельной работы. Этап 3.
Разработайте для вашего приложения сценарии авторизации
сотрудников, личного кабинета и, если необходимо, регистрации и
авторизации пользователей.
36
Разработка Web-АРМ на ASP.Net
Этап 4. Разработка мастер-страниц
Мастер-страницы, или эталонные страницы, или шаблоны – это
удобное средство для организации общих элементов интерфейса или
программной логики для целой группы страниц. В ASP.NET мастерстраница представляет собой некую общую «оболочку», в которую
будут встраиваться элементы содержимого частных страниц.
Мастер-страница
Текущая страница
Общая часть
Место для элемента1
Элемент1
Место для элемента2
Элемент2
...
...
Место для элементаN
ЭлементN
Мастер-страницы имеют расширение .master, по умолчанию
первая строка сценария имеет вид:
<%@
Master
Language="C#"
AutoEventWireup="true"
CodeFile=
"MasterPage.master.cs" Inherits="librarian_MasterPage" %>
Внутри мастер-страницы должна быть по крайней мере одна
заготовка – место для вставки кода текущей страницы, которое имеет
уникальный идентификатор в рамках страницы:
<asp:contentplaceholder id="ContentPlaceHolder1"
runat="server">
</asp:contentplaceholder>
Каждая конкретная текущая страница, использующая мастерстраницу, при создании по умолчанию имеет вид:
<%@ Page Language="C#"
MasterPageFile="~/librarian/MasterPage.master"
AutoEventWireup="true" CodeFile="Search.aspx.cs"
Inherits="librarian_Search" Title="Поиск и просмотр" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
37
О.В. Пинягина
</asp:Content>
Здесь
является
мастер-страницу:
MasterPageFile="~/librarian/MasterPage.master",
можно задать
заголовок для страницы: Title="Поиск и просмотр", а также должен
присутствовать хотя бы один элемент для вставки в мастер-страницу
<asp:Content
...
обязательной
>
...
ссылка
на
</asp:Content>
у которого значение
совпадает с заданным значением id тэга
<asp:contentplaceholder> в мастер-странице.
Создадим, например, мастер-страницу для АРМ библиотекаря:
ContentPlaceHolderID
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="MasterPage.master.cs" Inherits="librarian_MasterPage"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
38
Разработка Web-АРМ на ASP.Net
<head runat="server">
<title>Библиотека</title>
</head>
<body style="background-image: url(../images/EULA.jpg);
background-repeat: repeat-y; background-attachment: scroll;
margin-left: 140px;">
<form id="form1" runat="server">
<table width="100%" border="0">
<tr><td align="center" colspan="4">
<div style="font-size: 30pt; font-family:
'Bookman Old Style', 'Book Antiqua', 'Comic Sans MS';">
АРМ "Библиотекарь"
</div>
<div style="font-weight:bold; font-size:larger;
color:blue;">
<%=Profile.PersonalInfo.UserFIO%> </div>
</td></tr>
<tr><td style="width:27%; position:static;
text-align: center;">
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="RegReader.aspx" style="font-weight: bold; ">
Новый читатель </asp:HyperLink></td>
<td style="width: 27%; position: static;
text-align: center;">
<asp:HyperLink ID="HyperLink2" runat="server"
NavigateUrl="~/librarian/SearchReader.aspx"
style="font-weight: bold; ">
Поиск читателя
</asp:HyperLink></td>
<td style="width: 26%; position: static;
text-align: center;">
<asp:HyperLink ID="HyperLink3" runat="server"
NavigateUrl="~/librarian/SearchBook.aspx"
style="font-weight: bold; ">
Поиск книги </asp:HyperLink></td>
<td style="width: 20%; position: static;
text-align: center;">
<asp:HyperLink ID="HyperLink4" runat="server"
NavigateUrl="~/logout.aspx" style="font-weight: bold; ">
Выход</asp:HyperLink></td></tr>
<tr><td colspan="4"><div style="text-align: center;">
<asp:contentplaceholder id="ContentPlaceHolder1"
runat="server">
</asp:contentplaceholder>
</div></td></tr>
</table>
<div style="text-align: center;"><asp:HyperLink ID="HyperLink5"
runat="server" NavigateUrl="~/cabinet.aspx">Личные данные
</asp:HyperLink></div>
</form></body></html>
Обратите внимание на строку
<%=Profile.PersonalInfo.UserFIO%>.
39
О.В. Пинягина
Поскольку с АРМ библиотекаря может работать только
авторизованный пользователь, мы для информации выводим на
страницу его ФИО из объекта-профиля.
Страница по умолчанию Default.aspx будет выглядеть
следующим образом:
<%@ Page Language="C#"
MasterPageFile="~/librarian/MasterPage.master"
AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="librarian_Default" Title="АРМ 'Библиотекарь'" %>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<asp:Image ID="Image1" runat="server"
ImageUrl="~/images/pict13_289.jpg" Width="550px" />
</asp:Content>
Задание для самостоятельной работы. Этап 4.
Разработайте для вашего приложения мастер-страницы для всех
АРМ. Измените ранее созданные страницы АРМ так, чтобы они
использовали мастер-страницы.
40
Разработка Web-АРМ на ASP.Net
Этап 5. Разработка сценариев поиска и просмотра
данных
В каждом АРМ так или иначе нужен режим поиска и просмотра
данных в разных разрезах. Рассмотрим подробнее сценарии поиска и
просмотра данных в АРМ библиотекаря.
Поиск и просмотр читателя в АРМ библиотекаря
Создадим сценарий для поиска читателя SearchReader.aspx,
использующий master-страницу для АРМ библиотекаря. Будем искать
читателя по номеру его читательского билета или (если он, например,
потерял свой читательский билет и забыл его номер) по номеру
паспорта.
На странице разместим два текстовых поля (txt_searct_ID и
txt_search_pasp) и две кнопки (searchId и searchPasp).
Для доступа к базе данных, как обычно, создадим источник
данных типа SQLDataSource. В окне Properties назначим источнику
данных в качестве строки соединения ConnectionString ссылку на
нашу базу данных ASPNETDB.mdf. C помощью свойства SelectQuery
в построителе запросов назначим строку запроса
SELECT readers.* FROM readers where id_reader=@id_reader
41
О.В. Пинягина
Создадим параметр запроса @id_reader и свяжем его с текстовым
полем txt_searct_ID.
Поместим на страницу объект DetailesView из группы Data
вкладки Tools. Этот объект удобен для вывода подробной информации
из одной записи таблицы базы данных. Настроить внешний вид этого
объекта можно с помощью многочисленных свойств в окне Properties.
Обязательно нужно назначить свойство DataSourceID, т.е., связать с
источником данных. Для настройки отдельных полей записи
используйте свойство Fields.
Стиль таблицы (цвет, шрифт и т.п.) можно быстро изменить через
контекстное меню (правая кнопка мыши) – Auto Format.
Пункт Edit Templates в контекстном меню позволяет также
редактировать шаблон верхнего и нижнего колонтитулов объекта
(Header Template и Footer Template), а также задать шаблон для
пустой выборки (Empty Data Template) – добавим в этот шаблон
строку «Читатель не найден!».
Получившийся объект в коде программы выглядит следующим
образом:
<asp:DetailsView ID="DetailsView1" runat="server"
AutoGenerateRows="False" CellPadding="4"
DataSourceID="SqlDataSource1" ForeColor="#333333"
GridLines="None" Height="50px" Width="528px">
<FooterStyle BackColor="#5D7B9D" Font-Bold="True"
ForeColor="White" />
<CommandRowStyle BackColor="#E2DED6" Font-Bold="True" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<FieldHeaderStyle BackColor="#E9ECF1" Font-Bold="True"
Width="40%" />
<PagerStyle BackColor="#284775" ForeColor="White"
HorizontalAlign="Center"/>
<Fields>
<asp:BoundField DataField="id_reader"
HeaderText="Номер билета"
InsertVisible="False" SortExpression="id_reader" />
<asp:BoundField DataField="fio_reader" HeaderText="ФИО"
SortExpression="fio_reader" />
<asp:BoundField DataField="passport"
HeaderText="Паспорт" SortExpression="passport" />
<asp:BoundField DataField="datebird"
HeaderText="Дата рождения"
SortExpression="datebird" />
<asp:BoundField DataField="addr_reader"
HeaderText="Адрес" SortExpression="addr_reader" />
<asp:BoundField DataField="tel_reader"
42
Разработка Web-АРМ на ASP.Net
HeaderText="Телефон" SortExpression="tel_reader" />
<asp:BoundField DataField="email_reader"
HeaderText="Еmail" SortExpression="email_reader" />
</Fields>
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True"
ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<EmptyDataTemplate>
Читатель не найден!
</EmptyDataTemplate>
</asp:DetailsView>
Наконец, нужно назначить обработчики на кнопки:
protected void searchPasp_Click(object sender, EventArgs e)
{
SqlDataSource1.SelectParameters.Clear();
SqlDataSource1.SelectParameters.Add("passport",
txt_search_pasp.Text);
SqlDataSource1.SelectCommand =
"SELECT readers.* FROM readers WHERE
passport=@passport";
}
protected void searchID_Click(object sender, EventArgs e)
{
try
{
int id = Int32.Parse(txt_search_ID.Text);
SqlDataSource1.SelectParameters.Clear();
SqlDataSource1.SelectParameters.Add("id_reader",
txt_search_ID.Text);
SqlDataSource1.SelectCommand =
"SELECT readers.* FROM readers WHERE
id_reader=@id_reader";
}
catch(Exception ex)
{
SqlDataSource1.SelectCommand =
"SELECT readers.* FROM readers WHERE 1!=1";
}
}
Как видим, в первом обработчике «Поиск по паспорту» мы
очищаем список параметров, явно задаем значение параметра поиска
@passport и текст команды Select для источника данных – все
остальное будет сделано автоматически.
43
О.В. Пинягина
А при поиске по номеру билета возникает следующая проблема:
номер билета представляет собой
целое число (int), и если
пользователь наберет в поле поиска нечисловые символы, то при
выполнении Select возникнет исключение (к сожалению, это
произойдет за пределами данной функции). Здесь предлагается
следующее решение: мы пытаемся преобразовать значение из
текстового поля к целому типу, и в случае успеха формируем обычный
текст запроса Select. Если же возникло исключение, мы искусственно
создаем такой Select, который содержит ложное условие, и выборка
будет пустой.
Как только библиотекарь нашел какого-то читателя, он начинает
работать с его карточкой. Создадим переменные сессии для имени и
номера читателя. Для этого будем использовать объект Session.
Удобнее всего выполнить это действие в тот момент, когда объект
DetailsView заполняется данными, а именно в обработчике события
DataBound. (Здесь есть еще одна хитрость: скопируем номер
читательского билета в поле txt_search_ID, чтобы при дальнейших
действиях со страницей не потерять связь с источником данных,
44
Разработка Web-АРМ на ASP.Net
которому по умолчанию мы назначили параметр, связанный с этим
текстовым полем.)
protected void DetailsView1_DataBound(object sender,
EventArgs e)
{
try
{
Session.Add("id_reader",
DetailsView1.Rows[0].Cells[1].Text);
Session.Add("fio_reader", "Читатель: "
+DetailsView1.Rows[1].Cells[1].Text);
txt_search_ID.Text=Session["id_reader"].ToString();
}
catch (Exception ex)
{
}
}
Обратите внимание, как извлекаются данные из DetailsView.
Номер билета берем из нулевой строки, первого столбца, ФИО – из
первой строки, первого столбца. Для удобства будем выводить ФИО
найденного читателя сразу же после линейки меню. Для этого в
мастер-страницу поместим строку:
<%=Session["fio_reader"]%>
Далее добавим в карточку читателя информацию о его заявках на
книги, о взятых и возвращенных книгах.
Прежде всего, для удобства выборки информации из разных
таблиц создадим три представления непосредственно в базе данных.
Представление vw_orders содержит информацию о еще не
выполненных заявках (дата выдачи пустая). Выборка отсортирована в
порядке убывания даты заявки.
SELECT dbo.books.ISBN, dbo.books.name_book, dbo.items.id_item,
dbo.orders.date_order, dbo.books.author,
dbo.orders.id_reader, dbo.items.status,
dbo.orders.id_order
FROM dbo.orders INNER JOIN dbo.items
ON dbo.orders.id_item = dbo.items.id_item
INNER JOIN dbo.books
ON dbo.items.ISBN = dbo.books.ISBN
WHERE (dbo.orders.date_get IS NULL)
ORDER BY dbo.orders.date_order DESC
45
О.В. Пинягина
Представление vw_given содержит информацию о книгах,
которые находятся на руках у читателей: (дата выдачи непустая, дата
возврата пустая). Выборка отсортирована в порядке убывания даты
выдачи.
SELECT dbo.items.id_item, dbo.orders.id_reader,
dbo.books.name_book, dbo.books.author,
dbo.orders.date_get, dbo.books.ISBN, dbo.orders.id_order
FROM dbo.items INNER JOIN dbo.orders
ON dbo.items.id_item = dbo.orders.id_item
INNER JOIN dbo.books
ON dbo.items.ISBN = dbo.books.ISBN
WHERE (dbo.orders.date_return IS NULL)
AND (dbo.orders.date_get IS NOT NULL)
ORDER BY dbo.orders.date_get DESC
Представление vw_returned содержит информацию о книгах,
которые возвращены читателями: (дата возврата непустая). Выборка
отсортирована в порядке убывания даты выдачи.
SELECT dbo.books.ISBN, dbo.books.name_book, dbo.books.author,
dbo.items.id_item, dbo.orders.date_get,
dbo.orders.date_return, dbo.orders.id_reader,
dbo.orders.id_order
FROM dbo.books INNER JOIN dbo.items
ON dbo.books.ISBN = dbo.items.ISBN
INNER JOIN dbo.orders
ON dbo.items.id_item = dbo.orders.id_item
WHERE (dbo.orders.date_return IS NOT NULL)
ORDER BY dbo.orders.date_get DESC
На основе каждого из представлений создадим источник данных
SQLDataSource. Нас интересуют книги конкретного читателя,
поэтому в источнике данных при построении запроса в свойстве
SelectQuery зададим параметр id_reader, который свяжем с элементом
управления DetailsView1 и добавим соответствующее условие в
запрос:
46
Разработка Web-АРМ на ASP.Net
SELECT vw_given.* FROM vw_given WHERE (id_reader=@id_reader)
Кроме того, у элемента управления DetailsView1 нужно явно
указать ключевые поля из источника данных: назначим свойство
DataKeyNames=id_reader.
Теперь можно выводить информацию из источников данных на
страницу. Для этого будем использовать элементы управления типа
GridView, которые представляют данные в табличной форме. У этих
элементов обязательно нужно назначить источник данных: свойство
DataSourceID
связать с соответствующим объектом типа
SQLDataSource.
Для настройки отдельных столбцов таблицы используйте свойство
Columns
и соответствующий построитель. Здесь в визуальном
режиме можно настроить список столбцов, задать их порядок,
заголовки и прочие свойства.
Стиль таблицы (цвет, шрифт и т.п.) можно быстро изменить через
контекстное меню (правая кнопка мыши) – Auto Format.
Наконец, для более компактного размещения информации будем
выводить на экран только один из объектов GridView. Для этого у
всех объектов GridView назначим по умолчанию свойство
47
О.В. Пинягина
Visible=false. Затем в нижнем колонтитуле объекта DetailsView1 (в
шаблоне Footer Template) поместим три кнопки: «Заявки», «Книги
выданные», «Книги возвращенные». Обработчик соответствующей
кнопки делает видимым одну из таблиц и делает невидимыми две
остальные:
protected void Button1_Click(object sender, EventArgs e)
{
GridView1.Visible = true;
GridView2.Visible = false;
GridView3.Visible = false;
}
Поиск и просмотр книг в АРМ библиотекаря
Создадим сценарий для поиска книг (SearchBook.aspx),
использующий master-страницу для АРМ библиотекаря. Книги будем
искать по номеру, ISBN, названию (или части названия), автору. На
странице разместим текстовые поля для поиска (пусть их названия
совпадают с названиями соответствующих столбцов в базе данных).
Поскольку нам нужно выбирать информацию сразу из нескольких
таблиц, создадим, как обычно, представление в базе данных. Назовем
его vw_books. Это представление состоит из 5 таблиц и визуально
выглядит следующим образом:
А его код представлен следующим запросом:
SELECT dbo.books.ISBN, dbo.books.name_book, dbo.books.author,
dbo.books.price, dbo.books.pages, dbo.books.year,
48
Разработка Web-АРМ на ASP.Net
dbo.books.type, dbo.books.image, dbo.categories.name_cat,
dbo.publishers.name_publ, dbo.items.id_item,
dbo.items.state, dbo.status.name_status, dbo.items.status
FROM dbo.books INNER JOIN dbo.items
ON dbo.books.ISBN = dbo.items.ISBN
INNER JOIN dbo.categories
ON dbo.books.id_cat = dbo.categories.id_cat
INNER JOIN dbo.publishers
ON dbo.books.id_publ = dbo.publishers.id_publ
INNER JOIN dbo.status
ON dbo.items.status = dbo.status.id_status
Для доступа к базе данных, как обычно, создадим источник
данных типа SQLDataSource. В окне Properties назначим источнику
данных в качестве строки соединения ConnectionString ссылку на
нашу базу данных ASPNETDB.mdf. C помощью свойства SelectQuery
в построителе запросов назначим строку запроса c ложным условием,
чтобы по умолчанию выборка была пустая, пока пользователь не задал
критерии поиска:
SELECT vw_books.* FROM vw_books WHERE 1!=1
После того как пользователь задаст критерии поиска, ему следует
нажать на кнопку «Найти». Серверный обработчик этой кнопки
выглядит следующим образом:
protected void Button1_Click(object sender, EventArgs e)
{
bool nodata = true;
SqlDataSource1.SelectCommand = "SELECT * FROM vw_books ";
SqlDataSource1.SelectParameters.Clear();
if (id_item.Text != "")
{
SqlDataSource1.SelectParameters.Add("id_item",
id_item.Text);
SqlDataSource1.SelectCommand +=
" WHERE id_item=@id_item ";
nodata = false;
}
if (ISBN.Text != "")
{
SqlDataSource1.SelectCommand +=
nodata ? " WHERE " : " AND ";
SqlDataSource1.SelectParameters.Add("ISBN", ISBN.Text);
SqlDataSource1.SelectCommand += " ISBN=@ISBN ";
49
О.В. Пинягина
nodata = false;
}
if (author.Text != "")
{
SqlDataSource1.SelectCommand +=
nodata ? " WHERE " : " AND ";
SqlDataSource1.SelectParameters.Add
("author", author.Text);
SqlDataSource1.SelectCommand += " author=@author ";
nodata = false;
}
if (name_book.Text != "")
{
SqlDataSource1.SelectCommand +=
nodata ? " WHERE " : " AND ";
SqlDataSource1.SelectParameters.Add("name_book",
name_book.Text);
SqlDataSource1.SelectCommand +=
" name_book LIKE '%'+@name_book+'%'";
nodata = false;
}
if (nodata)
{
SqlDataSource1.SelectCommand =
"SELECT * FROM vw_books WHERE 1!=1";
}
}
Рассмотрим код этого обработчика более подробно. В этом
обработчике мы явно создаем параметры запроса и добавляем их в
коллекцию параметров SelectParameters источника данных.
Обратите внимание, как формируется условие запроса. Дело в
том, что оно должно начинаться с ключевого слова WHERE, а если
условие составное, то отдельные его части в нашем случае должны
быть связаны ключевым словом AND (одновременное выполнение
нескольких условий). Для краткости используем тернарный
(условный) оператор; вспомним, что он имеет следующий синтаксис:
условие ? значение_если_истина : значение_если_ложь
Обратите также внимание на то, как формируется условие поиска
по подстроке в названии книги. Здесь мы используем ключевое слово
LIKE, а сама подстрока поиска в запросе должна обрамляться слева и
справа знаками ‘%’.
Если ни один из критериев поиска не задан, снова формируем
запрос с ложным условием:
50
Разработка Web-АРМ на ASP.Net
"SELECT * FROM vw_books WHERE 1!=1"
Теперь можно вывести результаты запроса на экран. Будем
использовать элемент управления GridView.
Элементу GridView обязательно нужно назначить источник
данных: свойство DataSourceID связать с соответствующим объектом
типа SQLDataSource.
Как и в предыдущем параграфе, для настройки отдельных
столбцов таблицы используйте свойство Columns и соответствующий
построитель. Здесь в визуальном режиме можно настроить список
столбцов, задать их порядок, заголовки и прочие свойства.
Зададим в объекте GridView несколько новых для нас свойств.
Щелкните по объекту правой кнопкой мыши и в контекстном меню
выберите строку Show smart tag. Здесь отметим флажки Enable
paging и Enable selection.
Включение режима Enable paging приводит к автоматическому
разбиению нашей таблицы на страницы (по умолчанию на странице
помещается 10 строк).
Включение режима Enable selection приводит к появлению в
таблице нового столбца с гиперссылками Select. Изменим в
построителе свойство этого столбца SelectText на Подробнее... Кроме
51
О.В. Пинягина
того, у элемента управления GridView нужно явно указать ключевые
поля
из
источника
данных:
назначим
свойство
DataKeyNames=id_item.
Теперь для того чтобы выводить подробную информацию о книге,
создадим еще один источник данных SQLDataSource, назначим ему
запрос
SELECT ISBN, name_book, author, price, pages, year, type,
name_cat, name_publ, id_item, state, name_status, status
FROM vw_books WHERE (id_item = @id_item)
и обязательно создадим параметр запроса @id_item, связанный с
объектом GridView. Для вывода на экран подробной информации из
текущей строки создадим объект DetailsView, связанный с этим
источником данных. Теперь при щелчке по гиперссылке Подробнее…
текущая строка таблицы будет выделяться другим стилем (в нашем
случае более темно-серым) и в объект DetailsView будет выводиться
подробная информация о книге.
52
Разработка Web-АРМ на ASP.Net
Таким образом, в последних двух параграфах мы рассмотрели
совместное использование взаимосвязанных объектов GridView и
DetailsView, как в прямом, так и в обратном направлении.
Задание для самостоятельной работы. Этап 5.
Разработайте для вашего приложения страницы поиска и
просмотра данных для всех АРМ. В дальнейшем в эти же страницы
могут быть добавлены средства для изменения данных.
53
О.В. Пинягина
Этап 6. Разработка сценариев добавления,
редактирования и удаления данных
Начинаем разрабатывать рабочее место для сотрудника отдела
комплектования. Главная страница будет выглядеть следующим образом
(вспомним, что повторяющиеся элементы интерфейса можно поместить в
мастер-страницу):
Управление издателями и категориями
Начнем с пунктов «Издатели» и «Категории». В базе данных
структура этих объектов простая – они содержат только номер и
название. Поэтому рассмотрим подробнее только сценарий для
редактирования издателей.
Создадим
сценарий
Publishers.aspx.
Добавим
объект
SQLDataSource, сразу же щелкнем по гиперссылке Configure Data
Source и займемся настройкой источника данных.
54
Разработка Web-АРМ на ASP.Net
На
первой
странице
выберем
строку
подключения
ConnectionString.
На второй странице построим запрос SELECT * FROM
[publishers] и не забудем нажать на кнопку Advanced. Появится окно,
в котором обязательно надо выбрать режим «Generate Insert, Update
and Delete statements» для того, чтобы SQL-команды были
сгенерированы автоматически.
На третьей странице можно протестировать полученный запрос на
выборку и нажать кнопку Finish. Источник данных подготовлен.
Теперь подумаем о визуальном представлении издателей. На
форму поместим объект GridView. Назначим ему только что
созданный источник данных.
Займемся настройкой столбцов GridView. Выберем в контекстном
меню Show smart tag – EditColumns. Если никакие столбцы не
выбраны, можно щелкнуть по гиперссылке Refresh Schema, затем
выбрать столбцы id_publ и name_publ, а, кроме того, в секции
CommandField выбрать элементы «Edit, Update, Cancel» и «Delete».
В таблице появятся два дополнительных столбца с гиперссылками для
редактирования и удаления строк. По умолчанию появляются именно
55
О.В. Пинягина
гиперссылки, но можно поменять их тип ButtonType на значение
Button (кнопка). Изменим всевозможные надписи на русские.
Так выглядит интерфейс для редактирования строки (он создается
автоматически):
Столбец «Delete» мы преобразуем в шаблон с помощью
гиперссылки «Convert this field into a Template Field». После этого
для кнопки «Удалить» можно будет назначить клиентский
обработчик: свойству OnClientClick нужно присвоить значение
return confirm('Вы уверены?');
для того чтобы в браузере на клиентской стороне при нажатии на эту
кнопку появлялось окно предупреждения:
56
Разработка Web-АРМ на ASP.Net
Наконец, разместим на странице текстовое поле и кнопку
«Добавить» для создания новых издателей. Подправим свойство
InsertQuery в SQLDataSource1, чтобы параметр запроса был связан с
этим текстовым полем и назначим на кнопку обработчик для
обновления GridView1:
protected void Button2_Click(object sender, EventArgs e)
{
SqlDataSource1.Insert();
GridView1.DataBind();
}
Интерфейс для управления издателями готов. Таким же образом
создадим сценарий Categories.aspx для редактирования категорий
книг:
Регистрация новых книг
Теперь создадим сценарий NewBook.aspx для регистрации новых
книг:
Как обычно, прежде всего, поместим на форму источники данных
(здесь нам нужно три источника).
SQLDataSource1 предназначен для добавления книги в таблицу
базы данных, поэтому щелкнем по гиперссылке Configure Data Source
и займемся настройкой. На второй странице настройки построим
запрос SELECT * FROM [books] и не забудем нажать на кнопку
57
О.В. Пинягина
Advanced. Появится окно, в котором обязательно надо выбрать режим
«Generate Insert, Update and Delete statements» для того, чтобы SQLкоманды были сгенерированы автоматически.
Источники данных SQLDataSource2 и SQLDataSource3
предназначены только для формирования списков издателей и
категорий, зададим для них запросы
SELECT * FROM [publishers] и SELECT * FROM [categories]
Теперь поместим на форму элемент управления FormView из
группы Data. Зададим для него параметр DefaultMode=Insert (т.е., по
умолчанию будет показана форма для добавления записи).
Для редактирования полей формы следует выбрать в контекстном
меню Edit Template – InsertItemTemplate.
Для полей «Тип», «Категория» и «Издательство» нам понадобятся
списки. Поэтому удалим сгенерированные автоматически на их месте
текстовые поля и добавим элементы управления DropDownList из
секции Standard.
Список для указания типа книги формируется из фиксированных
значений (1–учебная, 0–прочая). Поэтому следует выбрать свойство
Item списка и добавить два элемента со свойствами: Text=учебная,
Value=1; Text=прочая, Value=0.
58
Разработка Web-АРМ на ASP.Net
Списки издательств и категорий должны заполняться значениями
из базы данных, поэтому у этих списков нужно настроить источник
данных (например, DataSourceID=SQLDataSource2), имя столбца для
строк списка (например, DataTextField=name_publ) и имя столбца для
значений списка (например, DataValueField=id_publ).
Осталось связать все три полученных списка со столбцами
таблицы books. Для этого непосредственно в тексте сценария нужно
найти тег, формирующий список
<asp:DropDownList ...> </asp:DropDownList>
и задать в нем атрибут
SelectedValue = '<%# Bind("id_publ")%>'>
То же самое можно получить, если в контекстном меню для
списка найти строку «Edit Data Binding», выбрать режим «Custom
Binding» и в поле «Code Expression» указать Bind("id_publ").
Для автоматической проверки, корректно ли введены данные,
можно задать валидаторы, как мы это делали при регистрации
читателя. Для всех полей нужна проверка непустоты, а для числовых
полей – дополнительная проверка корректности введенных значений,
как мы это делали при поиске читателя по номеру билета.
Поиск книг и создание экземпляров
Рассмотрим довольно сложный сценарий, который включает
возможности поиска и редактирования книг, а также просмотра и
создания экземпляров. Сценарий поиска книг частично будет похож
на тот, который мы разрабатывали для библиотекаря. Заметим, что для
сотрудника отдела комплектования существует разница между
понятиями «Книга» и «Экземпляр».
В базе данных создадим представление vw_books2 с полной
информацией о книгах (без информации об экземплярах), которая
выбирается из таблиц books, categories и publishers:
SELECT
dbo.books.ISBN, dbo.books.name_book,
dbo.books.author, dbo.books.price, dbo.books.pages,
dbo.books.year, dbo.books.type, dbo.books.id_cat,
dbo.books.id_publ, dbo.categories.name_cat,
dbo.publishers.name_publ
FROM dbo.books INNER JOIN dbo.categories ON
59
О.В. Пинягина
dbo.books.id_cat = dbo.categories.id_cat INNER JOIN
dbo.publishers ON dbo.books.id_publ = dbo.publishers.id_publ
Как и в сценарии для библиотекаря, поместим на форму текстовые
поля для поиска по ISBN, названию и автору. Создадим источник
данных SQLDataSource, назначим ему в построителе SelectQuery
запрос по умолчанию:
SELECT vw_books2.* FROM vw_books2 WHERE ISBN=@isbn
и свяжем параметр @isbn с текстовым полем для поиска по ISBN.
В построителе DeleteQuery назначим запрос
DELETE FROM books WHERE ISBN=@isbn
Обратите внимание, что последний запрос будет удалять строки
непосредственно из таблицы books, поскольку через представление,
состоящее из нескольких таблиц, удаление сделать нельзя.
Обработчик кнопки «Найти» почти без изменений возьмем из
сценария поиска книги для библиотекаря.
Для вывода информации о найденных книгах поместим на
страницу объект GridView и свяжем его с источником данных.
Назначим свойство DataKeyNames =ISBN.
60
Разработка Web-АРМ на ASP.Net
Займемся настройкой столбцов GridView. Выберем в контекстном
меню Show smart tag – EditColumns. Если никакие столбцы не
выбраны, можно щелкнуть по гиперссылке Refresh Schema, затем
выбрать нужные, а, кроме того, в секции CommandField выбрать
элементы «Select», «Edit, Update, Cancel» и «Delete». В таблице
появятся три дополнительных столбца с гиперссылками. Переименуем
их в «Экземпляры», «Редактировать» и «Удалить» и преобразуем в
шаблоны с помощью гиперссылки «Convert this field into a Template
Field». После этого они появятся в списке шаблонов как отдельные
элементы.
Для гиперссылки «Удалить» можно будет назначить клиентский
обработчик: свойству OnClientClick нужно присвоить значение
return confirm('Вы уверены?');
Для редактирования книги создадим новый источник данных
SQLDataSource2 и настроим его напрямую на таблицу books:
щелкнем по гиперссылке Configure Data Source
и займемся
настройкой источника данных.
На
первой
странице
выберем
строку
подключения
ConnectionString.
На второй странице построим запрос SELECT * FROM [books] и
не забудем нажать на кнопку Advanced. Появится окно, в котором
обязательно надо выбрать режим «Generate Insert, Update and Delete
statements» для того, чтобы SQL-команды были сгенерированы
автоматически.
На третьей странице можно протестировать полученный запрос на
выборку и нажать кнопку Finish. Источник данных подготовлен.
Далее поместим на форму объект FormView. (Для редактирования
книги нам нужен только шаблон EditItemTemplate, поэтому все
остальные шаблоны можно просто вручную удалить из кода
страницы.) По умолчанию назначим свойства Visible=false,
DataKeyNames=ISBN.
Как и в сценарии добавления книги, для полей «Тип»,
«Категория» и «Издательство» нам понадобятся списки. Поэтому
удалим сгенерированные автоматически на их месте текстовые поля и
добавим элементы управления DropDownList из секции Standard.
Список для указания типа книги формируется из фиксированных
значений (1–учебная, 0–прочая). Поэтому следует выбрать свойство
61
О.В. Пинягина
Item списка и добавить два элемента со свойствами: Text=учебная,
Value=1; Text=прочая, Value=0.
Списки издательств и категорий должны заполняться значениями
из базы данных, поэтому у этих списков нужно настроить источник
данных (например, DataSourceID=SQLDataSource4), имя столбца для
строк списка (например, DataTextField=name_publ) и имя столбца для
значений списка (например, DataValueField=id_publ).
Осталось связать все три полученных списка со столбцами
таблицы books. Это можно сделать непосредственно в тексте
сценария, а можно в контекстном меню для списка найти строку «Edit
Data Binding», выбрать режим «Custom Binding» и в поле «Code
Expression» указать Bind("id_publ").
62
Разработка Web-АРМ на ASP.Net
Объект FormView1 должен появляться на экране при щелчке на
гиперссылке «Редактировать» в GridView1. Поэтому назначим на эту
гиперссылку обработчик:
protected void LinkButton3_Click(object sender, EventArgs e)
{
FormView1.Visible = true;
}
Внутри объекта FormView1 есть гиперссылки «Update» и
«Cancel». Переименуем их в «Обновить» и «Скрыть» и назначим
обработчики:
protected void UpdateButton_Click(object sender, EventArgs e)
{
FormView1.Visible = false;
}
protected void UpdateCancelButton_Click(object sender,
EventArgs e)
{
FormView1.Visible = false;
}
Для того чтобы сделанные изменения отображались в GridView1,
назначим следующий обработчик на событие Updated объектаисточника данных для FormView1 (здесь мы явно вызываем метод
Button1_Click, поскольку именно в нем динамически формируется
строка запроса SelectCommand объекта SqlDataSource1):
protected void SqlDataSource3_Updated(object sender,
SqlDataSourceStatusEventArgs e)
{
Button1_Click(sender, e);
SqlDataSource1.Select(DataSourceSelectArguments.Empty);
GridView1.DataBind();
}
Далее для просмотра экземпляров книги в базе данных создадим
представление vw_items
SELECT dbo.state.name_state, dbo.items.id_item,
dbo.items.ISBN, dbo.status.name_status,
dbo.items.state, dbo.items.status
FROM dbo.items INNER JOIN dbo.state
ON dbo.items.state = dbo.state.id_state
INNER JOIN dbo.status
63
О.В. Пинягина
ON dbo.items.status = dbo.status.id_status
Поместим на форму новый источник данных с SELECT-запросом
SELECT * FROM [vw_items] WHERE ([ISBN] = @ISBN)
и свяжем параметр запроса @ISBN с объектом GridView1.
На основе этого источника данных создадим GridView2 и
настроим, как обычно, его внешний вид. И, наконец, разместим на
странице объект FormView2 для создания новых экземпляров (его
настройка напоминает сценарий создания новых книг).
Для гиперссылки «Экземпляры» в GridView1 зададим
обработчик, который делает видимыми список экземпляров и форму
для добавления нового экземпляра:
protected void LinkButton1_Click(object sender, EventArgs e)
{
GridView2.Visible = true;
64
Разработка Web-АРМ на ASP.Net
FormView2.Visible = true;
}
У нас получился довольно сложный интерфейс для поиска и
редактирования книг, просмотра и создания экземпляров.
Подумайте, как можно реализовать следующий сценарий, который
позволяет выполнять поиск и редактирование экземпляров книг:
Выдача и прием книг
Рассмотрим еще один интересный пример обработки данных.
Вернемся в АРМ библиотекаря, к сценарию поиска и просмотра
данных читателя. В этом сценарии у нас есть список заявок текущего
читателя на книги (объект GridView1). Добавим в него столбец
«Select» и переименуем его в «Выдать».
Выдача книги с точки зрения данных приводит к следующим
изменениям:
1.
Статус книги меняется на значение «на руках» (код=2).
2.
У заявки заполняется дата выдачи (сегодняшним днем).
3.
В заявке указывается библиотекарь, выдавший книгу.
Эти действия удобно оформить в виде хранимой процедуры,
которая в качестве параметров получает номер заявки, номер
экземпляра книги и логин библиотекаря:
CREATE PROCEDURE dbo.Give_book
@id_order INT, @id_item INT, @login_give NCHAR(10)
65
О.В. Пинягина
AS
BEGIN
BEGIN TRANSACTION
UPDATE items SET status=2 WHERE id_item=@id_item
UPDATE orders SET date_get=GETDATE(), login_give=@login_give
WHERE id_order=@id_order
COMMIT TRANSACTION
END
RETURN
Теперь назначим обработчик события SelectedIndexChanged
объекта GridView1. В этом обработчике мы явно используем типы
данных SQLConnection и SQLCommand, поэтому в начале файла
следует подключить библиотеку: using System.Data.SqlClient;
protected void Give_Click1(object sender, EventArgs e)
{
Создаем объекты для запуска хранимой процедуры:
SqlConnection conn = new
SqlConnection(SqlDataSource1.ConnectionString);
conn.Open();
SqlCommand cmd = new SqlCommand("Give_book", conn);
cmd.CommandType = CommandType.StoredProcedure;
В хранимую процедуру нужно передать параметры – номера
заявки и экземпляра книги, а также логин библиотекаря. Первые два
значения мы «вытаскиваем» из текущей строки GridView1 – это
столбцы нулевой и пятый. Логин получаем из информации об
авторизованном пользователе.
66
Разработка Web-АРМ на ASP.Net
string id_item = GridView1.SelectedRow.Cells[0].Text;
string id_order = GridView1.SelectedRow.Cells[5].Text;
string login_take =
HttpContext.Current.User.Identity.Name;
cmd.Parameters.AddWithValue("@id_item", id_item);
cmd.Parameters.AddWithValue("@id_order", id_order);
cmd.Parameters.AddWithValue("@login_give", login_give);
cmd.ExecuteNonQuery();
conn.Close();
После выполнения процедуры обновляем список заявок и список
выданных книг.
SqlDataSource2.Select(DataSourceSelectArguments.Empty);
GridView1.DataBind();
SqlDataSource3.Select(DataSourceSelectArguments.Empty);
GridView2.DataBind();
}
Подобным же образом можно оформить и прием книг от читателя:
Задание для самостоятельной работы. Этап 6.
Добавьте в ваше приложение возможности редактирования,
удаления и добавления данных для всех АРМ. Можете создавать
новые страницы или же добавлять новые возможности к сценариям,
разработанным ранее. Постарайтесь использовать разные типы
визуальных объектов (GridView, DetailsVies, FormView).
67
О.В. Пинягина
Этап 7. Выгрузка и загрузка данных в формате XML
XML является исключительно удобной и гибкой технологией для
обмена данными между приложениями. В ASP.NET есть много
разнообразных объектов для работы с XML-данными. В нашем
проекте мы рассмотрим только два простых примера.
Загрузка данных из XML-файла в базу данных
Пусть в отдел комплектования вместе с новыми книгами
присылают XML-документ следующего вида:
- <books>
<book ISBN="5-8959-1091-9111" name_book="Microsoft ASP.NET 2.0 с
примерами на C# 2005 для профессионалов" author="М. Мак-Дональд, М.
Шпушта" price="500" pages="1408" year="2007" />
<book ISBN="3-91180-009-3111" name_book="Гибкая разработка вебприложений в среде Rails" author="Д. Томас, Д. Х. Хэнссон" price="400"
pages="700" year="2008" />
...
</books>
Разумеется, автоматически переписать эту информацию в таблицу
books гораздо удобнее, чем вручную заполнять формы для новых
книг.
Создадим сценарий, который автоматически загружает данные из
этого документа в таблицу books. Добавим на страницу источник
68
Разработка Web-АРМ на ASP.Net
данных SQLDataSource, единственная цель которого – выполнять
команду INSERT:
INSERT INTO [books]
([ISBN], [name_book], [author], [price], [pages], [year])
VALUES (@ISBN, @name_book, @author, @price, @pages, @year)
Поместим на страницу элемент управления FileUpload из секции
Standard, кнопку «Загрузить» и метку с именем Message.
Подключим необходимую библиотеку для работы с XMLклассами:
using System.Xml;
Создадим обработчик для кнопки «Загрузить»:
protected void Button1_Click(object sender, EventArgs e)
{
Если файл был загружен:
if (this.FileUpload1.HasFile)
{
try
{
задаем путь к файлу на диске и сохраняем его.
string Name="c:\\upload\\" + FileUpload1.FileName;
FileUpload1.SaveAs(Name);
На экран будет выдано сообщение: имя и размер загруженного
файла:
Message.Text = "Имя файла: " +
FileUpload1.PostedFile.FileName + "<br>" +
FileUpload1.PostedFile.ContentLength + " кб<br>";
Создаем объект для последовательного чтения из XML-файла
(модель SAX) и читаем его в цикле:
XmlTextReader XMLData = new XmlTextReader(Name);
while (XMLData.Read())
Если текущий элемент – узел <book>
if (XMLData.NodeType == XmlNodeType.Element)
if (XMLData.Name == "book")
69
О.В. Пинягина
{
читаем его атрибуты:
string
string
string
string
string
string
ISBN = XMLData.GetAttribute("ISBN");
name_book = XMLData.GetAttribute("name_book");
author = XMLData.GetAttribute("author");
pages = XMLData.GetAttribute("pages");
price = XMLData.GetAttribute("price");
year = XMLData.GetAttribute("year");
и записываем их в параметры запроса INSERT, затем выполняем
запрос:
SqlDataSource1.InsertParameters["ISBN"].DefaultValue = ISBN;
SqlDataSource1.InsertParameters["name_book"].DefaultValue =
name_book;
SqlDataSource1.InsertParameters["author"].DefaultValue =
author;
SqlDataSource1.InsertParameters["pages"].DefaultValue = pages;
SqlDataSource1.InsertParameters["price"].DefaultValue = price;
SqlDataSource1.InsertParameters["year"].DefaultValue = year;
SqlDataSource1.Insert();
}
}
Предусмотрим вывод ошибки для тех случаев, когда возникает
исключение:
catch (Exception ex)
{
Message.Text = "Ошибка: " + ex.Message.ToString();
}
}
}
Вообще говоря, в данном сценарии в базу загружается только
информация о книгах, но не об экземплярах книг. Подумайте, как
изменить XML-файл и сценарий загрузки, добавив информацию об
экземплярах книг.
Выгрузка данных в XML-файл
Предположим, мы хотим выгрузить данные о читателе и его
книгах в XML-файл следующего вида:
<?xml version="1.0" encoding="utf-8" ?>
70
Разработка Web-АРМ на ASP.Net
- <formular>
<reader id_reader="18" fio_reader="Петров Петр Петрович"
passport="1213 456789" addr_reader="Казань, Ленина, 20-2"
tel_reader="123-123-123" email_reader="petrov@petrov.ru"
datebird="11.11.1950 0:00:00" />
<book ISBN="5-8959-1091-9" id_item="1"
date_get="21.11.2010 18:12:58" />
<book ISBN="978-5-91180-009-3" id_item="6"
date_get="28.11.2010 18:26:08" />
...
</formular>
На странице личной карточки читателя создадим новую кнопку с
надписью «Формуляр в формате XML» и зададим для нее
обработчик:
protected void Button5_Click(object sender, EventArgs e)
{
Читаем данные из карточки читателя (объект DetailsView1):
string
string
string
string
string
id_reader = DetailsView1.Rows[0].Cells[1].Text;
fio_reader = DetailsView1.Rows[1].Cells[1].Text;
passport = DetailsView1.Rows[2].Cells[1].Text;
datebird = DetailsView1.Rows[3].Cells[1].Text;
addr_reader =
DetailsView1.Rows[4].Cells[1].Text;
string tel_reader = DetailsView1.Rows[5].Cells[1].Text;
string email_reader =
DetailsView1.Rows[6].Cells[1].Text;
Создаем объект для записи XML-файла, имя файла – это номер
читательского билета:
71
О.В. Пинягина
XmlTextWriter XMLData = new
XmlTextWriter("C:\\upload\\"+id_reader +
".xml", System.Text.Encoding.UTF8);
Записываем информацию о читателе:
XMLData.WriteStartDocument();
XMLData.WriteStartElement("formular");
XMLData.WriteStartElement("reader");
XMLData.WriteAttributeString("id_reader", id_reader);
XMLData.WriteAttributeString("fio_reader", fio_reader);
XMLData.WriteAttributeString("passport", passport);
XMLData.WriteAttributeString("addr_reader",
addr_reader);
XMLData.WriteAttributeString("tel_reader", tel_reader);
XMLData.WriteAttributeString("email_reader",
email_reader);
XMLData.WriteAttributeString("datebird", datebird);
XMLData.WriteEndElement();
Создаем выборку для книг на руках у читателя:
DataView GivenBooks = new DataView();
GivenBooks =
(DataView)SqlDataSource3.Select(DataSourceSelectArguments.Empty
);
Перебираем строки выборки и записываем информацию о книгах
в XML-документ:
int i=0;
for (i=0; i < GivenBooks.Count; i++)
{
XMLData.WriteStartElement("book");
XMLData.WriteAttributeString("ISBN",
Convert.ToString(GivenBooks[i]["ISBN"]));
XMLData.WriteAttributeString("id_item",
Convert.ToString(GivenBooks[i]["id_item"]));
XMLData.WriteAttributeString("date_get",
Convert.ToString(GivenBooks[i]["date_get"]));
XMLData.WriteEndElement();
}
Закрываем тэги и файл:
XMLData.WriteEndElement();
XMLData.WriteEndDocument();
XMLData.Close();
}
72
Разработка Web-АРМ на ASP.Net
Задание для самостоятельной работы. Этап 7.
Разработайте для вашего приложения сценарии загрузки и
выгрузки данных в XML-формат.
73
О.В. Пинягина
Приложение 1. Вопросы и ответы
Вопрос. В SQL server 2005 при выполнении сценария,
содержащего FormView, выдается ошибка: The version of SQL Server in
use does not support datatype 'date'. Почему?
Если в таблице имеется тип данных DateTime, построитель
FormView ошибочно указывает в параметрах запросов вместо него
тип Date. Нужно вручную исправить в сценарии Date на DateTime.
Вопрос. Как в тексте C#-программы обратиться к элементу
управления aspx-страницы?
Для этого удобно использовать метод FindControl. Например, в
контейнере FormView1 (в любом его шаблоне) находится текстовое
поле с именем ISBNTextBox. Получить из него значение можно
следующим образом (не забывайте явно выполнить преобразование
типа!):
((TextBox)FormView1.FindControl("ISBNTextBox")).Text
Вопрос. Что делать, если при подключении провайдера в ASP.Net
Configuration выдается ошибка?
Следует:
1) запустить утилиту
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\
aspnet_regsql.exe
2) на третьей странице мастера назначить точное имя сервера
(например, HOME\SQLEXPRESS), после этого база данных будет
создана автоматически;
3) затем в свойствах проекта в папке App_data выбрать пункт
Add existing item, найти файл базы данных (примерный путь к нему
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\
ASPNETDB.MDF) и подключить его к проекту. Файл будет
скопирован в папку App_data.
74
Разработка Web-АРМ на ASP.Net
Вопрос. Что делать, если при запуске ASPX-страницы не удается
подключиться к SQL серверу и выдается ошибка:
Generating user instances in SQL Server is disabled. Use sp_configure
'user instances enabled' to generate user instances.
Следует выполнить в среде SQL server management studio
следующие команды:
sp_configure 'user instances enabled', 1
RECONFIGURE
Вопрос. Как из текущей страницы обратиться к элементу мастерстраницы?
Пусть, например, в мастер-странице есть метка для вывода
сообщения. По умолчанию она скрыта (Visible="false").
<asp:Label ID="MessageBox" runat="server" Text="" Width="100%"
Visible="false">
Из текущей страницы нам нужно иметь возможность изменить
видимость этой метки, текст и цвет фона. Для этого в файле
masterpage.master.cs зададим следующие свойства:
public string MessageBoxText
{
get { return MessageBox.Text; }
set { MessageBox.Text = value; }
}
public System.Drawing.Color MessageBoxColor
{
get { return MessageBox.BackColor; }
set { MessageBox.BackColor = value; }
}
public bool MessageBoxVisible
{
get { return MessageBox.Visible; }
set { MessageBox.Visible = value; }
}
Теперь при необходимости (например, в обработчике Page_Load
текущей страницы) можно обращаться к этим свойствам:
((ASP.masterpage_master)Master).MessageBoxVisible = true;
((ASP.masterpage_master)Master).MessageBoxText =
"Вы не авторизованы!";
75
О.В. Пинягина
((ASP.masterpage_master)Master).MessageBoxColor =
System.Drawing.Color.Red;
Вопрос. Как в таблицу GridView вывести картинку, имя которой
хранится в текущей строке источника данных?
Например, в список книг будем выводить их обложки. Вспомним,
что в таблице books есть столбец image varchar(50) (используйте
именно тип varchar, чтобы избежать концевых пробелов). Пусть в этом
столбце хранится точный путь к картинке относительно корневого
каталога в таком виде: ~/images/имя_файла.тип_файла.
В свойствах объекта GridView выберем Columns. В верхнем
списке выберем тип ImageField и нажмем кнопку Add. Затем в списке
свойств этого поля назначим свойство DataImageURLField=image
(т.е., имя столбца в таблице books). Кроме того, здесь имеет смысл
назначить свойства DataAlternateTextField (альтернативный текст) и
NullImageURL (имя картинки-«заглушки» по умолчанию, которая
будет выдаваться на экран, если в базе данных имя картинки
отсутствует).
Вопрос. Как в ASP.NET работать с ключиками?
Массивы ключиков (cookies) являются свойствами объектов
Response и Request, которые, в свою очередь, являются свойствами
объекта типа Page (от него наследуются все aspx-страницы).
Например, создадим уникальный ключик для идентификатора
корзины покупателя, который будет храниться у клиента 2 недели:
76
Разработка Web-АРМ на ASP.Net
Response.Cookies["id_bask"].Value = ""+System.Guid.NewGuid();
Response.Cookies["id_bask"].Expires=DateTime.Now.AddDays(14);
Прочитать значение ключика из клиентского запроса можно
будет, например, так:
string id_bask=Request.Cookies["id_bask"].Value;
Вопрос. Как создать список гиперссылок следующего вида? В
базе данных имеется таблица категорий, содержащая коды и названия.
Гиперссылка должна представлять собой название категории, а при
щелчке на гиперссылке должен вызываться один и тот же сценарий, в
который передается код категории.
Для создания такого списка подходит объект DataList. Прежде
всего, его следует связать с источником данных. Пусть, например, в
источнике данных задан следующий запрос:
SELECT [Id_cat], [Name_cat] FROM [Categories]
Содержимое списка будем настраивать непосредственно в aspxсценарии. Внутри тэга <asp:DataList></asp:DataList> зададим
следующий код для шаблона строки:
<ItemTemplate>
<asp:HyperLink ID="Name_catLabel" runat="server"
NavigateUrl='<%# Eval("Id_cat", "~/show.aspx?id={0}") %>' >
<%# Eval("Name_cat") %>
</asp:HyperLink>
<br />
</ItemTemplate>
Вопрос. Стандартные объекты GridView, DetailsView не всегда
подходят для удобного представления табличных данных. Как можно
вывести, например, список книг в таком виде:
77
О.В. Пинягина
Для создания такого списка подходит объект Repeater. Прежде
всего, его следует связать с источником данных. Пусть в источнике
данных выбирается вся нужная информация о книгах.
Внешний вид этого объекта будем настраивать непосредственно в
aspx-сценарии. Внутри тэга <asp:Repeater></asp:Repeater> зададим
следующий код для шаблона строки:
<itemtemplate>
<table border="1" width="100%">
<tr><td rowspan="6" width="30%">
<asp:Image ID="Image1" runat="server"
ImageUrl='<%# Eval("image", "~/images/{0}") %>' /> <br/>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl=
'<%# Eval("Id_book", "~/dobasket.aspx?id_book={0}") %>'>
положить в корзину </asp:HyperLink></td>
<td align="right" width="20%"><b>Название</b></td>
<td><%# Eval("name_book") %>
</td></tr>
<tr><td align="right"><b>Автор</b></td>
<td><%# Eval("author") %>
</td></tr>
<tr><td align="right"><b>Издательство</b></td>
<td><%# Eval("name_publ") %>
</td></tr>
<tr><td align="right"><b>Категория</b></td>
<td><%# Eval("name_cat") %>
</td></tr>
<tr><td align="right"><b>Цена</b></td>
<td> <%# Eval("price") %>
</td></tr>
<tr><td align="right"><b>Страниц</b></td>
<td><%# Eval("pages") %>
</td></tr>
</table>
</itemtemplate>
78
Разработка Web-АРМ на ASP.Net
Приложение 2. Как обойтись без ASP.net Configuration
Как создать и настроить базу данных, роли, пользователей,
полномочия, без средств администрирования ASP Configuration
1.
Создаем базу данных.
Для этого следует:
1) запустить утилиту создания ASP.NET-базы данных (примерный
путь)
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ aspnet_regsql.exe
2) на третьей странице мастера назначить точное имя сервера
(например, HOME\SQLEXPRESS), после этого база данных будет
создана автоматически;
3) затем в свойствах web-проекта в папке App_data выбрать пункт
Add existing item, найти файл базы данных (примерный путь к нему
C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\
ASPNETDB.MDF) и подключить его к проекту. Файл будет
скопирован в папку App_data.
2.
Настраиваем тип аутентификации
В файл web.config корневого каталога вместо кода
<authentication mode="Windows"/>
следует поместить такой код:
<authentication mode="Forms">
<forms loginUrl="default.aspx"/>
</authentication>
Режим аутентификации mode=”Forms” означает, что мы не
полагаемся на пользователей Windows, а будем создавать их сами
специально для нашего web-приложения. В этой секции мы также
указываем имя страницы, которая загружается для неавторизованного
пользователя (по умолчанию это файл login.aspx).
3.
Создаем роли
В файле web.config в секции <system.web> включим команду,
разрешающую использование ролей:
79
О.В. Пинягина
<roleManager enabled="true"/>
В проекте отсоединим файл базы данных (щелкнуть правой
кнопкой мыши по базе данных – Detach), в SQL Management Studio –
присоединим его (щелкнуть правой кнопкой мыши на пункте Базы
данных – Присоединить).
В SQL Management Studio выполним команды, создающие роли:
EXECUTE aspnet_Roles_CreateRole '/', 'librarian'
EXECUTE aspnet_Roles_CreateRole '/', 'collector'
EXECUTE aspnet_Roles_CreateRole '/', 'warehouse'
4.
Назначаем ролям права доступа
Внутри нашего корневого каталога создаем 3 каталога,
совпадающие по названиям с именами ролей.
Назначить права доступа, например, для каталога библиотекаря
можно так: в каталог библиотекаря следует поместить следующий
файл web.config.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<authorization>
<allow roles="librarian" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
Доступ разрешается только библиотекарю, всем остальным он
запрещен (назначения доступа читаются снизу вверх).
5.
Наконец, создаем пользователей и привязываем их к
ролям.
В SQL Management Studio выполним команды:
-- создание пользователя john с паролем absdef_
DECLARE @UserId uniqueidentifier
DECLARE @PasswordSalt nvarchar(128)
DECLARE @CurrentTimeUtc datetime
DECLARE @CreateDate datetime
SET @PasswordSalt=NEWID()
80
Разработка Web-АРМ на ASP.Net
SET @CurrentTimeUtc=GETUTCDATE()
SET @CreateDate=GETDATE()
EXECUTE aspnet_Membership_CreateUser
'/'
,'john'
,'absdef_'
,@PasswordSalt
,NULL
,NULL
,NULL
,1
,@CurrentTimeUtc
,@CreateDate
,NULL
,0
,@UserId
-- добавление пользователя john к роли librarian
EXECUTE aspnet_UsersInRoles_AddUsersToRoles
'/'
,'john'
,'librarian'
,@CurrentTimeUtc
В завершение отсоединим базу данных в SQL Management
Studio. Для этого нужно щелкнуть правой кнопкой на базе данных –
Задачи – Отсоединить.
Наконец, в Visual Studio нужно обратно присоединить базу
данных: щелкнуть правой кнопкой на базе данных и выбрать Refresh.
81
О.В. Пинягина
Приложение 3. Web-сервисы
Web-сервисы представляют собой очень удобную технологию
удаленного доступа к данным и программам. Web-сервис можно
представить себе как некоторый объект, который имеет свойства и
методы и расположен по некоторому Internet-адресу. В определенном
смысле это развитие COM-технологий в Internet-программировании.
Создадим простой Web-сервис, который выполняет поиск
названия книги по ее ISBN-номеру.
Щелкнем правой кнопкой по имени сайта в SolutionExplorer,
выберем тип WebService. По умолчанию создается файл
WebService.asmx, а его код с названием WebService.cs помещается в
каталог App_code.
Кроме стандартных библиотек, здесь нам потребуются
следующие:
using
using
using
using
System.Data;
// для DataView
System.Web.UI;
// для DataSourceSelectArguments
System.Web.UI.WebControls;
// для SqlDataSource
System.Configuration;
// для ConfigurationManager
В файле WebService.cs создадим метод FindBook (каждый такой
метод должен предваряться атрибутом [WebMethod]).
[WebMethod]
public string FindBook(string ISBN)
{
Поскольку у Web-сервиса нет визуального представления,
источник данных приходится создавать программным образом
SqlDataSource SqlDataSource1 = new SqlDataSource();
Строку подключения берем из настроек Web-сайта:
SqlDataSource1.ConnectionString =
ConfigurationManager.ConnectionStrings[0].ToString();
Назначаем команду SELECT и параметр для нее и выполняем запрос:
SqlDataSource1.SelectCommand =
"SELECT name_book FROM books WHERE ISBN=@ISBN";
SqlDataSource1.SelectParameters.Add("ISBN", ISBN);
DataView book = new DataView();
book = (DataView)SqlDataSource1.
82
Разработка Web-АРМ на ASP.Net
Select(DataSourceSelectArguments.Empty);
if (book.Count > 0)
return book[0]["name_book"].ToString();
else
return "Книга не найдена!";
}
Запустим Web-сервис в браузере:
Вызовем метод FindBook (щелкнем по гиперссылке):
83
О.В. Пинягина
Зададим значение параметра, щелкнем по кнопке «Invoke».
Получим следующий результат:
Теперь попробуем вызвать этот Web-сервис из внешнего
приложения. Создадим простое оконное приложение:
84
Разработка Web-АРМ на ASP.Net
В окне Solution Explorer проекта щелкнем правой кнопкой по
пункту References и выберем Add Web Reference… Вставим URL
Web-сервиса, в нашем примере этот адрес выглядит так:
http://localhost:2697/WebSite/WebService.asmx,
и нажмем на кнопку Go. По умолчанию ссылка на сборку Web-сервиса
получила имя localhost.
Теперь можно писать обработчик на кнопку «Найти книгу»:
private void button1_Click(object sender, EventArgs e)
{
localhost.WebService book =
new localhost.WebService();
if (textBox1.Text != "")
{
string name = book.FindBook(textBox1.Text);
textBox2.Text = name;
}
else
MessageBox.Show("Задайте номер книги!");
}
В этом обработчике мы создаем объект Web-сервиса
localhost.WebService. Затем вызываем его метод FindBook, передавая
номер книги в качестве параметра. Возвращаемое значение содержит
название книги или строку «Книга не найдена!».
85
О.В. Пинягина
Приложение 4. Краткий справочник используемых
классов
Button отображает элемент управления "Кнопка" на вебстранице.
Пространство имен: System.Web.UI.WebControls.
Свойство OnClientClick получает или задает клиентский скрипт,
выполняемый при происхождении события Click в элементе
управления Button в браузере.
Событие Click происходит на сервере при нажатии элемента
управления Button, обычно на это событие задается серверный методобработчик.
_____________________________________________________________
ConfigurationManager предоставляет доступ к файлам
конфигурации для клиентских приложений.
Пространство имен: System.Configuration
Пример использования: получение текущей строки подключения
ConfigurationManager.ConnectionStrings[0].ToString();
_____________________________________________________________
DataView представляет настраиваемое и допускающее привязку
данных представление объекта DataTable для сортировки, фильтрации,
поиска, изменения и навигации.
Пространство имен: System.Data
Пример использования: выполнение запроса SELECT
DataView1 = (DataView)SqlDataSource1.Select
(DataSourceSelectArguments.Empty);
Свойство Count представляет количество строк в таблице.
К результатам выборки можно обращаться как к двумерному
массиву. При этом к строке можно обращаться по номеру, а к столбцу
– по имени.
_____________________________________________________________
DetailsView отображает значения одной записи из источника
данных в таблице, где каждая строка данных представляет поле
записи. Элемент управления DetailsView позволяет изменять, удалять
и вставлять записи.
Пространство имен: System.Web.UI.WebControls.
86
Разработка Web-АРМ на ASP.Net
_____________________________________________________________
DropDownList представляет элемент управления, позволяющий
пользователю выбрать один элемент из раскрывающегося списка.
Пространство имен: System.Web.UI.WebControls.
Список может быть связан с таблицей базы данных через
источник данных.
Свойство DataSourceID получает или задает ID элемента
управления, из которого элемент управления, присоединенный к
данным, извлекает свои данные.
Свойство DataTextField получает или задает поле источника
данных, предоставляющее текстовое содержимое элементов списка.
Свойство DataValueField получает или задает поле источника
данных, предоставляющее значение для каждого элемента списка.
_____________________________________________________________
FileUpload отображает элемент управления типа текстового
поля и кнопку обзора, позволяя пользователю выбрать файл для
загрузки на сервер.
Пространство имен: System.Web.UI.WebControls.
Свойство FileName возвращает имя файла, загруженного с
компьютера клиента.
Свойство HasFile возвращает значение, определяющее, загружен
ли файл.
Свойство FileBytes возвращает массив байт загруженного файла.
Свойство FileContent возвращает объект Stream, указывающий на
загруженный файл.
Метод SaveAs(ПутьКФайлу) сохраняет содержимое загруженного
файла по указанному пути на веб-сервере.
_____________________________________________________________
FormView отображает значения отдельной записи из источника
данных с помощью пользовательских шаблонов. Элемент управления
FormView позволяет изменять, удалять и вставлять записи.
Пространство имен: System.Web.UI.WebControls.
_____________________________________________________________
GridView отображает значения источника данных в таблице, где
каждый столбец представляет поле, а каждая строка — запись.
Элемент управления GridView позволяет выбирать, сортировать и
изменять эти записи.
87
О.В. Пинягина
Пространство имен: System.Web.UI.WebControls.
_____________________________________________________________
HttpContext Инкапсулирует все связанные с НТТР сведения об
индивидуальном НТТР-запросе.
Пространство имен: System.Web.
Примеры использования:
HttpContext.Current.User.Identity.IsAuthenticated
–
логическое
значение: истина, если пользователь аутентифицирован, ложь в
противном случае.
HttpContext.Current.User.IsInRole(ИмяРоли)
–
логическое
значение: истина, если пользователь связан с данной ролью, ложь в
противном случае.
_____________________________________________________________
Label представляет элемент управления меткой, отображающий
текст на веб-странице.
Пространство имен: System.Web.UI.WebControls.
Свойство Text можно использовать для динамического создания
части HTML-документа.
_____________________________________________________________
ListBox
представляет
элемент
управления
списком,
позволяющий выбрать один или несколько его элементов.
Пространство имен: System.Web.UI.WebControls.
Список может быть связан с таблицей базы данных через
источник данных.
Свойство DataSourceID получает или задает ID элемента
управления, из которого элемент управления, присоединенный к
данным, извлекает свои данные.
Свойство DataTextField получает или задает поле источника
данных, предоставляющее текстовое содержимое элементов списка.
Свойство DataValueField получает или задает поле источника
данных, предоставляющее значение для каждого элемента списка.
_____________________________________________________________
Login предоставляет элементы пользовательского интерфейса для
аутентификации пользователя на веб-узле.
Пространство имен: System.Web.UI.WebControls.
_____________________________________________________________
88
Разработка Web-АРМ на ASP.Net
Page представляет файл ASPX, называемый также страницей
веб-формы, запрашиваемый с сервера, где выполняется вебприложение ASP.NET.
Пространство имен: System.Web.UI.
Свойство Master возвращает объект, представляющий страницушаблон для текущей страницы.
Свойство Request возвращает объект-запрос HttpRequest для
запрашиваемой страницы. В частности:
Request.InputStream представляет собой входной поток запроса;
Request.Cookies
представляет собой массив ключиков,
полученных от клиента (обращение к ключику id_bask:
Request.Cookies["id_bask"].Value);
Request.QueryString представляет собой строку запроса
(обращение к параметру строки запроса с именем id_book:
Request.QueryString["id_book"] );
Свойство Response возвращает объект-ответ HttpResponse,
связанный с объектом Page. Этот объект позволяет отправить клиенту
ответные данные HTTP и содержит сведения об этом ответе. В
частности,
Response.Output представляет собой выходной поток ответа;
Response. Cookies
представляет собой массив ключиков,
отправляемых клиенту;
Response.Redirect(URL) перенаправляет браузер на указанную
страницу.
Свойство Session возвращает текущий объект Session,
содержащий информацию о сеансе. В частности, метод Add(имя,
значение) позволяет добавлять новые сеансовые переменные, метод
Remove(имя) позволяет удалять сеансовые переменные. Обращаться к
сеансовым переменным можно как к одномерному массиву, по имени
переменной.
_____________________________________________________________
RegularExpressionValidator проверяет, соответствует ли
значение связанного элемента управления образцу, заданному
регулярным выражением.
Пространство имен: System.Web.UI.WebControls.
Свойство ControlToValidate получает или задает проверяемый
элемент управления для ввода данных.
89
О.В. Пинягина
Свойство ValidationExpression получает или задает регулярное
выражение, определяющее образец для проверки поля.
Свойство Text получает или задает текст сообщения об ошибке,
отображаемый при сбое проверки.
_____________________________________________________________
RequiredFieldValidator превращает связанный с ним элемент
управления входящими данными в обязательное поле.
Пространство имен: System.Web.UI.WebControls.
Свойство ControlToValidate получает или задает проверяемый
элемент управления для ввода данных.
Свойство Text получает или задает текст сообщения об ошибке,
отображаемый при сбое проверки.
_____________________________________________________________
SqlDataSource представляет базу данных SQL для элементов
управления с привязкой к данным.
Пространство имен: System.Web.UI.WebControls.
Свойство ConnectionString возвращает или задает строку
подключения к конкретному поставщику ADO.NET, используемую
элементом управления SqlDataSource для подключения к основной
базе данных.
Свойство SelectCommand возвращает или задает SQL-строку,
используемую элементом управления SqlDataSource для извлечения
данных из основной базы данных.
Свойство SelectCommandType возвращает или задает значение,
позволяющее определить, чем является текст в свойстве
SelectCommand: SQL-запросом или именем хранимой процедуры.
Свойство SelectParameters возвращает коллекцию, содержащую
параметры, используемые свойством SelectCommand.
Такие же свойства есть для команд INSERT,UPDATE и DELETE.
_____________________________________________________________
SqlCommand представляет инструкцию Transact-SQL или
хранимую процедуру, выполняемую над базой данных SQL Server.
Пространство имен: System.Data.SQLClient
Свойство CommandText возвращает или задает инструкцию
Transact-SQL, имя таблицы или хранимую процедуру, выполняемую
для источника данных.
90
Разработка Web-АРМ на ASP.Net
Свойство CommandType возвращает или задает значение,
указывающее, как будет интерпретироваться свойство CommandText.
Свойство Connection возвращает или задает объект SqlConnection,
используемый экземпляром класса SqlCommand.
Метод ExecuteNonQuery
выполняет
для
подключения
инструкцию Transact-SQL и возвращает количество задействованных в
инструкции строк.
Метод ExecuteReader отправляет CommandText в Connection и
строит SqlDataReader.
_____________________________________________________________
SqlConnection предоставляет открытое подключение к базе
данных SQL Server.
Пространство имен: System.Data.SQLClient.
Свойство ConnectionString возвращает или задает строку,
используемую для подключения к базе данных SQL Server.
Метод Open открывает подключение к базе данных со
значениями свойств, определяемыми объектом ConnectionString.
Метод Close закрывает подключения к базе данных.
Рекомендуется использовать этот метод для закрытия любого
открытого подключения.
_____________________________________________________________
SqlDataReader предоставляет возможность чтения потока
строк только в прямом направлении из базы данных SQL Server.
Пространство имен: System.Data.SQLClient.
Метод Read перемещает указатель SqlDataReader к следующей
записи. Возвращает ложь, если записи исчерпаны, и истину в
противном случае.
К элементам текущей строки можно обращаться как к элементам
одномерного массива: по номеру или по имени столбца.
_____________________________________________________________
TextBox отображает элемент управления текстовым окном для
ввода данных пользователем.
Пространство имен: System.Web.UI.WebControls.
91
О.В. Пинягина
Литература
1. Мак-Дональд, Мэтью; Шпушта, Марио. Microsoft ASP.NET 2.0 с
примерами на C# 2005 для профессионалов.: Пер. с англ. – М.:
ООО «И.Д. Вильямс», 2006. – 1408 с.
2. Беллиньясо, Марко. Разработка приложений в среде ASP.NET
2.0: задача – проект – решение.: Пер. с англ.: – М.: ООО «И.Д.
Вильямс», 2007. – 640 с.
3. Эспозито, Дино. Microsoft ASP.NET 2.0. Базовый курс
(Programming Microsoft ASP.NET 2.0 Core Reference).: Пер. с англ.:
– СПб.: Русская Редакция, 2007. – 688 с.
4. Lowe, Doug; Cox, Ken; Cogswell, Jeff. ASP.NET 2.0 All-In-One Desk
Reference For Dummies : Wiley Publishing, 2006 . – 936 p.
5. Сеппа, Дэвид. Программирование на Microsoft ADO.NET 2.0 +
примеры.: Пер. с англ.: – СПб.: Питер, Русская редакция, 2007. –
780 с.
Web-ресурсы
6. Microsoft Developer Network: http://msdn.microsoft.com/ru-ru
92
Download