Опубликован: 07.05.2010 | Доступ: свободный | Студентов: 1676 / 62 | Оценка: 4.56 / 4.06 | Длительность: 34:11:00
Лекция 3:

Web-формы

Аннотация: Абсолютное позиционирование элементов управления. Обработчик переключения экземпляра элемента CheckBox. Модель событий ASP.NET. Автоматические обратные отсылки. Сохранение состояния вида. Этапы выполнения страниц на сервере. Обработка событий. Автоматическая привязка данных. Страница как контейнер элементов управления. Программное управление заголовком страницы. Создание элемента управления во время выполнения. Класс Page. Объекты Session, Application, Cache. Объект Request. Объект Response. Объект Server. Объект User.
Ключевые слова: Web, HTML, дескриптор, e-form, html-форма, сервер, элементы управления HTML, пользователь, www-броузер, длина строки, Actions, POST, атрибут, 1-разбор, определение, поле, значение, управляющий символ, пассивный, оболочка, элементы управления, программирование, представление, меню, серверные элементы управления, ASP, кодировка, дизайн, script, двойной щелчок, C, контейнер, сигнатура, load, clicking, checkbox, method, HTML-код, позиционирование, парадигма, объектно-ориентированное программирование, объект, таймер, скрытое поле, AutoPostBack, АРМ, сеть, запрос, метка, ПО, Дополнение, control, State, hidden, место, поток, обработка событий, привязка данных, init, управление событиями, свойство класса, передача данных, минимизация, ожидаемое значение, исключительная ситуация, злоумышленник, Windows-приложения, Button, источник данных, жизненный цикл, изменение записей, БД, события элемента управления, извлечение данных, жизненный цикл страницы, disposal, среда разработки, редактор кода, производный класс, делегаты, конструктор класса, конструктор, базовый класс, модификаторы доступа, protected, память, очередь, HTTP, файл, рекурсивный вызов, Panel, labels, параграф, tooltip, всплывающая подсказка, рекурсивный обход, title, heading, интерфейс, коллекция объектов, таблица стилей, metadata, метаданные, horizontal, rule, динамический элемент управления, placeholder, Размещение, вывод, информация, идентификатор, статические методы, remove, динамическая, этапы проектирования, класс, динамические страницы, метод класса, виртуальное, пространство, ASP.NET, cache, requester, responsivity, session.name, trace, principal, Состояние сеанса, идентификатор пользователя, cookie, виртуальный каталог приложения, анонимный доступ, browser, activex, фрейм, transfer, collection, special, header, аутентификация пользователя, сокет, Secure Sockets Layer, SSL, строка запроса, %URI, Internet Explorer, доменная имя, DNS, domain-specific, многоязычность, кэширование вывода, expire, %datetime, останов, Write, char, byte, redirection, обратная совместимость, D-AMPS, кодирование, строка символов, спецсимвол

Файлы к лекции Вы можете скачать здесь

Страницы ASP.NET, официально известные как Web-формы, являются неотъемлемой частью приложения ASP.NET. Это конкретные интерфейсные единицы, которые клиенты могут запрашивать и отображать в своих броузерах. Web-формы в ASP.NET поддерживают ту же технологию визуального программирования, что и Windows-формы в локальных приложениях. А это очень удобно для бедных и несчастных разработчиков, т.е. нас с вами.

В основе Web-форм HTML-страниц лежит дескриптор <form>...</form>. В активных страницах других систем, например PHP, страница допускает наличие на ней нескольких дескрипторов <form>...</form> (дескрипторов HTML-форм). В таком случае эти дескрипторы должны иметь атрибуты ID с разными значениями, чтобы поддерживающая активные страницы система могла различать, какая форма прислала на сервер данные, которые нужно обработать.

Страницы ASP.NET требуют, чтобы на каждой из них было не более одной формы (в принципе, форм на странице может быть несколько, но в каждый момент видимой Visible=True может быть только одна форма).

Но этого достаточно и для обычной HTML-страницы, дабы сколько бы элементов управления HTML-форма не содержала, с них всех собирается информация при подготовке обратной отсылки на сервер. Когда пользователь щелкает на кнопке Submit, броузер извлекает текущие значения последовательно с каждого элемента управления и формирует из них длинную строку пар ID=значение. Затем эта строка отправляется на сервер странице, указанной в атрибуте action дескриптора <form>, используя метод post, или метод get. Если атрибут action не указан, то данные отправляются той же странице. Сам HTML не устанавливает на количество форм никаких ограничений, а ASP.NET устанавливает и для одной активной страницы способна генерировать только одну HTML-форму <form></form>.

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

<html>
<head>
    <title>Посылка сообщений</title>
    <meta content="text/html; charset=windows-1251" http-equiv="Content-Type">
</head>
<body>
    <form method="get" name="form1">
        <p>
            Ваше сообщение:
            <input id="message" name="message" type="text" value="Hello, world!">
            <br>
            Кто посылает:
            <input id="autor" name="autor" type="text" value="CHETKOB B.M.">
        </p>
        <p>
            Кто примкнул к сообщению:
        </p>
        <ul>
            <li>
                <input id="P" name="P" type="checkbox" value="checkbox">
                Петров Петр </li>
            <li>
                <input id="I" name="I" type="checkbox" value="checkbox">
                Иванов Иван </li>
        </ul>
        <p>
            <input id="OK" type="submit" value="Submit">
        </p>
    </form>
</body>
</html>
Представление в броузере (клиенте)

Представление в броузере (клиенте)

Нажмите на кнопку Submit и посмотрите в поле адреса броузера. Форма отослала на сервер строку

WebForms.htm?message=Hello%2C+World%21&autor=CHETKOB+B.M.&OK=Submit

Поскольку в форме указан метод get, то к URL -адресу через символ вопроса ( ?) оказались присоединены пары имя=значение, разделенные амперсандом ( & ). Обратите внимание, что символы пробела, восклицательный знак, запятая (и если вы введете русский текст) заменяются двухбайтными кодами с предваряющим символом процента ( % ).

Это называется URL-кодированием сообщения формы в допустимые символы латинских букв и цифр (для простоты CHETKOB B.M. как раз и введено латинскими буквами), чтобы сообщение не содержало управляющих символов, способных вызвать нежелательный эффект. Поскольку принимающая страница не указана, то принимающей от клиента данные формы на стороне сервера будет та же самая страница. В нашем примере она ничего не делает. Во-первых, она не размещена на сервере, во-вторых, в ней нет активных серверных элементов, способных транслировать дескрипторы и их атрибуты в переменные кода и их значения.

Мы уже говорили, что если такую страницу разместить на сервере, то не смотря на расширение .aspx, ASP.NET -машина ее все равно обрабатывать не будет. Для этого HTML-дескрипторы нужно сделать активными (серверными) добавлением атрибута runat="server". В связи с этим сделаем два определения: та страница, которая не содержит серверных дескрипторов, называется статической (пассивной). Если же на странице есть хоть один дескриптор с указанным атрибутом, то такая страница подлежит дальнейшей обработке системой ASP.NET (или иной) и называется динамической (активной).

Отсюда мораль: статическим страницам лучше присваивать расширения htm или html, чтобы сервер при их запросе клиентом без промедления осуществлял отправку. Если же присвоить статической странице расширение aspx, то все равно она без изменений будет отправлена клиенту, но прежде пройдет через систему обработки, что потребует дополнительного времени и напрасной траты машинных ресурсов.

Пример кодирования страницы

Оболочка имеет две основных вкладки с элементами пользовательского интерфейса для поддержки активных страниц, Standard и HTML. Вкладка HTML содержит элементы, напрямую поддерживающие стандарт HTML-дескрипторов, и нужна для того, чтобы с минимальными переделками можно было приспособить старые страницы к новой технологии ASP.NET. Достаточно добавить к дескрипторам таких элементов атрибут runat="server". Вкладка Standard содержит более развитые элементы управления, имеющие больший набор свойств и событий, полностью ориентированные на объектное программирование.

При помещении элементов с вкладки HTML на страницу атрибут runat="server" автоматически не добавляется и такой элемент средой на сервере обрабатываться не будет. Следовательно, кодировать на языке программирования его будет нельзя. Прежде элемент нужно пометить как серверный, введя напрямую указанный атрибут в дескрипторное представление элемента, или в оболочке в режиме Design на выделенном элементе вызвать контекстное меню и выполнить опцию Run As Server Control (сделать серверным элементом управления)


Если мы разрабатываем активную страницу "с нуля", то лучше сразу применять серверные элементы управления, где уже автоматически встроен дескриптор runat="server". И более того, если его убрать, это будет считаться ошибкой. Дескрипторы, представляющие серверные элементы, начинаются с метки asp:Тип_элемента, далее следуют атрибуты элемента.

Для примера создадим простую страницу.

  • Создайте новый сайт командой File/New/Web Site..., настроив окно мастера примерно так

После щелчка на кнопке OK будет создана начальная страница, которая состоит из двух файлов: Default.aspx и Default.aspx.cs.

Существует два вида кодировки страниц ASP.NET:

  1. Страницы со встроенным кодом (совмещенным), когда весь код C# и HTML-дескрипторы хранятся в одном файле .aspx
  2. Страницы со скрытым кодом (раздельным, застраничным), когда код C# хранится отдельно от кода с дескрипторами в файле .aspx.cs

Второй способ лучше и начальная страница сайта создается именно так. Большой Билл рекомендует использовать именно второй способ, чтобы разделить дизайн страницы и ее функциональность. Но для тренировки один разок мы воспользуемся первым способом.

  • Через панель Solution Explorer удалите файл с кодом C#

  • В редакторе HTML-дескрипторов скорректируйте декларацию Page, чтобы она стала такой
    <%@ Page Language="C#" %>
  • Сразу под декларацией создайте контейнер <script runat="server"></script> для будущего размещения в нем кода C#. Это можно сделать либо напрямую в режиме Source, либо в режиме Design двойным щелчком на странице создать обработчик события по умолчанию Page_Load(), который оболочка поместит в блок скриптов (а затем за ненадобностью обработчик можно удалить)
  • Полность удалите декларацию DOCTYPE (не обязательно, но чтобы не мешала)
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Теперь мы получили страницу, где код C# нужно будет размещать в контейнеры <script runat="server"></script>. Этих контейнеров на странице может быть сколько угодно и они могут располагаться в любом месте. ASP.NET перед выполнением всеравно скомпилирует страницу, пройдя весь ее код. Но все же рекомендуется иметь один контейнер и располагать его вначале страницы (для удобства бедного сопровождающего программиста). Начальная заготовка страницы будет выглядеть так

<%@ Page Language="C#" %>
	
<script runat="server">
</script>
	
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
        </div>
    </form>
</body>
</html>

Создание обработчиков

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

Обработчик загрузки страницы

Напомним, что каждый раз при поступлении на сервер первого запроса или обратной отсылки ( постинга ) с данными инициируется создание объекта страницы. И как только объект страницы будет загружен в память и будут созданы и инициализированы все элементы страницы, срабатывает событие Load, с которым мы свяжем функцию-обработчик с нужным нам кодом.

Обычно, при разработке визуальных элементов управления, имеющих события, назначают событие по умолчанию для того, чтобы оболочка при двойном щелчке на элементе в режиме Design автоматичеси создавала обработчик именно этого события. Например, для элемента Button это событие Click, для флажка CheckBox - CheckedChanged, и т.д. Событие по умолчанию назначается с помощью атрибута [DefaultEvent("Имя_события")].

  • Переведите страницу в режим Design и двойным щелчком на ней создайте заготовку обработчика события по умолчанию Load, которое срабатывает каждый раз, когда страница на сервере загружается в память. Теперь в режиме Source страница будет выглядет так
    <%@ Page Language="C#" %>
    	
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }  
    </script>
    	
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
            </div>
        </form>
    </body>
    </html>
    Заметьте, что в дескрипторе <form> нет атрибутов action и method, это значит, что данные от клиента форма будет посылать этой же странице, и посылать их будет методом post (метод get присоединяет данные элементов управления к URL-адресу). Это нам и нужно, поэтому ничего не будем менять.
  • Поместите с вкладки Standard панели Toolbox элементы Label, CheckBox, TextBox, Button и через панель Properties оформите их по умолчанию примерно так, как показано на рисунке

    Исходный код страницы Default.aspx будет таким

    <%@ Page Language="C#" %>
    	
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
        
        }
    </script>
    	
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Начальная страница</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:Label ID="Label1" runat="server"></asp:Label>
                &nbsp;&nbsp;&nbsp;
                <asp:CheckBox ID="CheckBox1" runat="server"
                    Text="Red" /><br />
                Имя:
                <asp:TextBox ID="TextBox1" runat="server">Снетков</asp:TextBox><br />
                Привет дорогой товарищ (господин)
                <asp:Label ID="Label2" runat="server"></asp:Label><br />
                <br />
                <asp:Button ID="Button1" runat="server" Text="Обновить" />
            </div>
        </form>
    </body>
    </html>

Включение режима абсолютного позиционирования элементов управления

Порядок размещения элементов управления на форме проектирования страницы определяет и порядок размещения генерируемого ими HTML-кода на компьютере клиента (кода разметки страницы). При изменении размеров, стиля или выводимого текста рендеринг автоматически смещается в броузере без нарушения порядка следования информации.

Если какой-то элемент управления жестко зафиксировать на web-странице, то и рендеринг этого элемента в окне броузера клиента также будет зафиксирован. Это может привести к тому, что рендеринг одних элементов управления в броузере будет наползать на другие элементы HTML-вывода страницы. В результате на клиенте может получиться примерно вот такая мешанина


Но все равно, в некоторых случаях может понадобиться именно абсолютное позиционирование. Вот как этот режим в оболочке можно включить:

  • Переведите страницу .aspx в режим Design, чтобы появилось меню Layout оболочки
  • Выберите команду меню Layout/Position/Auto-position Options и настройте диалоговое окно так