<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Лекции</title>
		<link>http://krutoto.ucoz.ru/</link>
		<description></description>
		<lastBuildDate>Wed, 10 Feb 2010 22:03:28 GMT</lastBuildDate>
		<generator>uCoz Web-Service</generator>
		<atom:link href="https://krutoto.ucoz.ru/news/rss" rel="self" type="application/rss+xml" />
		
		<item>
			<title>Дополнительные возможности</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Дополнительные возможности&lt;BR&gt;&lt;/SPAN&gt;для компиляции С#&lt;BR&gt;В настоящем приложении приводится список различных возможностей компи-&lt;BR&gt;лятора С#, которыми можно воспользоваться при выполнении компиляции проек-&lt;BR&gt;тов С# без использования возможностей Visual Studio.NET, либо, если нужно,&lt;BR&gt;чтобы компилятор выполнил какие-либо операции, не поддерживаемые Visual&lt;BR&gt;Studio.NET. Эти опции представлены в виде нескольких таблиц, где они сгруппи-&lt;BR&gt;рованы в соответствии со своей категорией.&lt;BR&gt;В первой таблице приводятся различные форматы файлов, которые могут вклю-&lt;BR&gt;чаться в выходной поток компилятора:&lt;BR&gt;Опция Назначение ч&lt;BR&gt;Выполняется обработка комментариев, предназначенных для создания&lt;BR&gt;XML-документации (помеченных тремя слэшами — / / / ) , и выходной&lt;BR&gt;поток направляется в указанный файл.&lt;BR&gt;Осуществляется компиляция кода, но не создается выходной файл; этот&lt;BR&gt;режим может оказаться полезным для отладки, поскольку в нем можно&lt;BR&gt;увидеть все предупрежден...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Дополнительные возможности&lt;BR&gt;&lt;/SPAN&gt;для компиляции С#&lt;BR&gt;В настоящем приложении приводится список различных возможностей компи-&lt;BR&gt;лятора С#, которыми можно воспользоваться при выполнении компиляции проек-&lt;BR&gt;тов С# без использования возможностей Visual Studio.NET, либо, если нужно,&lt;BR&gt;чтобы компилятор выполнил какие-либо операции, не поддерживаемые Visual&lt;BR&gt;Studio.NET. Эти опции представлены в виде нескольких таблиц, где они сгруппи-&lt;BR&gt;рованы в соответствии со своей категорией.&lt;BR&gt;В первой таблице приводятся различные форматы файлов, которые могут вклю-&lt;BR&gt;чаться в выходной поток компилятора:&lt;BR&gt;Опция Назначение ч&lt;BR&gt;Выполняется обработка комментариев, предназначенных для создания&lt;BR&gt;XML-документации (помеченных тремя слэшами — / / / ) , и выходной&lt;BR&gt;поток направляется в указанный файл.&lt;BR&gt;Осуществляется компиляция кода, но не создается выходной файл; этот&lt;BR&gt;режим может оказаться полезным для отладки, поскольку в нем можно&lt;BR&gt;увидеть все предупреждения и сообщения об ошибках на консоли.&lt;BR&gt;Позволяет задавать имя выходного файла. Если файл не задан, то ком-&lt;BR&gt;пилятор создает стандартный .ехе-файл с тем же именем, что и исход-&lt;BR&gt;ный файл (за исключением расширения).&lt;BR&gt;Позволяет задавать формат выходного файла. У параметра &lt;опция&amp;gt; су-&lt;BR&gt;ществует четыре возможных значения:&lt;BR&gt;• ехе: создается стандартный выполняемый файл (это значение&lt;BR&gt;используется по умолчанию).&lt;BR&gt;• library: создается программная библиотека (DLL).&lt;BR&gt;• module: создается программный отсек (модуль, у которого&lt;BR&gt;отсутствует манифест), который в дальнейшем добавляется к модулю&lt;BR&gt;(с использованием /addmodule).&lt;BR&gt;• winexe: создается выполняемый файл Windows.&lt;BR&gt;/doc:&lt;имяфайла&amp;gt;&lt;BR&gt;/nooutput&lt;BR&gt;/out:&lt;имяфайла&amp;gt;&lt;BR&gt;/target:&lt;опция&amp;gt; /Ь:&lt;опцпя&amp;gt;&lt;BR&gt;Во всех случаях, кроме использования опции /target .-module, в создаваемый&lt;BR&gt;ЕХЕ-файл будет включаться манифест (или в первую DLL, если ЕХЕ-файл не со-&lt;BR&gt;здается). Заметим, что /target может быть сокращено до /t.&lt;BR&gt;В следующей таблице приводятся опции, которые могут задаваться в командной&lt;BR&gt;строке для определения режима оптимизации при компиляции.&lt;BR&gt;858 Приложение С&lt;BR&gt;Опция Назначение&lt;BR&gt;/optimize&lt;+ I -&amp;gt; /о&lt;+ I -&amp;gt; Устанавливает или отменяет режим оптимизации, выполняемой&lt;BR&gt;компилятором, чтобы создать меньший по объему, более быстрый&lt;BR&gt;и более эффективный выходной код. По умолчанию такой режим&lt;BR&gt;отменен. Для включения режима следует воспользоваться&lt;BR&gt;следующим синтаксисом:&lt;BR&gt;/optimize или /optimize*&lt;BR&gt;Для отмены режима используется синтаксис:&lt;BR&gt;/optimize-&lt;BR&gt;В следующей таблице представлены опции для создания модулей .NET и обра-&lt;BR&gt;щения к ним:&lt;BR&gt;Опция Назначение&lt;BR&gt;/addmodule:&lt;HMH отсека&amp;gt; Позволяет задавать один или нескольких программных отсеков, которые&lt;BR&gt;будут включены в указанный модуль. Если задается более одного отсека,&lt;BR&gt;они отделяются друг от друга точкой с запятой. Эта опция не может&lt;BR&gt;использоваться в Visual Studio.NET.&lt;BR&gt;/nostdliix+ I -&amp;gt; Позволяет задать, следует или нет импортировать стандартную библиотеку&lt;BR&gt;( m s c o r l i b . d l l ) , которая импортируется по умолчанию. Если вы желаете&lt;BR&gt;реализовать собственное пространство имен System и классы, то можно&lt;BR&gt;не импортировать стандартную библиотеку. Для этого используется&lt;BR&gt;следующий синтаксис:&lt;BR&gt;/nostdlib ИЛИ /nostdlib+&lt;BR&gt;Синтаксис для импорта стандартной библиотеки:&lt;BR&gt;/nostdlib-&lt;BR&gt;/ге&amp;pound;егепсе:&lt;имя модуля&amp;gt; Предназначен для импорта метаданных из файла модуля. Можно либо&lt;BR&gt;/г:&lt;имя модуля&amp;gt; задать полный путь к данному модулю, либо этот путь может быть задан&lt;BR&gt;в переменной среды PATH, либо указать путь относительно текущего проекта.&lt;BR&gt;Если задается более одного файла, то они разделяются точками с запятой.&lt;BR&gt;В следующей таблице объясняются опции, которые применяются при отладке&lt;BR&gt;и поиске ошибок:&lt;BR&gt;Опция Назначение&lt;BR&gt;/bugreport:&lt;имя файла&amp;gt; Создает файл с заданным именем, в котором содержится вся информация&lt;BR&gt;об ошибках, сгенерированная компилятором. В состав содержимого файла&lt;BR&gt;входит:&lt;BR&gt;• Копия исходного файла.&lt;BR&gt;• Список опций компилятора.&lt;BR&gt;• Информация о версии компилятора, об операционной системе и т. д.&lt;BR&gt;• Весь выходной поток компилятора&lt;BR&gt;• Описание обнаруженной проблемы и возможное решение&lt;BR&gt;(при наличии такового)&lt;BR&gt;Эта опция не может использоваться в Visual Studio.NET.&lt;BR&gt;Дополнительные&lt;BR&gt;Опция&lt;BR&gt;возможности для компиляции С#&lt;BR&gt;Назначение&lt;BR&gt;859&lt;BR&gt;Продолжение таблицы&lt;BR&gt;/checked&lt;+ I -&amp;gt; Позволяет определять, будет ли переполнение целых значений приводить&lt;BR&gt;к возникновению ошибки во время выполнения. Это относится только&lt;BR&gt;к тому коду, который находится вне области действия описателей checked&lt;BR&gt;и unchecked. По умолчанию этот режим отключен. Синтаксис, включающий&lt;BR&gt;режим контроля за переполнением, имеет вид:&lt;BR&gt;/checked ИЛИ /checked+&lt;BR&gt;Для отказа от контроля за переполнением следует использовать следующий&lt;BR&gt;синтаксис:&lt;BR&gt;/checked-&lt;BR&gt;/debug&lt;+ I -&amp;gt;&lt;BR&gt;/debug:&lt;опция&amp;gt;&lt;BR&gt;/fullpaths&lt;BR&gt;/nowarn:&lt;номер&amp;gt;&lt;BR&gt;/warn: &lt;опция&amp;gt;&lt;BR&gt;/•ю:&lt;опция&amp;gt;&lt;BR&gt;/warnaserror&lt;+ I -&amp;gt;&lt;BR&gt;Позволяет генерировать отладочную информацию.&lt;BR&gt;Для этой цели используется синтаксис:&lt;BR&gt;/debug ИЛИ /debug*&lt;BR&gt;Для отмены режима используется следующий синтаксис:&lt;BR&gt;/debug-&lt;BR&gt;По умолчанию режим отладки не используется. Если задается вывод&lt;BR&gt;отладочной информации, то имеются два варианта, касающиеся того,&lt;BR&gt;какого типа отладочная информация будет генерироваться:&lt;BR&gt;• /debug:full: позволяет присоединить отладчик к работающей программе&lt;BR&gt;• /debug rpdbonly: позволяет осуществлять отладку исходного кода,&lt;BR&gt;если программа запускается в отладчике, но будет выводить только&lt;BR&gt;ассемблер, если выполняющаяся программа присоединена к отладчику.&lt;BR&gt;Задает полный путь к файлу, в котором содержится ошибка.&lt;BR&gt;Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;Не позволяет компилятору генерировать сообщения об ошибках с заданным&lt;BR&gt;номером. Номер предупреждения, отказ от вывода которого задается,&lt;BR&gt;определяется опцией &lt;номер&amp;gt;. Если задается более одного номера,&lt;BR&gt;то они разделяются запятыми. Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;Позволяет задавать минимальный уровень выводимых ошибок.&lt;BR&gt;Имеются следующие возможности:&lt;BR&gt;• 0: Отказ от вывода всех ошибок.&lt;BR&gt;• 1: Вывод сообщений только о грубых ошибках.&lt;BR&gt;• 2: Вывод сообщений о грубых ошибках&lt;BR&gt;и об ошибках средней &quot;тяжести&quot;.&lt;BR&gt;• 3: Вывод сообщений о грубых ошибках,&lt;BR&gt;об ошибках средней &quot;тяжести&quot;&lt;BR&gt;и о незначительных ошибках.&lt;BR&gt;• 4: Вывод сообщений обо всех ошибках,&lt;BR&gt;включая информационные сообщения&lt;BR&gt;Устанавливает режим, в котором все предупреждения трактуются&lt;BR&gt;как ошибки. Для включения режима используется следующий синтаксис:&lt;BR&gt;/warnaserror ИЛИ /warnaserror+&lt;BR&gt;Для отмены режима следует использовать синтаксис:&lt;BR&gt;/warnaserror-&lt;BR&gt;По умолчанию режим не устанавливается.&lt;BR&gt;860 Приложение С&lt;BR&gt;Опция Назначение&lt;BR&gt;/def л.пе&lt;имя&amp;gt; Определяет символ препроцессора&lt;BR&gt;/а&lt;имя&amp;gt; с именем &lt;имя&amp;gt;.&lt;BR&gt;Таблица слева демонстрирует, как следует&lt;BR&gt;задавать директивы препроцессора.&lt;BR&gt;В следующей ниже таблице представлены&lt;BR&gt;опции, связанные с использованием внешних&lt;BR&gt;ресурсов:&lt;BR&gt;Опция Назначение&lt;BR&gt;/linkresourсе КУПЛЯ файла&amp;gt;&lt;BR&gt;файла&amp;gt;&lt;BR&gt;/resource:&lt;имя файла&amp;gt;&lt;BR&gt;/гез:&lt;имя файла&amp;gt;&lt;BR&gt;/Win32 icon :&lt;имя файла&amp;gt;&lt;BR&gt;/win32res:&lt;HMH файла&amp;gt;&lt;BR&gt;Позволяет создавать ссылку на указанный .NET-ресурс.&lt;BR&gt;Имеет следующие два необязательных дополнительных параметра&lt;BR&gt;(разделенных запятыми):&lt;BR&gt;• i d e n t i f i e r : Логическое имя ресурса;&lt;BR&gt;имя, которое будет использовано для загрузки ресурса&lt;BR&gt;(по умолчанию используется &lt;имя файла&amp;gt;).&lt;BR&gt;• mimetype: Строка, представляющая тип носителя,&lt;BR&gt;на котором находится ресурс (по умолчанию отсутствует).&lt;BR&gt;Эта опция не может использоваться в Visual Studio.NET.&lt;BR&gt;Внедряет указанный .NET-pecypc в выходной файл.&lt;BR&gt;Имеет следующие два необязательных дополнительных параметра&lt;BR&gt;(разделенных запятыми):&lt;BR&gt;• i d e n t i f i e r : Логическое имя ресурса;&lt;BR&gt;имя, которое будет использовано для загрузки ресурса&lt;BR&gt;(по умолчанию используется &lt;имя файла&amp;gt;).&lt;BR&gt;• mimetype: Строка, представляющая тип носителя,&lt;BR&gt;на котором находится ресурс (по умолчанию отсутствует).&lt;BR&gt;Позволяет включить заданный файл с иконкой Win32 (Лео)&lt;BR&gt;в выходной файл.&lt;BR&gt;Позволяет включить заданный файл с ресурсом Win32 ( . r e s )&lt;BR&gt;в выходной файл. Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;В заключительной таблице представлены остальные опции компилятора:&lt;BR&gt;Опция Назначение&lt;BR&gt;@&lt;имя файла&amp;gt;&lt;BR&gt;/baseaddress:&lt;адрес&amp;gt;&lt;BR&gt;/codepage:&lt;идентификатор&amp;gt;&lt;BR&gt;/help&lt;BR&gt;/?&lt;BR&gt;Позволяет задавать файл, где содержатся все опции компилятора&lt;BR&gt;и исходные файлы, которые будут обрабатываться компилятором&lt;BR&gt;таким образом, как если бы они были заданы в командной строке.&lt;BR&gt;Позволяет задавать наиболее предпочтительный базовый адрес,&lt;BR&gt;по которому будет загружаться DLL. Значение опции &lt;адрес&amp;gt;&lt;BR&gt;может быть представлено в десятичном, шестнадцатеричном&lt;BR&gt;или восьмеричном виде.&lt;BR&gt;Позволяет задавать страницу кодировки (значение, передаваемое&lt;BR&gt;опцией &lt;идентификатор&amp;gt;), которая должна использоваться для всех&lt;BR&gt;файлов с исходным кодом в процессе компиляции. Эта опция&lt;BR&gt;оказывается полезной, когда для файлов с кодами на С# используется&lt;BR&gt;набор символов, отличный от используемого в системе по умолчанию.&lt;BR&gt;Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;Помещает перечень опций компилятора в стандартный выходной&lt;BR&gt;поток. Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;Дополнительные возможности для компиляции С# 861&lt;BR&gt;Продолжение таблицы&lt;BR&gt;Опция Назначение&lt;BR&gt;/incremental&lt;+ I -&amp;gt;&lt;BR&gt;/incr&lt;+ I -&amp;gt;&lt;BR&gt;/main:&lt;класс&amp;gt;&lt;BR&gt;/nologo&lt;BR&gt;/recurse:&lt;директория&amp;#92;файл&amp;gt;&lt;BR&gt;/unsafe&lt;BR&gt;Позволяет осуществлять, последовательную компиляцию файлов&lt;BR&gt;с исходным кодом, при которой компилируются только функции,&lt;BR&gt;в которые были внесены какие-либо изменения с момента&lt;BR&gt;предшествующей компиляции. Информация о состоянии&lt;BR&gt;предшествующей компиляции сохраняется в двух файлах —&lt;BR&gt;в файле с расширением .dbg (или в файле с расширением .pdb,&lt;BR&gt;если установлен режим /debug), предназначенном для хранения&lt;BR&gt;отладочной информации, и в файле с расширением . incr — здесь&lt;BR&gt;сохраняется информация о состоянии. Для задания такого режима&lt;BR&gt;можно воспользоваться одним из двух следующих вариантов&lt;BR&gt;синтаксиса:&lt;BR&gt;/incremental ИЛИ /incremental+&lt;BR&gt;Чтобы отменить этот режим, следует использовать&lt;BR&gt;следующий синтаксис:&lt;BR&gt;/incremental-&lt;BR&gt;По умолчанию этот режим не установлен.&lt;BR&gt;Позволяет задавать местоположение основного метода Main (),&lt;BR&gt;если в исходном коде таких методов несколько.&lt;BR&gt;Позволяет отказаться от вывода &quot;шапки&quot; с информацией&lt;BR&gt;о компиляторе. Эта опция недоступна в Visual Studio.NET.&lt;BR&gt;Позволяет осуществлять поиск файлов, подлежащих компиляции,&lt;BR&gt;внутри поддиректорий. Имеет две опции:&lt;BR&gt;• &lt;директория&amp;gt; (необязательная): определяет директорию&lt;BR&gt;или поддиректорию, с которой следует начинать поиск.&lt;BR&gt;Если эта опция не задана, то поиск осуществляется&lt;BR&gt;с директории текущего проекта.&lt;BR&gt;• &lt;файл&amp;gt;: определяет файл или файлы, поиск которых&lt;BR&gt;следует осуществлять.&lt;BR&gt;Позволяет выполнять компиляцию кода, который помечен&lt;BR&gt;ключевым словом unsafe.&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/dopolnitelnye_vozmozhnosti/2010-02-11-414</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/dopolnitelnye_vozmozhnosti/2010-02-11-414</guid>
			<pubDate>Wed, 10 Feb 2010 22:03:28 GMT</pubDate>
		</item>
		<item>
			<title>Инсталляция MSDE</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Инсталляция MSDE&lt;BR&gt;&lt;/SPAN&gt;Предназначенные для работы при больших нагрузках системы управления БД&lt;BR&gt;(database managemant system — DBMS) типа Oracle и Microsoft SQL Server по-&lt;BR&gt;зволяют поддерживать выполнение десятков тысяч транзакций в минуту, при этом&lt;BR&gt;сокращая до минимума время отключения для проведения работ по сопровожде-&lt;BR&gt;нию и внесению изменений. Они представляют собой замечательный пример со-&lt;BR&gt;временного программного обеспечения, однако за эту мощь приходится платить&lt;BR&gt;определенную цену. Прежде всего — дороговизной таких систем DBMS, которая&lt;BR&gt;начинается с несколько тысяч долларов и круто идет вверх при увеличении воз-&lt;BR&gt;можностей. КрОхМе того, за применение систем DBMS промышленного использо-&lt;BR&gt;вания приходится также расплачиваться памятью, мощностью процессора и объемом&lt;BR&gt;памяти на жестком диске, которые необходимы для работы таких систем.&lt;BR&gt;С точки зрения разработчиков установка такой полномасштабной системы на&lt;BR&gt;переносных компью...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Инсталляция MSDE&lt;BR&gt;&lt;/SPAN&gt;Предназначенные для работы при больших нагрузках системы управления БД&lt;BR&gt;(database managemant system — DBMS) типа Oracle и Microsoft SQL Server по-&lt;BR&gt;зволяют поддерживать выполнение десятков тысяч транзакций в минуту, при этом&lt;BR&gt;сокращая до минимума время отключения для проведения работ по сопровожде-&lt;BR&gt;нию и внесению изменений. Они представляют собой замечательный пример со-&lt;BR&gt;временного программного обеспечения, однако за эту мощь приходится платить&lt;BR&gt;определенную цену. Прежде всего — дороговизной таких систем DBMS, которая&lt;BR&gt;начинается с несколько тысяч долларов и круто идет вверх при увеличении воз-&lt;BR&gt;можностей. КрОхМе того, за применение систем DBMS промышленного использо-&lt;BR&gt;вания приходится также расплачиваться памятью, мощностью процессора и объемом&lt;BR&gt;памяти на жестком диске, которые необходимы для работы таких систем.&lt;BR&gt;С точки зрения разработчиков установка такой полномасштабной системы на&lt;BR&gt;переносных компьютерах для тестирования SQL-операторов может оказаться не-&lt;BR&gt;возможной. Компания Microsoft предлагает определенную альтернативу — она&lt;BR&gt;взяла продукт SQL Server и убрала все инструменты, предназначенные для управ-&lt;BR&gt;ления и ведения разработок, оставив только ядро, отвечающее за работу с данными.&lt;BR&gt;Затем они ограничили максимальное число пользователей — не более пяти, и объ-&lt;BR&gt;ем данных — 2 гигабайта. Полученный в результате продукт получил название&lt;BR&gt;MSDE (Microsoft Data Engine — ядро для работы с данными компании Microsoft).&lt;BR&gt;Он вполне может использоваться в качестве серверной части, к которой совер-&lt;BR&gt;шенно естественно могут добавляться клиентские с CD, что позволяет инсталли-&lt;BR&gt;ровать менее масштабные варианты SQL Server.&lt;BR&gt;Инсталляция Microsoft Data Engine (MSDE)&lt;BR&gt;На дисках Office 2000 программа MSDE располагается на Disk 0ne&amp;#92;SQL&amp;#92;x86&amp;#92;&lt;BR&gt;SETUP&amp;#92;SetupSQL.exe.&lt;BR&gt;Если вы обладаете лицензией на какой-либо продукт Visual Products, то вы мо-&lt;BR&gt;жете скачать MSDE С сайта http://insdn.microsoft.com/vstudio/insde/default.asp&lt;BR&gt;или — по тому же самому адресу — сделать заказ, и CD будет выслан вам по поч-&lt;BR&gt;те. Инсталляция продукта очень проста; требуется 50 Мбайт памяти на жестком&lt;BR&gt;диске плюс собственно ваши данные. И хотя это всего лишь MSDE, а не Microsoft&lt;BR&gt;SQL Server, приложение будет инсталлировано в папке C:&amp;#92;MSSQL7. Внутри этой&lt;BR&gt;папки располагается папка Data, в которой вы сможете обнаружить базы данных,&lt;BR&gt;устанавливаемые по умолчанию.&lt;BR&gt;1. Весь процесс инсталляции занимает менее пятнадцати минут,&lt;BR&gt;Начните с завершения всех работающих приложений.&lt;BR&gt;Иъ MSDE&lt;BR&gt;851&lt;BR&gt;2. С помощью пункта меню&lt;BR&gt;Start | Run | browse найдите выполняемый&lt;BR&gt;файл setupSQL.exe и запустите его.&lt;BR&gt;Для этого необходимо один раз&lt;BR&gt;щелкнуть мышью на кнопке ОК,&lt;BR&gt;чтобы покинуть окно поиска,&lt;BR&gt;и второй раз щелкнуть на кнопке ОК&lt;BR&gt;для запуска файла установки.&lt;BR&gt;3. Будет запущен мастер инсталляции,&lt;BR&gt;который попросит выбрать метод&lt;BR&gt;инсталляции (см. рис. справа).&lt;BR&gt;&quot; Выберите опцию Local Install (локальная&lt;BR&gt;инсталляция) и щелкните мышью&lt;BR&gt;на кнопке Next.&lt;BR&gt;5. Теперь мастер запросит информацию,&lt;BR&gt;касающуюся вашего имени и вашей&lt;BR&gt;компании (см. рис. справа). Введите&lt;BR&gt;требуемую информацию и щелкните&lt;BR&gt;мышью на кнопке Next.&lt;BR&gt;6. Теперь нужно определить Setup Type&lt;BR&gt;(тип установки) — это единственное&lt;BR&gt;место, где можно изменять&lt;BR&gt;местоположение файлов. Как и для&lt;BR&gt;полномасштабного продукта SQL&lt;BR&gt;Server, в данный момент можно&lt;BR&gt;разместить свои данные на диске,&lt;BR&gt;4. Теперь мастер выводит экран,&lt;BR&gt;представленный на рисунке слева.&lt;BR&gt;На этом экране содержится&lt;BR&gt;предостережение о необходимости&lt;BR&gt;завершить все другие приложения,&lt;BR&gt;а также информация, касающаяся&lt;BR&gt;охраны прав. Щелкните мышью .&lt;BR&gt;на кнопке Next.&lt;BR&gt;852 Приложение В&lt;BR&gt;отличном от того, на котором&lt;BR&gt;располагаются программные файлы&lt;BR&gt;(см. рис. слева). Щелкните мышью&lt;BR&gt;на кнопке Next.&lt;BR&gt;7. Для работы MSDE необходимо&lt;BR&gt;располагать информацией об используемом&lt;BR&gt;по умолчанию наборе символов,&lt;BR&gt;а также о некоторых других установках&lt;BR&gt;по используемому языку программирования&lt;BR&gt;(см. рис. справа). Все это не требует&lt;BR&gt;пояснений. Обычно достаточно принять&lt;BR&gt;значения, используемые по умолчанию.&lt;BR&gt;Щелкните мышью на кнопке Next.&lt;BR&gt;ШШШ-&apos; г..&lt;BR&gt;• &apos; • -&lt;BR&gt;?В»т«у Order&lt;BR&gt;|C&amp;pound;*ta&lt;BR&gt;ияиннми&lt;BR&gt;p&lt;BR&gt;8. MSDE предоставляет возможность инсталлировать&lt;BR&gt;несколько библиотек для установления&lt;BR&gt;сетевых соединений (см. рис. слева).&lt;BR&gt;В самом простом случае воспользуйтесь&lt;BR&gt;значением, предлагаемым по умолчанию,&lt;BR&gt;которое предполагает инсталляцию&lt;BR&gt;только TCP/IP Sockets и Multi-Protocol.&lt;BR&gt;Щелкните мышью на кнопке Next.&lt;BR&gt;9. Далее мастер потребует информацию&lt;BR&gt;о том, какой способ управления&lt;BR&gt;учетными записями ему следует&lt;BR&gt;использовать (см. рис. справа).&lt;BR&gt;В самом простом случае следует&lt;BR&gt;выбрать &apos;Use the same account for&lt;BR&gt;each service&apos; (использование одной&lt;BR&gt;и той же учетной записи для всех&lt;BR&gt;служб) и &apos;use local system account&apos;&lt;BR&gt;(использование учетной записи&lt;BR&gt;локальной системы).&lt;BR&gt;Инсталляция MSDE 853&lt;BR&gt;dkNext U? begirt &amp;amp;шп$ fcifi?&lt;BR&gt;10. В этот момент мастер выведет экран&lt;BR&gt;для запуска процедуры копирования&lt;BR&gt;(см. рим. слева); щелкните мышью&lt;BR&gt;на кнопке Next.&lt;BR&gt;11. После этого увидите окно с сообщением,&lt;BR&gt;которое информирует о том, какие&lt;BR&gt;именно файлы копируются.&lt;BR&gt;Далее выводятся последовательные&lt;BR&gt;сообщения по мере развития процесса.&lt;BR&gt;12. Мастер выводит экран &apos;setup complete1&lt;BR&gt;(начальная установка завершена)&lt;BR&gt;(см. след. ниже рис.). Щелкните мышью&lt;BR&gt;на кнопке Finish.&lt;BR&gt;13. Теперь можно запустить MSDE,&lt;BR&gt;выбрав пункт меню&lt;BR&gt;Start | programs | MSDE | Service Manager&lt;BR&gt;Service Manager для MSDE ничем&lt;BR&gt;не отличается от Service Manager&lt;BR&gt;для полного продукта SQL Server.&lt;BR&gt;14. При желании можете указать режим&lt;BR&gt;автозапуска.&lt;BR&gt;Для работы MSDE требуется&lt;BR&gt;приблизительно 5,3 Мбайт&lt;BR&gt;оперативной памяти, а для Service&lt;BR&gt;Manager — еще 2,3. Поэтому установка&lt;BR&gt;режима автозапуска приведет&lt;BR&gt;к захвату соответствующих ресурсов,&lt;BR&gt;&amp;#92; &apos; &quot; •&lt;BR&gt;Ике*&lt;BR&gt;1&lt;BR&gt;s S i P f&lt;BR&gt;1&lt;BR&gt;• • • • • • • &apos; • • • : = • &apos; • •&lt;BR&gt;.&apos; L&lt;BR&gt;Server Service М&lt;*.„&lt;BR&gt;ft) JJ ^ -&lt;BR&gt;—&lt;BR&gt;-&lt;BR&gt;i 1:47 PM&lt;BR&gt;нежелательно, если вы&lt;BR&gt;на самом деле не собираетесь&lt;BR&gt;использовать систему.&lt;BR&gt;Вы всегда при необходимости&lt;BR&gt;можете запустить ее вручную.&lt;BR&gt;15. Для запуска службы MSDE&lt;BR&gt;щелкните мышью на кнопке&lt;BR&gt;Start с зеленой стрелкой.&lt;BR&gt;В процессе работы Service Manager&lt;BR&gt;с правой стороны системной линейки,&lt;BR&gt;расположенной внизу экрана, будет на-&lt;BR&gt;ходиться вспомогательная иконка. Пока&lt;BR&gt;MSDE выполняется, она выводится с&lt;BR&gt;зеленой стрелкой, а после остановки —&lt;BR&gt;с красным квадратом, как показано на&lt;BR&gt;рисунке слева.&lt;BR&gt;854 Пр сложение В&lt;BR&gt;I&lt;BR&gt;Чтобы проверить номер используемой вер-&lt;BR&gt;сии, можное щелкнуть правой кнопкой мыши&lt;BR&gt;на вспомогательной иконке MSDE и выбрать&lt;BR&gt;пункт меню About (О программе). Вы должны&lt;BR&gt;получить сообщение о том, что используете&lt;BR&gt;SQL Service Manager версии 7 (см. рис. слева).&lt;BR&gt;Импорт Northwind в MSDE&lt;BR&gt;MSDE инсталлируется без каких-либо&lt;BR&gt;стандартных баз данных, поэтому требуется&lt;BR&gt;импортировать базу данных, чтобъг работать&lt;BR&gt;с примерами, приведенными в главах 18 и 19.&lt;BR&gt;MSDE и SQL Server поставляются совместно&lt;BR&gt;с утилитой, предназначенной для импорта&lt;BR&gt;и экспорта данных. Мы воспользуемся предо-&lt;BR&gt;ставляемыми ею возможностями для импорта в MSDE повсеместно распростра-&lt;BR&gt;ненной базы данных Northwind (nwind.mdb), КОТОрая ВХОДИТ В КОМПЛСКТ ПОСТавКИ&lt;BR&gt;Access и Visual Basic 6.&lt;BR&gt;Определите местоположение&lt;BR&gt;БД Northwind, воспользовавшись&lt;BR&gt;пунктом меню Start | Search | Files&lt;BR&gt;and folders | File и набрав текст&lt;BR&gt;nwind.mdb в окне Named:.&lt;BR&gt;Скопируйте (но не переносите)&lt;BR&gt;этот файл в папку с именем&lt;BR&gt;С:&amp;#92;BegCSharp&amp;#92;AppendixB&lt;BR&gt;(которую вам придется&lt;BR&gt;создать самостоятельно).&lt;BR&gt;2. Перейдите в раздел меню&lt;BR&gt;Start/programs/MSDE or SQL&lt;BR&gt;Server/Import and Export Data.&lt;BR&gt;Перед вами возникнет экран,&lt;BR&gt;представленный на рисунке справа,&lt;BR&gt;Data Transformation Services&lt;BR&gt;import/Export Wizard&lt;BR&gt;TWb wuafd gudee you В I I ;-• б e steps ?o p&lt;BR&gt;d l a between many popular &lt;fata fCK^ats including&lt;BR&gt;s. spteadffoai*. &lt; d ffe&lt;BR&gt;Help&lt;BR&gt;Choose о Data Source&lt;BR&gt;в do you v^ant to^ c^Opy d^s? You from&lt;BR&gt;D#3 Su»C&apos;j k&apos;-&amp;#92; r&apos; &apos;: sift Access&lt;BR&gt;^S^- *o connect select с dclab we end psovide a user name -2&lt;BR&gt;1 ^ 4 ? Vcu ftvv need ^o specify edvenced opj.bnt,&lt;BR&gt;p P S r p ^ l i l l l&lt;BR&gt;z J&lt;BR&gt;Aclvonc-cd., j&lt;BR&gt;Data Transformation Wizard&lt;BR&gt;(мастер трансформации данных).&lt;BR&gt;3. Щелкните мышью на кнопке Next,&lt;BR&gt;чтобы перейти к экрану Source&lt;BR&gt;(источник), и выберите в качестве&lt;BR&gt;значения поля Data Source (источник&lt;BR&gt;данных) Microsoft Access, как&lt;BR&gt;показано на рисунке слева, и задайте&lt;BR&gt;значение в поле File name (имя&lt;BR&gt;файла) — nwind.mdb (необходимо&lt;BR&gt;СОСЛаТЬСЯ на КОПИЮ Northwind,&lt;BR&gt;которую вы создали в директории&lt;BR&gt;С: &amp;#92;BegCSharp&amp;#92;AppendixB).&lt;BR&gt;Инсталляция MSDE 855&lt;BR&gt;4. Щелкните мышью на кнопке Next,&lt;BR&gt;чтобы перейти к экрану Destination&lt;BR&gt;(назначение) (см. рис. справа)&lt;BR&gt;и выбрать для поля Destination&lt;BR&gt;значение Microsoft OLE DB Provider&lt;BR&gt;for SQL Server (провайдер OLE DB&lt;BR&gt;для SQL Server компании Microsoft),&lt;BR&gt;для поля Server — значение (local),&lt;BR&gt;а для Username (имя пользователя)&lt;BR&gt;в разделе SQL Server Authentication&lt;BR&gt;(аутентификация SQL Server) —&lt;BR&gt;значение sa (пароля не требуется).&lt;BR&gt;Create Datable&lt;BR&gt;Specify thte name md properties of &amp;#92;Ы SQL j&lt;BR&gt;Server database.&apos; v - - * * I&lt;BR&gt;Name:&lt;BR&gt;Data file si:&lt;BR&gt;Log file siz*&lt;BR&gt;JNorlhwind&lt;BR&gt;±J&lt;BR&gt;«icel Help&lt;BR&gt;в этом диалоге следует ввести имя базы дан-&lt;BR&gt;ных (мы будем использовать в качестве име-&lt;BR&gt;ни &quot;Northwind&quot;) и задать размер файла Data,&lt;BR&gt;равным 4 Мбайт, а файла Log — 1 Мбайт.&lt;BR&gt;5. Для перехода на экран Method (метод)&lt;BR&gt;(см. рис. справа) щелкните мышью&lt;BR&gt;на кнопке Next и выберите copy table&lt;BR&gt;(копировать таблицу). Щелкните на&lt;BR&gt;Save, schedule, and replicate package&lt;BR&gt;Specify iym 4Vdnl to save &amp;#92;Ш OTS ftfrffritflt You Мф a&amp;amp;o sepicste Ш&amp;amp; 4&amp;amp;1&amp;amp; &amp;amp;•&lt;BR&gt;«chedufe tit psekags to be екесмЫ &amp;amp; з Ш* t^ne.&lt;BR&gt;г When&lt;BR&gt;c*e;e|y Г* и&lt;BR&gt;e DTS рйс&apos;иадв k&lt;BR&gt;Choose a destination&lt;BR&gt;T &amp;amp; &lt;Мше do уац v&lt;tmi to copy data? You слш COPJ* data iu o&lt;BR&gt;;CL S^&lt;BR&gt;~. То co^ntc? to ll^oxiit SOL ic«ver. j*ou л&lt;BR&gt;&lt;* U»SQLS«v«Awthen»icfiSoo[&lt;BR&gt;Rehe*h [ Advanced.. | &apos;&lt;BR&gt;Перед тем как щелкнуть мышью на кнопке Next,&lt;BR&gt;выберите для базы данных значение &lt;new&amp;gt;, что по-&lt;BR&gt;зволит перейти в показанный на рисунке слева диа-&lt;BR&gt;лог Create Database (диалог создания базы данных);&lt;BR&gt;Specify TdbJc Copy or&lt;BR&gt;Specily л;-;! -.ы :а сору ше or tmci&lt;BR&gt;h dMt source.&lt;BR&gt;ij«ciry Uve 4i&apos;.s&lt;BR&gt;* F&lt;BR&gt;•д(&lt;BR&gt;J&lt;BR&gt;кнопке Next, а затем на следующем&lt;BR&gt;раскрывшемся экране выберите&lt;BR&gt;copy all (копировать все).&lt;BR&gt;6. Щелкните мышью на кнопке Next&lt;BR&gt;и выберите режим Run immediately&lt;BR&gt;(немедленный запуск), как показано&lt;BR&gt;на рисунке слева.&lt;BR&gt;856 Приложение В&lt;BR&gt;Completing the DTS Import/Export&lt;BR&gt;Wizard&lt;BR&gt;You have successfully specified the information requited io&lt;BR&gt;copy, if arafoi«v or Um$t&amp;amp; the dake* R evtew the selections&lt;BR&gt;bebw жд cfck on FINISH to етеойе&lt;BR&gt;Summewy:&lt;BR&gt;T ]&lt;BR&gt;Uong Microsoft Je? 4.0 OLE DB Provider H&lt;BR&gt;Detfkvatim: Mbiosoft SQL S&amp;amp;tvej&lt;BR&gt;Using Microso-Jt OLE: DB Piovide for SQL Server&lt;BR&gt;с Back&lt;BR&gt;Щелкните мышью на кнопке Next&lt;BR&gt;еще раз, взгляните на окончательный&lt;BR&gt;результат (см. рис. слева) и щелкни-&lt;BR&gt;те мышью на кнопке Finish.&lt;BR&gt;7. Доводитесь появления&lt;BR&gt;сообщения об успешном&lt;BR&gt;завершении, а затем щелкните&lt;BR&gt;на кнопке Done (сделано).&lt;BR&gt;8. Обратите внимание на то,&lt;BR&gt;что все запросы, ответы&lt;BR&gt;и прочая информация&lt;BR&gt;копированию не подлежат.&lt;BR&gt;9. Откройте Windows Explorer&lt;BR&gt;и убедитесь, что в директории&lt;BR&gt;C:&amp;#92;MSSQL7&amp;#92;Data теперь&lt;BR&gt;наХОДИТСЯ файл N&lt;Drthwind.mdf&lt;BR&gt;(а не .mdb).&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/installjacija_msde/2010-02-11-413</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/installjacija_msde/2010-02-11-413</guid>
			<pubDate>Wed, 10 Feb 2010 22:02:52 GMT</pubDate>
		</item>
		<item>
			<title>Задание переменной среды PATH</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Задание переменной среды PATH&lt;BR&gt;&lt;/SPAN&gt;Для того чтобы иметь возможность использовать компилятор С# и другой ин-&lt;BR&gt;струментарий .NET из командной строки Windows, необходимо убедиться в том,&lt;BR&gt;что переменная среды PATH соответствующим образом изменена. В командной&lt;BR&gt;строке поиск файлов осуществляется в рамках текущей директории; если же воз-&lt;BR&gt;никает необходимость запустить файл из какой-либо другой директории, то для&lt;BR&gt;этого требуется задать информацию, где именно Windows следует искать требуе-&lt;BR&gt;мый файл. Это может быть сделано с помощью переменной среды PATH. В ней со-&lt;BR&gt;держится список имен директорий, разделенных точкой с запятой, где Windows&lt;BR&gt;будет осуществлять поиск запрашиваемого файла, если его не удается обнаружить&lt;BR&gt;в текущей директории. Необходимо добавить в эту переменную информацию о двух&lt;BR&gt;папках, для того чтобы система Windows могла отыскать все инструменты .NET;&lt;BR&gt;ОДНа ИЗ Н И Х — ЭТО C:&amp;#92;Program Files&amp;#92;Microsoft.Net&amp;#92;Fr...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Задание переменной среды PATH&lt;BR&gt;&lt;/SPAN&gt;Для того чтобы иметь возможность использовать компилятор С# и другой ин-&lt;BR&gt;струментарий .NET из командной строки Windows, необходимо убедиться в том,&lt;BR&gt;что переменная среды PATH соответствующим образом изменена. В командной&lt;BR&gt;строке поиск файлов осуществляется в рамках текущей директории; если же воз-&lt;BR&gt;никает необходимость запустить файл из какой-либо другой директории, то для&lt;BR&gt;этого требуется задать информацию, где именно Windows следует искать требуе-&lt;BR&gt;мый файл. Это может быть сделано с помощью переменной среды PATH. В ней со-&lt;BR&gt;держится список имен директорий, разделенных точкой с запятой, где Windows&lt;BR&gt;будет осуществлять поиск запрашиваемого файла, если его не удается обнаружить&lt;BR&gt;в текущей директории. Необходимо добавить в эту переменную информацию о двух&lt;BR&gt;папках, для того чтобы система Windows могла отыскать все инструменты .NET;&lt;BR&gt;ОДНа ИЗ Н И Х — ЭТО C:&amp;#92;Program Files&amp;#92;Microsoft.Net&amp;#92;FrameworkSDK&amp;#92;Bin, В которой&lt;BR&gt;находится часть инструментов .NET, используемых из командной строки, такие на-&lt;BR&gt;пример, как ildasm, gacutil И sn; а вторая — ЭТО папка C:&amp;#92;WINNT&amp;#92;Microsoft.Net&amp;#92;&lt;BR&gt;Framework&amp;#92;vi.0.2914 (цифры в имени последней поддиректории могут варьиро-&lt;BR&gt;ваться в зависимости от того, какая конкретно версия .NET Framework инсталли-&lt;BR&gt;рована на вашей машине), именно в ней расположен собственно компилятор С#&lt;BR&gt;(esc), а также библиотека классов system.&lt;BR&gt;~— -&lt;BR&gt;• Genefti.i N«Nwwfci&lt;fc««ric4tc«| 4*-d-wcj U seriates&lt;BR&gt;; ; : . . ••.•;. •&lt;BR&gt;&amp;pound; r « « - « r r ^ V &amp;amp; A f c ! t j - --••&lt;BR&gt;Windows 2000/XP&lt;BR&gt;Чтобы задать переменную PATH на компьютере, работающем&lt;BR&gt;под Windows 2000 или ХР, откройте окно System в Control&lt;BR&gt;Panel и щелкните на вкладке Advanced (см. рис. слева).&lt;BR&gt;f ^ ^ ^ f f i - &apos; 1 JJ-Si&lt;BR&gt;Перейдите на вкладку Advanced, щелкните мышью на&lt;BR&gt;кнопке Environment Variables... и прокрутите окно со списком&lt;BR&gt;System variables до переменной Path (см. рис. справа).&lt;BR&gt;f&apos;= ГИ2ХТ&lt;BR&gt;PRQCE5SORJO.&amp;gt;,&lt;BR&gt;COM -&lt;BR&gt;&apos; -,.,;&amp;gt;&lt;BR&gt;At.;.i&amp;gt; O;,VSS;.V&lt;BR&gt;?, uenu-:... j*J&lt;BR&gt;848 Приложение А&lt;BR&gt;tdit System Variable&lt;BR&gt;Variable Wamei&lt;BR&gt;Variable Value:&lt;BR&gt;Path&lt;BR&gt;I ram Ftbs&amp;#92;Microsoft.Net&amp;#92;FrameworkSDK&amp;#92;Bin&lt;BR&gt;OK Cancel&lt;BR&gt;Выберите ее и щелкните мышью на&lt;BR&gt;кнопке Edit..., которая расположена под&lt;BR&gt;окном со списком.&lt;BR&gt;Введите в окно Variable Value пол-&lt;BR&gt;ный путь к директориям, которые вы&lt;BR&gt;хотите добавить в конец списка дирек-&lt;BR&gt;торий, хранящегося в переменной сре-&lt;BR&gt;ды PATH, как показано на рисунке слева.&lt;BR&gt;Переменная PATH представляет собой&lt;BR&gt;разделенный точками с запятой список,&lt;BR&gt;поэтому требуется включить одну точку с запятой перед названием первого пути,&lt;BR&gt;а вторую — между названиями двух путей. Например, для современной версии&lt;BR&gt;.NET Framework требуется добавить к концу строки следующий текст:&lt;BR&gt;;C:&amp;#92;Program Files&amp;#92;Microsoft.Net&amp;#92;FrameworkSDK&amp;#92;Bin;C:&amp;#92;WINNT&amp;#92;&lt;BR&gt;Microsoft.Net&amp;#92;Framework&amp;#92;vl.0.2914&lt;BR&gt;Чтобы закрыть диалог Edit System Variable, щелкните мышью на кнопке OK,&lt;BR&gt;а затем щелкните еще два раза для закрытия диалогов Environment Variables&lt;BR&gt;и System Properties. После этого изменения будут сохранены в переменной PATH.&lt;BR&gt;Если вы ранее открыли окно командной строки, то придется закрыть и открыть его&lt;BR&gt;заново, поскольку новое значение недоступно для уже существующих окон.&lt;BR&gt;W i n d o w s NT&lt;BR&gt;В задании значения переменных среды под Windows NT4&lt;BR&gt;существует несколько незначительных отличий. Откройте&lt;BR&gt;диалоговое окно System из Control Panel точно так же,&lt;BR&gt;как в Windows 2000, а затем щелкните мышью на вкладке&lt;BR&gt;Environment (см. рис. справа).&lt;BR&gt;Выберите переменную Path из окна со списком System&lt;BR&gt;Variables. Текущее значение этой переменной появится&lt;BR&gt;в окне со списком Value; добавьте необходимые для .NET&lt;BR&gt;Framework значения пути в конец записи точно так же,&lt;BR&gt;как и для Windows 2000 (также разделенные точкой с за-&lt;BR&gt;пятой). Щелкните мышью на кнопке Set для обновления&lt;BR&gt;имеющегося значения, а для его сохранения — на кнопке&lt;BR&gt;ОК. Теперь новое значение будет доступно для всех вновь&lt;BR&gt;открываемых окон.&lt;BR&gt;OS&lt;BR&gt;1 PA*hiA7&lt;BR&gt;IMP&lt;BR&gt;1 и&lt;BR&gt;.;. •;:•;.•*•.•:•?&lt;BR&gt;шшааетв-1&lt;BR&gt;jd&lt;BR&gt;_jg_j _gi^J&lt;BR&gt;Owed j ;&apos; •=:.; 1&lt;BR&gt;Windows 95/98/ME&lt;BR&gt;Если вы используете Windows 9x или Windows ME, то, чтобы изменить значе-&lt;BR&gt;ние переменной PATH, требуется модифицировать текстовый файл autoexec.bat.&lt;BR&gt;Этот файл содержит информацию, используемую для конфигурирования Windows&lt;BR&gt;в момент ее запуска, и располагается в корневой директории жесткого диска&lt;BR&gt;(например, C:&amp;#92;autoexec.bat). Откройте файл в редакторе Notepad или любом дру-&lt;BR&gt;гом текстовом редакторе и добавьте следующую строку:&lt;BR&gt;SET РАТН=%РАТН%;С:&amp;#92;Windows&amp;#92;Microsoft.NET&amp;#92;Framework&amp;#92;vl.0.2914&lt;BR&gt;Задание переменной среды PATH __ 849&lt;BR&gt;В данном случае нужно привести значение пути в соответствие с используемой&lt;BR&gt;системой и версией .NET Framework. Введенный путь будет добавлен к существу-&lt;BR&gt;ющей переменной PATH. Обратите внимание на то, что на машинах, работающих&lt;BR&gt;под управлением Windows 9x или Windows ME, будут инсталлированы не все инст-&lt;BR&gt;рументы .NET Framework. В завершение необходимо перезапустить Windows —&lt;BR&gt;только после этого сделанные изменения вступят в силу.&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/zadanie_peremennoj_sredy_path/2010-02-11-412</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/zadanie_peremennoj_sredy_path/2010-02-11-412</guid>
			<pubDate>Wed, 10 Feb 2010 22:02:10 GMT</pubDate>
		</item>
		<item>
			<title>Создание подписной формы для пользователя</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Создание подписной формы для пользователя&lt;BR&gt;&lt;/SPAN&gt;Все страницы, предназначенные для управления списками рассылки и подпис-&lt;BR&gt;чиками, отправки сообщений по электронной почте изменения внешнего представ-&lt;BR&gt;ления, завершены. Осталось создать подписную форму, которая позволит&lt;BR&gt;конечному пользователю подписаться на некоторый список.&lt;BR&gt;Вместо создания одной подписной формы,&lt;BR&gt;создадим страницу ASP.NET (см. рис. слева),&lt;BR&gt;которая будет автоматически генерировать&lt;BR&gt;HTML-форму для заданного списка рассылки.&lt;BR&gt;Администратор сначала выбирает список&lt;BR&gt;рассылки, для которого он собирается созда-&lt;BR&gt;вать подписную форму, потом определяет не-&lt;BR&gt;обходимость наличия полей для первого&lt;BR&gt;и последнего имени (эти поля при подписке&lt;BR&gt;не являются обязательными, поэтому форма&lt;BR&gt;вполне может без них обойтись). Создавае-&lt;BR&gt;мая форма будет иметь две кнопки, которые&lt;BR&gt;реализуют две возможности пользователя —&lt;BR&gt;подписаться и отказаться от подписки. При&lt;BR&gt;нажатии кн...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Создание подписной формы для пользователя&lt;BR&gt;&lt;/SPAN&gt;Все страницы, предназначенные для управления списками рассылки и подпис-&lt;BR&gt;чиками, отправки сообщений по электронной почте изменения внешнего представ-&lt;BR&gt;ления, завершены. Осталось создать подписную форму, которая позволит&lt;BR&gt;конечному пользователю подписаться на некоторый список.&lt;BR&gt;Вместо создания одной подписной формы,&lt;BR&gt;создадим страницу ASP.NET (см. рис. слева),&lt;BR&gt;которая будет автоматически генерировать&lt;BR&gt;HTML-форму для заданного списка рассылки.&lt;BR&gt;Администратор сначала выбирает список&lt;BR&gt;рассылки, для которого он собирается созда-&lt;BR&gt;вать подписную форму, потом определяет не-&lt;BR&gt;обходимость наличия полей для первого&lt;BR&gt;и последнего имени (эти поля при подписке&lt;BR&gt;не являются обязательными, поэтому форма&lt;BR&gt;вполне может без них обойтись). Создавае-&lt;BR&gt;мая форма будет иметь две кнопки, которые&lt;BR&gt;реализуют две возможности пользователя —&lt;BR&gt;подписаться и отказаться от подписки. При&lt;BR&gt;нажатии кнопки Create генерируется HTML-&lt;BR&gt;код, который помещается в расположенное&lt;BR&gt;в нижней части страницы текстовое окно,&lt;BR&gt;а сама форма выводится в центре страницы&lt;BR&gt;для предварительного просмотра. В этот мо-&lt;BR&gt;мент у администратора есть возможность&lt;BR&gt;скопировать сгенерированный HTML и пере-&lt;BR&gt;нести его в произвольную страницу.&lt;BR&gt;• - . &apos; • &apos; . .&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 837&lt;BR&gt;Страница FormWizard.aspx&lt;BR&gt;Первая часть страницы, в которой находятся раскрывающийся список и тексто-&lt;BR&gt;вые окна, строится как обычно, с выравниванием всех управляющих элементов&lt;BR&gt;при помощи таблицы. Вторая часть таблицы, которая располагается на приведен-&lt;BR&gt;ном выше рисунке за надписью &quot;Result Form:&quot;(полученная форма), по умолчанию&lt;BR&gt;является невидимой и выводится, только когда пользователь нажимает кнопку&lt;BR&gt;Create. Поскольку код этой страницы почти целиком состоит из управляющих эле-&lt;BR&gt;ментов ASP.NET, с аналогами которых мы уже встречались ранее, этот код здесь&lt;BR&gt;не приводится.&lt;BR&gt;Код поддержки для страницы FormWizard.aspx&lt;BR&gt;Код поддержки для этой страницы производит обращение к базе данных для&lt;BR&gt;заполнения раскрывающегося списка имеющимися в наличии списками рассылки,&lt;BR&gt;а также извлекает URL страницы Subscribers.aspx из таблицы settings. Осталь-&lt;BR&gt;ная часть программы занимается созданием HTML-текста для формы с учетом&lt;BR&gt;выбранных опций. Обработчик событий create_ciick() создает HTML-строку,&lt;BR&gt;содержимое которой определяется в зависимости от опций, выбранных админист-&lt;BR&gt;ратором в верхней части формы. Поскольку в этом коде не содержится чего-либо&lt;BR&gt;нового или интересного, мы этот код воспроизводить не будем.&lt;BR&gt;HTML-КОД, СОЗДанНЫЙ Обработчиком событий Create_Click() , ВЫВОДИТСЯ&lt;BR&gt;в управляющем элементе Label с именем ResuitForm, что позволяет пользователю&lt;BR&gt;осуществлять предварительный просмотр результатов своей работы. Получаемый&lt;BR&gt;HTML не является законченным, поскольку в качестве корне-&lt;BR&gt;вого элемента в нем присутствует тег &lt;form&amp;gt;, но при необхо-&lt;BR&gt;димости его можно легко скопировать из текстового окна&lt;BR&gt;в отдельный файл.&lt;BR&gt;На рисунке слева можно увидеть некоторые тестовые фор-&lt;BR&gt;мы, сгенерированные с использованием данной страницы.&lt;BR&gt;Первая из представленных выше форм, была создана без ис-&lt;BR&gt;пользования всех трех возможных опций, вторая — с исполь-&lt;BR&gt;зованием двух первых опций (запрос первого и последнего&lt;BR&gt;имени), а третья форма создавалась с использованием всех&lt;BR&gt;трех имеющихся возможностей.&lt;BR&gt;Совершенно очевидно, что, поскольку создаваемый код&lt;BR&gt;представляет собой обычный HTML, есть возможность видо-&lt;BR&gt;изменять получаемый результат по своему усмотрению: на-&lt;BR&gt;пример, изменить цвет, шрифт, ширину текстовых окон,&lt;BR&gt;использовать определенный рисунок для границ или фона или&lt;BR&gt;вывести комментарии, позволяющие пользователю получить&lt;BR&gt;дополнительную информацию относительно списка, на кото-&lt;BR&gt;рый он подписывается. Очень полезным представляется ис-&lt;BR&gt;пользование функции на JavaScript, которая позволяет перед&lt;BR&gt;фактической отправкой формы убедиться в том, что поле, со-&lt;BR&gt;держащее адрес электронной почты, не является пустым.&lt;BR&gt;Подписка на список рассылки&lt;BR&gt;До этого момента мы смотрели на приложение с точки зрения администратора,&lt;BR&gt;а как быть с конечным пользователем? Посетитель зашел на наш web-сайт и ре-&lt;BR&gt;шил подписаться на какой-либо список рассылки, но каким образом он может это&lt;BR&gt;: . Pi* Zi&amp;#92; V«w Fev«&amp;pound;e» Tcr« н?&apos;р&lt;BR&gt;i&lt;BR&gt;^ «.&lt;BR&gt;Subfnjt j&lt;BR&gt;MufCQ ^ . Д&lt;BR&gt;J&lt;BR&gt;838 Практический пример&lt;BR&gt;осуществить? Именно это мы сейчас и продемонстрируем. Страница с подписной&lt;BR&gt;формой может находится где угодно, даже на другом сервере, поскольку она ука-&lt;BR&gt;зывает на ПОЛНЫЙ URL Страницы Subscribe.aspx.&lt;BR&gt;Настала пора протестировать одну из подписных форм, представленных на&lt;BR&gt;странице, которая изображена на предшествующем рисунке и которая позволяет&lt;BR&gt;регистрировать новых подписчиков. Мы будем заполнять третью из форм, пока-&lt;BR&gt;занных на рисунке. Если на странице администратора выбрана установка Send&lt;BR&gt;Subscription Email (отправить сообщение о подписке), что происходит по умолча-&lt;BR&gt;нию, если вы используете включенный в состав программного обеспечения файл&lt;BR&gt;с установками, то подписчик получит по электронной почте сообщение с подтвер-&lt;BR&gt;ждением, содержащее информацию, заданную им самим:&lt;BR&gt;&amp;amp; Welcome to the тсЖпг* list &amp;euro;#&lt;BR&gt;ь&lt;BR&gt;Reply . Reply All Forward Юг* Delete Previous&lt;BR&gt;from: NewsMallcr Team&lt;BR&gt;Date: Sunday, ЛиЕу 15, 2001 7:52 PM&lt;BR&gt;To; mbelllna$o#vb2themcis.com&lt;BR&gt;Добро пожаловать в список рассылки С#, дорогой Марко Бе/шииазо*&lt;BR&gt;ДЛЯ отказа от подписки щелкните мышью на следующей ссылке:&lt;BR&gt;••g-.com&lt;BR&gt;1 1 1 я&lt;BR&gt;Последняя строка этого сообщения представляет собой ссылку, которая, в слу-&lt;BR&gt;чае если ее нажать, удалит данного подписчика из списка рассылки. Эта ссылка&lt;BR&gt;создается динамически из приведенной ниже строки посредством замены тегов на&lt;BR&gt;соответствующие значения, извлеченные из XML-файла:&lt;BR&gt;#SubscriberURL#?ListID=#ListID#&amp;amp;Action=Unsubscribe&amp;amp;Email=#SubscriberEmaiI#&lt;BR&gt;Параметр Action отличает подписку от отказа от подписки. В данном случае&lt;BR&gt;ему присваивается значение unsubscribe. Ссылка ддя осуществления подписки&lt;BR&gt;представляет собой точно такую же строку, но не содержащую параметра Action,&lt;BR&gt;или содержащую параметр Action, которому в качестве значения присваивается&lt;BR&gt;произвольная строка (только не unsubscribe). Остальные параметры, входящие&lt;BR&gt;в ссылку,— это идентификатор списка рассылки (который хранится в форме&lt;BR&gt;в скрытом поле) и адрес электронной почты подписчика.&lt;BR&gt;Сообщение о подтверждении посылается по электронной почте, только если есть&lt;BR&gt;соответствующая установка. Вы, однако, всегда будете получать web-страницу&lt;BR&gt;с подтверждением, в которой содержится тот же самый текст, что и в сообщении.&lt;BR&gt;Процедура отказа от подписки аналогична: администратор определяет, должно ли&lt;BR&gt;посылаться подтверждение, но на сайте в любом случае выводится соответствую-&lt;BR&gt;щая web-страница. Чтобы протестировать выполнение этой операции, откройте&lt;BR&gt;ссылку, присутствующую в предыдущем сообщении, это приведет к открытию бра-&lt;BR&gt;узера и выводу сообщения, представленного на рисунке на стр. 839.&lt;BR&gt;Вы получите точно такой же результат, если выберете опцию unsubscribe&lt;BR&gt;(отказ от подписки) в HTML-форме. У администратора есть также возможность&lt;BR&gt;добавлять или удалять подписчика с помощью страницы subscribers.aspx.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 839&lt;BR&gt;NewsMatter; Subscription - Microsoft Internet Explorer&lt;BR&gt;•As&lt;BR&gt;.a^px?listiD«38^cbcf^Unsub$ab^&amp;pound;md^&lt;BR&gt;До свидания» С#&lt;BR&gt;8ы исключены из списка рассылки С#. Почему вы приняли такое решение???&lt;BR&gt;~гг&lt;BR&gt;Страница Subscribe.aspx&lt;BR&gt;Код, предназначенный для создания этой страницы, является наиболее корот-&lt;BR&gt;ким из всех встречавшихся нам в этой главе:&lt;BR&gt;&lt;body&amp;gt; :.&lt;BR&gt;&lt;азр:Label ID=&quot;Subject&quot; runat-&quot;Server&quot; ,&lt;BR&gt;CssClass=&quot;SubscrSubject:i Visible^&quot;false&quot; /&amp;gt;&lt;BR&gt;&lt;asp:Label ID=&quot;Message&quot; runat-&quot;Server&quot;&lt;BR&gt;CssClass=&quot;SubscrMessage&quot; Visible^&quot;false&quot; /&amp;gt;&lt;BR&gt;&lt;asp:Label runat = &quot;server&quot; ID=&quot;EmailRequired&quot; Visible^&quot;false&quot;&lt;BR&gt;Text=&quot;The Email address is required&quot; Cless=Error&quot; /&amp;gt;&lt;BR&gt;&lt;/body&amp;gt;&lt;BR&gt;На странице присутствует три надписи: для подтверждения, для тела сообще-&lt;BR&gt;ния и для сообщения об ошибке, если не задан адрес электронной почты. Все эти&lt;BR&gt;надписи по умолчанию являются невидимыми. Они выводятся, только после того&lt;BR&gt;как пользователь выполняет операцию подписки или отказа от подписки и в соот-&lt;BR&gt;ветствии с ее результатом.&lt;BR&gt;Код поддержки для Subscribe.aspx&lt;BR&gt;Весь код данного класса поддержки помещен в процедуру Page_Load(), поско-&lt;BR&gt;льку все операции выполняются в момент загрузки страницы и на ней не сущест-&lt;BR&gt;вует каких-либо форм или управляющих элементов, которые приводят&lt;BR&gt;к наступлению других событий. Код для данного обработчика событий приводится&lt;BR&gt;ниже полностью:&lt;BR&gt;protected void Page__Load(object sender,EventArgs e)&lt;BR&gt;.; :•.:;.• , • i n t S u b s c r l D ; .-. . . . : .. ..• . • • :&lt;BR&gt;bool SendEmail;&lt;BR&gt;// считать ListID, FirstName, LastName, Email and Action&lt;BR&gt;//из QueryString, сгенерированной формой HTML&lt;BR&gt;int ListID = int.Parse(Request.Params[&quot;ListID*]); ;&lt;BR&gt;string FirstName = Request .Params [* FirstName•] + &apos; &quot; ;&lt;BR&gt;string LastName = Request.Params[^LastName&quot;] + &quot; &quot;] ;&lt;BR&gt;string Email = Request.Parains [&apos;Email&apos;] + * &apos;] ; ::&lt;BR&gt;string Action = Request.Params[&quot;Action&quot;] + • *;&lt;BR&gt;if (Email.Trim()=-&quot;&quot;)&lt;BR&gt;// если объект Email не был определен,&lt;BR&gt;// вывести сообщение об ошибке и завершить работу&lt;BR&gt;EmailRequired.Visible = true;&lt;BR&gt;e l s e : &quot; .&apos; • • &apos; :••&quot; •• •••••••:&apos;-&apos;;: • : • • • &apos;••• : &apos; &apos; &apos;&lt;BR&gt;{ . &apos;• • ^ . Щ : Ш$Щ&lt;BR&gt;string SubjectText;&lt;BR&gt;string MessageText; . : &quot; ;&lt;BR&gt;840 Практический пример&lt;BR&gt;// создать объекты для работы с установками и с подписчиком&lt;BR&gt;NewsMailer.AppSettings settings =&lt;BR&gt;. NewsMailer«AppConfig.GetSettings{&lt;BR&gt;. , Server.MapPath{GetSettingsFile()});&lt;BR&gt;NewsMailer.SubscribersDB subscribers - new&lt;BR&gt;NewsMailer.SubscribersDB(GetConnString());&lt;BR&gt;// лишение подписки&lt;BR&gt;if (Action.CompareTo (&quot;Unsubscribe&quot; }—0) ;&lt;BR&gt;{&lt;BR&gt;// считать сообщение от подписчика&lt;BR&gt;//и проверить, требуется ли подтверждающий ответ по Email&lt;BR&gt;SendEmail - settings.SendUnSubscrSmail;&lt;BR&gt;SubjectText = settings.UnsubscrSubjееt;&lt;BR&gt;MessageText = settings.UnSubscrMessage;&lt;BR&gt;// считать ID этого подписчика из Email&lt;BR&gt;SubccrlD - subscribers.GetSubscrID(ListID/ Email);&lt;BR&gt;// заменить теги этого подписчика&lt;BR&gt;MessageText = NewsMailer,Utilities.ProcessSubscriberTags(&lt;BR&gt;MessageText, GetConnString(), SubscrlD);&lt;BR&gt;. ••// вычеркнуть подписчика :&lt;BR&gt;subscribers.Delete{SubscrlD); •&lt;BR&gt;} :, •&lt;BR&gt;else //оформить подписку&lt;BR&gt;{ &apos; • •;..;.;.&lt;BR&gt;• &apos; // считать сообщение от подписчика&lt;BR&gt;// и проверить, требуется ли подтверждающий ответ по Email&lt;BR&gt;SendEmail = settings.SendSubscrEmail;&lt;BR&gt;SubjectText = settings.SubscrSubject;&lt;BR&gt;MessageText. = settings. SubscrMessage;&lt;BR&gt;••;: // добавить подписчика&lt;BR&gt;subscribers.Add(ListID, FirstName, LastName, Email);&lt;BR&gt;// получить ID только что зарегистрированного подписчика&lt;BR&gt;// или, если подписчик уже зарегистрирован&lt;BR&gt;// с известным Email адресом&lt;BR&gt;SubscrlD - subscribers.GetSubscrlD(ListID, Email);&lt;BR&gt;//заменить теги нового подписчика&lt;BR&gt;MessageText = NewsMailer.Utilities.ProcessSubscriberTags(&lt;BR&gt;MessageText, GetConnString(), SubscrlD);&lt;BR&gt;::-:::&amp;gt; } .. .Л--&lt;BR&gt;// заменить теги по установке и в списке&lt;BR&gt;SubjectText = NewsMailer.Utilities.ProcessListTags(&lt;BR&gt;SubjectText, GetConnString(), ListID);&lt;BR&gt;MessageText = NewsMailer.Utilities,ProcessListTags(&lt;BR&gt;MessageText, GetConnString(), ListID);&lt;BR&gt;MessageText = NewsMailer.Utilities.ProcessSettingsTags (&lt;BR&gt;MessageText, GetConnString());&lt;BR&gt;// если требуется подтверждающий ответ&lt;BR&gt;••:•: : if (SendEmail)&lt;BR&gt;{ &apos;:: .&lt;BR&gt;// создание нового сообщения&lt;BR&gt;MailMessage MailMsg = new MailMessageO ;&lt;BR&gt;MailMsg.From = settings .SenderName + • &lt;&quot; +&lt;BR&gt;; Settings -.Sender Email + &quot;&amp;gt;&quot;;&lt;BR&gt;// заполнение поля &quot;Кому&quot; в Email&lt;BR&gt;M a i l M s g . Т о = E m a i l ; .:••••••..•.,•:... ..:..,•••• •••...-.... •.,.,,:.:::; •,•;.,,:; . x , - . • ,..,: .,&lt;BR&gt;// заполнение поля &quot;Содержание&quot;,&lt;BR&gt;//созданного для случая подтверждения&lt;BR&gt;MailMsg.Subject -SubjectText;&lt;BR&gt;MailMsg.Body = MessageText;&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 841&lt;BR&gt;/7 отсылка сообщения&lt;BR&gt;S m t p M a i l . S e n d ( M a i l M s g ) ; . • -.&lt;BR&gt;v-:• ) S : : : ; Ж , :•; •;• •I)&apos;ЖЙ•&apos; •?• ^ :&amp;gt;:• ••;...:;.&apos;&apos;;;:U&amp;gt;&apos;/% J &amp;#92; ш • &apos;^МЖ^^ •• ••/•:• *ШШ^• • • &apos;:• Ш&quot;&apos;&apos; • • •&apos;• V. -: • . - •.&quot;. :,&lt;BR&gt;// вывод сообщения, подтверждающего выполненное действие&lt;BR&gt;•;•;••::•••••., . Subject.Text = SubjectText;&lt;BR&gt;Message.Text - Message-Text;&lt;BR&gt;Subject .Visible = true; . . . • :. &apos; •&lt;BR&gt;Message,Visible = true;&lt;BR&gt;) • • ; • • • &apos; • Ш&lt;BR&gt;В первых строках кода из строки запроса извлекаются идентификатор требуе-&lt;BR&gt;мого списка, имя подписчика и его адрес и переносятся в локальные переменные,&lt;BR&gt;с тем чтобы их было проще использовать в данной процедуре в дальнейшем.&lt;BR&gt;Прежде, чем переходить к выполнению дальнейших операций, программа выпол-&lt;BR&gt;няет проверку, не является ли параметр с адресом электронной почты пустым,&lt;BR&gt;и если является, то на экран выводится надпись об ошибке EmaiiRequired (адрес&lt;BR&gt;электронной почты необходим), а остальная часть процедуры не выполняется.&lt;BR&gt;Если адрес электронной почты присутствует, а параметр Action имеет значение&lt;BR&gt;unsubscribe, то программа сначала задает предмет сообщения и текст подтверж-&lt;BR&gt;дения и заменяет специальные теги на информацию о конкретном подписчике,&lt;BR&gt;а затем удаляет информацию о данном подписчике из базы данных. В противном&lt;BR&gt;случае информация о подписчике сначала добавляется в базу данных, а затем&lt;BR&gt;происходит замена тегов. Замена тегов осуществляется после, поскольку методу&lt;BR&gt;utilities.ProcessSubscriberTagsо требуется передать в качестве параметра&lt;BR&gt;идентификатор подписчика, следовательно, информация о новом подписчике сна-&lt;BR&gt;чала должна быть занесена в БД. После этого производится замена специальных&lt;BR&gt;тегов, касающихся списка рассылки и установок, которая является необходимой&lt;BR&gt;независимо от того, подписывается ли пользователь или производит отказ от под-&lt;BR&gt;писки. Если в файле установок хранится информация о том, что требуется отпра-&lt;BR&gt;вить по электронной почте сообщение с подтверждением (состоящее из предмета&lt;BR&gt;сообщения и тела сообщения), то процедура отправляет такое сообщение.&lt;BR&gt;Обеспечение безопасности приложения&lt;BR&gt;К настоящему моменту мы полностью реализовали функциональные возможно-&lt;BR&gt;сти приложения: произведено тестирование программы как со стороны админист-&lt;BR&gt;ратора, так и со стороны конечного пользователя — все работает замечательно.&lt;BR&gt;Осталось обеспечить безопасность. Если не предусмотреть какой-либо либо про-&lt;BR&gt;цедуры регистрации, управляющей доступом к страницам администратора, то это&lt;BR&gt;приведет к тому, что каждый пользователь сможет проникнуть туда и получить&lt;BR&gt;информацию об адресах электронной почты подписчиков, послать фиктивные со-&lt;BR&gt;общения по электронной почте, уничтожить списки рассылки и т. д. При создании&lt;BR&gt;любого общедоступного web-приложения обеспечение безопасности должно быть&lt;BR&gt;одной из самых первых вещей, которые принимаются во внимание на стадии раз-&lt;BR&gt;работки. Однако для небольших приложений, подобных создаваемому нами, обес-&lt;BR&gt;печение безопасности и аутентификация пользователей может быть реализована&lt;BR&gt;в качестве завершающего этапа разработки — без каких-либо проблем и с потря-&lt;BR&gt;сающей легкостью.&lt;BR&gt;842 Практический пример&lt;BR&gt;Установки для обеспечения безопасности&lt;BR&gt;в файле web.config&lt;BR&gt;Впервые мы столкнулись с файлом web.config, когда обсуждали вопрос о хра-&lt;BR&gt;нении строки соединения. Этот файл конфигурации может быть использован так-&lt;BR&gt;же для хранения установок web-страниц, управления состоянием сеанса, приложения&lt;BR&gt;(как например, включенных нами строк connstring и settingsFile), трассировки,&lt;BR&gt;компиляции, обеспечения безопасности и для многого другого. Этот файл оказы-&lt;BR&gt;вается очень полезным, поскольку он позволяет переопределять установки IIS.&lt;BR&gt;Мы планируем рассмотреть хранящиеся в этом файле установки для обеспечения&lt;BR&gt;безопасности. ASP.NET. Названный файл установок предоставляет простой спо-&lt;BR&gt;соб реализовать гибкую систему аутентификации пользователей (в результате чего&lt;BR&gt;пользователю будет либо разрешен, либо запрещен доступ к сайту) и систему&lt;BR&gt;определения полномочий (которая либо предоставляет какие-либо права, либо&lt;BR&gt;отбирает их у пользователей). Основная часть работы выполняется в следующих&lt;BR&gt;строках программы:&lt;BR&gt;&lt;configuration&amp;gt; . . &amp;#92;&lt;BR&gt;&lt;system.web&amp;gt; •&apos;•&apos;••.&lt;BR&gt;: v &lt;authentication mode=&quot;Forms&quot;&amp;gt; : . • :•&lt;BR&gt;&lt;forms name=&quot; .NEWSMAILER&quot; loginUr 1=11 Login.aspx&quot;&lt;BR&gt;protection=nAllB timeout=&quot;60&quot;&amp;gt;&lt;BR&gt;&apos; . &lt;credentials passwordFormat=&quot;Clear&quot; &amp;gt;&lt;BR&gt;&lt;user пате=яAdmin&quot; password=&quot;AdminOKll/&amp;gt;&lt;BR&gt;&lt;user name-&quot;Marco&quot; password-&quot;MarcoOK&quot;/&amp;gt;&lt;BR&gt;• •• • • : • •• &lt; / c r e d e n t i a l s &amp;gt; •:. : • . .: ,. - . •• &apos; ; • ;• Щ&lt;BR&gt;&lt;/forms&amp;gt;&lt;BR&gt;&lt;/authentication&amp;gt; . ;&lt;BR&gt;• ,. &lt;authorization&amp;gt;&lt;BR&gt;&apos; &apos; &apos; &lt;deny u s e r s - &quot; ? &quot; /&amp;gt; .: . . &apos; •• . , : • , - •. •&lt;BR&gt;••-.:•. •:•.:•:••/. : &apos; .:•..•. •/• &lt; / a U t h o r i Z a t i o n &amp;gt; . • • •• &quot; ••.••.: • &apos; &apos;: •• • : • &amp;#92;. : ../:&apos;:&apos;.. .&apos;••&apos;. . • .-:&apos;.::&lt;BR&gt;&lt;/system.web&amp;gt;&lt;BR&gt;&lt;appSettings&amp;gt;&lt;BR&gt;&lt;add key=&quot;connstring• value=&quot;Provider=Microsoft.Jet.OLEDB.4.0;&lt;BR&gt;Data source=E:&amp;#92;Projects&amp;#92;NewsMailer&amp;#92;DB&amp;#92;NewsMailer.mdb&quot; /&amp;gt;&lt;BR&gt;&lt;/appsettings&amp;gt;&lt;BR&gt;• &lt;/configuration&amp;gt; : . &apos;••;&apos;•••;. &quot; : &apos; . : : &quot; • : , . &apos; • • , • : . : • , - • • &apos; . / &apos; , &apos; . &apos; ; . / &apos; • . - &amp;#92; ; . ^ • : - &apos; . - &apos; : &apos; : . &apos; w - &amp;#92; - &apos;•;-: &amp;#92; y &apos; . •••,•••..••: •• : V •• - : &apos; &apos; . ? . : - : - : - -&lt;BR&gt;Выполнение аутентификации в режиме Forms означает, что для регистрации&lt;BR&gt;будет использоваться web-форма (в качестве альтернативных вариантов можно&lt;BR&gt;указать систему HTTP Basic или систему Microsoft Passport). Строки программы,&lt;BR&gt;расположенные внутри раздела &lt;authentication&amp;gt;, определяют URL страницы ре-&lt;BR&gt;гистрации, на которую пользователи будут отправляться, если они не пройдут про-&lt;BR&gt;цедуру аутентификации при попытке доступа к закрытым страницам. Для хранения&lt;BR&gt;информации о регистрации и о полномочиях пользователей, которым разрешен&lt;BR&gt;доступ к сайту, используется куки (.NEWSMAILER). ДЛЯ нашего простого примера&lt;BR&gt;мы храним полномочия в виде комбинаций имени пользователя — пароля. В за-&lt;BR&gt;вершение тег &lt;deny users=n?&quot; /&amp;gt;, расположенный внутри раздела &lt;authorization&amp;gt;&lt;BR&gt;определяет, что анонимным пользователям запрещается входить в закрытую часть&lt;BR&gt;приложения.&lt;BR&gt;Обеспечение безопасности в ASP.NET может быть намного более сложным&lt;BR&gt;и профессиональным — это всего лишь пример основ системы аутентификации&lt;BR&gt;пользователей и определения полномочий. Если вы собираетесь пользоваться&lt;BR&gt;файлом web.config, то у вас также появляется возможность зашифровывать&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 843&lt;BR&gt;пароли с помощью Triple DES. Другая возможность заключается в том, чтобы&lt;BR&gt;либо хранить имена пользователей и пароли в таблице базы данных и использо-&lt;BR&gt;вать собственную функцию для проверки правильности регистрационной информа-&lt;BR&gt;ции, переданной пользователем, либо проверять пользователей по Windows Active&lt;BR&gt;Directory. Все это, однако, выходит за рамки настоящего раздела. Более подроб-&lt;BR&gt;ную информацию вы сможете почерпнуть в документации .NET Framework SDK&lt;BR&gt;или в книге &quot;ASP.NET для профессионалов&quot; (&quot;Professional ASP.NET&quot;), выходящей&lt;BR&gt;в издательстве &quot;Лори&quot; в 2004 г.&lt;BR&gt;Файл Login.aspx и его код поддержки&lt;BR&gt;Теперь нам необходимо создать&lt;BR&gt;Страницу Login.aspx, КОТОрая&lt;BR&gt;в законченном виде выглядит так,&lt;BR&gt;как показано на рисунке справа.&lt;BR&gt;Код, необходимый для создания&lt;BR&gt;страницы, не представляет из себя&lt;BR&gt;ничего особенного — для других&lt;BR&gt;страниц нам уже приходилось пи-&lt;BR&gt;сать более сложные программы,&lt;BR&gt;поэтому сразу перейдем непосред-&lt;BR&gt;ственно к коду, ответственному за&lt;BR&gt;обработку нажатия кнопки Login:&lt;BR&gt;ЭкетМ*&lt;BR&gt;******* T&lt;sd$ нф&lt;BR&gt;——&lt;BR&gt;&amp;gt; ~ i , &apos; &apos;,,, &apos;•- &apos; г &apos;%&apos;., .&quot;( &lt; • , &apos;I-V ,н • &amp;gt;&amp;gt;г&apos; ,&apos;, J ; ¥&lt;-,&lt;&lt;BR&gt;L o g i n P a y t &apos; j&lt;BR&gt;I- ц и ti- JM «;И.&lt;BR&gt;&amp;amp; Po;&apos;5is*&apos;?nt Login&lt;BR&gt;protected void LoginUser_Click (object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;//проверка имени и пароля данного пользователя&lt;BR&gt;if (FormatAuthentication.Authenticate(UserName.Text, Password&lt;BR&gt;. : { &apos; &apos; •• : • . • • • . • •&apos; •. •. .. • • • - • &apos; • •:&apos;• &apos; • • . • • , • : • • • • . . • , :&lt;BR&gt;// если пользователь аутентифицирован, разрешить вход&lt;BR&gt;// (если если это требует пользователь) перейти на страницу,&lt;BR&gt;// которую требует процедура аутентификации&lt;BR&gt;FormsAuthentication, RedirectFromLoginPage(UserName.Text,&lt;BR&gt;Persistent.Checked);&lt;BR&gt;els&lt;BR&gt;•••/./• если имя пользователя или пароль неверны, вывести сообщение об ошибке&lt;BR&gt;I n v a l i d L o g i n . V i s i b l e - t r u e ; •.;:,.••••--&apos;&apos;:&apos;&apos;••:-:&apos;.,•; •&apos; :•-•&apos;; •.•:&apos;:::..&apos;.••,-. • : ; • • ; • ••:-::;-- •;,..• • : ;.•••.&lt;BR&gt;В этой программе осуществляется вызов метода AuthenticateO, который про-&lt;BR&gt;изводит проверку правильности имени пользователя и пароля. Если они не распо-&lt;BR&gt;знаны, то выводится надпись InvalidLogin, в противном случае, регистрационная&lt;BR&gt;информация записывается в куки (если в окне выбора Persistent Login установлен&lt;BR&gt;соответствующий флажок), и браузер переходит на страницу, которая необходима&lt;BR&gt;для регистрации пользователя. URL этой страницы передается в строке запроса,&lt;BR&gt;и вы можете увидеть ее в линейке с адресом на рисунке, приведенном выше: там&lt;BR&gt;ВЫВОДИТСЯ URL localhost/newsmailer/Lis-ts.aspx В закодированном виде. В ЭТОМ&lt;BR&gt;случае, если пользователь попытается загрузить некоторую страницу и не пройдет&lt;BR&gt;процедуру аутентификации, то он будет снова отправлен на страницу регистрации&lt;BR&gt;и после успешного прохождения аутентификации возвращен на исходную страницу.&lt;BR&gt;Теперь приложение выглядит вполне завершенным, однако остается еще одна&lt;BR&gt;маленькая проблема. Что произойдет, если пользователь отправит форму, для того&lt;BR&gt;844 Практический пример&lt;BR&gt;чтобы подписаться на некий список? Такой пользователь не будет аутентифициро-&lt;BR&gt;ван, поэтому он будет отправлен на страницу регистрации. Такого, естественно,&lt;BR&gt;быть не должно, и одним из возможных решений этой проблемы является перенос&lt;BR&gt;страницы Subscribe.aspx в другую папку, куда анонимный пользователь будет*&lt;BR&gt;иметь возможность загрузить требуемую страницу. Такой способ будет, конечно,&lt;BR&gt;работать, но здесь потребуется предусмотреть два файла web.config: один со стро-&lt;BR&gt;кой соединения, хранящийся в корневой папке, а второй с установками для обес-&lt;BR&gt;печения безопасности, хранящийся в закрытой папке. Существует, однако, более&lt;BR&gt;простое решение, для реализации которого требуется добавить лишь несколько&lt;BR&gt;строк в уже существующий файл web.config, и это позволит оставить страницу&lt;BR&gt;Subscribe.aspx там же, где находятся все остальные. Мы располагаем возмож-&lt;BR&gt;ностью задавать различные опции для обеспечения безопасности разных файлов&lt;BR&gt;с помощью тега &lt;iocation&amp;gt;; это означает, что можно закрыть все файлы, как мы&lt;BR&gt;делали это раньше, а затем открыть анонимным пользователям доступ только&lt;BR&gt;К странице Subscribe.aspx:&lt;BR&gt;&lt;configuration&amp;gt;&lt;BR&gt;&lt;system.web&amp;gt;&lt;BR&gt;...Code omitted for clarity&lt;BR&gt;&lt;/system.web&amp;gt;&lt;BR&gt;&lt;location path=nSubscribe.aspx&quot;&amp;gt;&lt;BR&gt;&lt;system.web&amp;gt;&lt;BR&gt;&lt;authorization&amp;gt;&lt;BR&gt;• • : •: -. &apos; :. ••••••.•••• - • • • • &apos; &apos; •• &apos; &lt; a l l O W U S e r S = &quot; * &quot; / &amp;gt; &apos;• . •••••.••••••, : •• . , . • • • : ; • • • , • . • • &apos; , •••• : .•;•••••,:• &amp;gt; v •&lt;BR&gt;&lt;/ author ization&amp;gt; • . •••••...-.:•:• ••.•&apos;•.&lt;BR&gt;• • ;••••..,-,•, • • • • &lt; / s y s t e m . w e b &amp;gt; ..•••.• . • •• • • • • • . . • • • . . .••, :. • . ,•. :, ••••:•••.•:•:• .&lt;BR&gt;&lt;/location&amp;gt;&lt;BR&gt;&lt;appSettings&amp;gt;&lt;BR&gt;&lt;add key=flconnstringn value=&quot;Provider=Microsoft. Jet .OLEDB.4 . 0;&lt;BR&gt;Data source=E:&amp;#92;Projects&amp;#92;NewsMailer&amp;#92;DB&amp;#92;NewsMailer.mdb&quot; /&amp;gt;&lt;BR&gt;&lt;/appSettings&amp;gt;&lt;BR&gt;&lt;/configuration&amp;gt;&lt;BR&gt;Теперь при отправке пользователем формы и загрузке страницы Subscribe.aspx&lt;BR&gt;ASP.NET распознает пользователей как анонимных и разрешает им доступ к этой&lt;BR&gt;странице. Если же пользователь осуществляет попытку попасть на любую другую&lt;BR&gt;страницу (возможно, узнав правильный URL этой страницы), то у него будет за-&lt;BR&gt;прошена регистрационная информация.&lt;BR&gt;И еще один момент: что необходимо предпринять, если возникает необходи-&lt;BR&gt;мость выйти из системы и уничтожить куки, в которых хранится регистрационная&lt;BR&gt;Информация? Мы ВОСПОЛЬЗуеМСЯ метОДОМ SignOutO объекта FormsAuthentication&lt;BR&gt;(который находится в пространстве имен System.web.security) — он выполняет&lt;BR&gt;именно те действия, которые нам требуются. Названный метод вызывается в про-&lt;BR&gt;цедуре Page_Load(), если в строке запроса параметру Action присваивается значе-&lt;BR&gt;ние &quot;logout&quot;:&lt;BR&gt;protected void Page_Load(object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;// если строка QueryString имеет выходной параметр, осуществите выход&lt;BR&gt;//и удалите куки для входной страницы •&lt;BR&gt;if {Request.Params[&quot;Action&quot;]==&quot;logout&quot;)&lt;BR&gt;FormsAuthentication.SignOut (); : J:&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 845&lt;BR&gt;РЯЯЯ?Ш?82&lt;»№&amp;amp;*; гh -••• -•.&lt;BR&gt;j Ш $ii References&lt;BR&gt;! .— *-Й Asse#ib{yln*o.c$&lt;BR&gt;- «Э BasePage.cs&lt;BR&gt;^ j— ||] Forfn¥sflzard.aspx&lt;BR&gt;U Header.ascx&lt;BR&gt;{ Д] Lists^spx&lt;BR&gt;I | h В NeweHttory^jpX&lt;BR&gt;K E S ?&lt;BR&gt;I I f* H Subitrsbe.aspx&lt;BR&gt;Г! г* S Subsorsbers.aspx&lt;BR&gt;| - • [Й Web.conf»g&lt;BR&gt;fj ;*?&apos;&quot; М|Л&lt;ГйД|&lt;BR&gt;: • • i&lt;BR&gt;1&lt;BR&gt;&amp;#92;&lt;BR&gt;&amp;#92;&lt;BR&gt;Страница с таким значением параметра вызывается посредством пункта меню&lt;BR&gt;Logout, который описан в пользовательском управляющем элементе Header следу-&lt;BR&gt;ющим образом:&lt;BR&gt;&lt;asp:HyperLink runat^&quot; server13&lt;BR&gt;NavigateUrl=&quot;Login.aspx?ReturnUrl=Lists.aspx&amp;amp;Action=logout&lt;BR&gt;Text=&quot;Logout&quot; Class=&quot;MenuItemi; .../&amp;gt;&lt;BR&gt;Обратите внимание на то, что в этом случае, кроме параметра *Action=iogout&quot;&lt;BR&gt;используется также и параметр Retumuri, имеющий значение Lists.aspx. Это&lt;BR&gt;оказывается необходимым, поскольку после выхода из системы мы возвращаемся&lt;BR&gt;обратно к регистрационной форме. Если администратор сразу повторно зарегист-&lt;BR&gt;рируется, то странице регистрации необходимо иметь информацию о том, на какую&lt;BR&gt;страницу необходимо перейти.&lt;BR&gt;Компиляция модуля&lt;BR&gt;Последним шагом, перед тем как приступим к тестированию&lt;BR&gt;приложения и загрузке его на web-сервер, является компиляция&lt;BR&gt;всех файлов с кодом поддержки, созданных до настоящего момен-&lt;BR&gt;та. Если вы используете VS.NET, то ваш Solution Explorer должен&lt;BR&gt;выглядеть так, как показано на рисунке слева.&lt;BR&gt;Выберите, команду Build, и VS.NET откомпилирует ваш проект,&lt;BR&gt;ПОЗабоТИВШИСЬ О ССЫЛКах На Два биЗНеС-МОДулЯ (NewsMailerConf ig&lt;BR&gt;И NewsMailerDB).&lt;BR&gt;Запуск приложения&lt;BR&gt;После того как модули откомпилированы, необходимо убедиться&lt;BR&gt;в том, что они находятся в директории bin, которая, в свою очередь,&lt;BR&gt;помещается в корневой папке web-приложения или виртуальной&lt;BR&gt;папке, создаваемой администратором IIS. Измените строку соеди-&lt;BR&gt;нения в файле web.config так, чтобы она указывала на БД Access&lt;BR&gt;(или DSN), и после этого вы готовы к тестированию программы&lt;BR&gt;в Internet Explorer. Чтобы попасть на страницу Lists, необходимо&lt;BR&gt;Отправиться ПО адресу http://localhost/newsmailer/Lists.aspx.&lt;BR&gt;Проблемы совместимости браузеров&lt;BR&gt;Все страницы указанного приложения были разработаны и протестированы&lt;BR&gt;в Internet Explorer 5.5. Если вы используете приложение совместно с Netscape б,&lt;BR&gt;то его внешнее представление будет несколько отличаться, поскольку Netscape&lt;BR&gt;интерпретирует некоторые установки таблицы стилей по-другому. При использо-&lt;BR&gt;вании более ранних версий Netscape данный сайт будет выглядеть еще хуже. Это&lt;BR&gt;составляет большую проблему для сайтов, которые должны быть доступны для&lt;BR&gt;широкой публики. В промышленных системах, когда невозможно потребовать от&lt;BR&gt;пользователей применения определенного браузера (как, например, в данном слу-&lt;BR&gt;чае — по крайней мере, в отношении администраторов), представляется важным&lt;BR&gt;разрабатывать web-страницы так, чтобы они могли работать на любом браузере.&lt;BR&gt;846 Практический пример&lt;BR&gt;Итоги&lt;BR&gt;Первое приложение ASP.NET, использующее базу данных, завершено. Главной&lt;BR&gt;целью этого практического примера было показать, насколько простым является&lt;BR&gt;написание web-приложения, как для этого можно использовать С# и что нужно&lt;BR&gt;для того, чтобы воспользоваться преимуществами, которые дает .NET Framework.&lt;BR&gt;Мы узнали, что использование серверных управляющих элементов ASP.NET по-&lt;BR&gt;зволяет запросто сэкономить на написании нескольких сотен строк кода, получив&lt;BR&gt;при этом более стройный и приятный результат.&lt;BR&gt;Настоящее приложение может использоваться прямо в таком виде для множе-&lt;BR&gt;ства web-сайтов, однако можно включить в него дополнительные возможности,&lt;BR&gt;чтобы сделать его еще более мощным! Предлагаем вам несколько идей:&lt;BR&gt;• Предусмотрите возможность создавать и работать&lt;BR&gt;с подписными формами, которые позволяют пользователю&lt;BR&gt;подписываться за один прием сразу на несколько списков рассылки,&lt;BR&gt;сообщив свой адрес электронной почты только один раз.&lt;BR&gt;• Предусмотрите возможность, позволяющую пользователю выбирать,&lt;BR&gt;хочет ли он получать новостные сообщения в виде HTML или&lt;BR&gt;обычного текста, и отправлять различные сообщения&lt;BR&gt;в соответствии с этим выбором.&lt;BR&gt;• Предусмотрите возможность отправлять вместе с новостными&lt;BR&gt;сообщениями различные приложения.&lt;BR&gt;• Предусмотрите возможность работы нескольких администраторов,&lt;BR&gt;каждый из которых обладает различными правами. Например,&lt;BR&gt;администратор базового уровня получает возможность только&lt;BR&gt;просматривать текущие списки рассылки, и информацию о подписчиках,&lt;BR&gt;администратор второго уровня может отправлять новые сообщения,&lt;BR&gt;а самый продвинутый администратор обладает полным набором прав,&lt;BR&gt;то есть возможностью добавлять, удалять и изменять списки рассылки&lt;BR&gt;и информацию о подписчиках.&lt;BR&gt;Большинство тем, рассмотренных здесь, посвящены web-разработке с исполь-&lt;BR&gt;зованием ASP.NET, но многие принципы и некоторый код (в частности, класс&lt;BR&gt;u t i l i t i e s ) могут быть также приспособлены для использования в приложениях&lt;BR&gt;Windows, например, управление вводом/выводом, объектно-ориентированная раз-&lt;BR&gt;работка, доступ к БД посредством ADO.NET и многие классы .NET Framework.&lt;BR&gt;Поэтому вы можете воспользоваться этим кодом, даже если web-программирова-&lt;BR&gt;ние не является основным объектом ваших интересов.&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/sozdanie_podpisnoj_formy_dlja_polzovatelja/2010-02-11-411</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/sozdanie_podpisnoj_formy_dlja_polzovatelja/2010-02-11-411</guid>
			<pubDate>Wed, 10 Feb 2010 22:01:35 GMT</pubDate>
		</item>
		<item>
			<title>Редактирование и обновление списков</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Редактирование и обновление списков&lt;BR&gt;&lt;/SPAN&gt;М ы переходим к реализации методов, которые осуществляют редактирование&lt;BR&gt;и обновление списков:&lt;BR&gt;protected void ListsGrid_Edit (object sender, DataGridCoiranandEventArgs e)&lt;BR&gt;{&lt;BR&gt;ShowAddNewControls(false);&lt;BR&gt;//начать редактирование&lt;BR&gt;ListsGrid.Editltemlndex = (int)e.Item.Itemlndex;&lt;BR&gt;BindGridO;&lt;BR&gt;•• • i i i &amp;gt; i ушшшшш ш •••:&lt;BR&gt;:- • •&apos; : &quot; v ••.-•• ш&lt;BR&gt;protected void ListsGrid_CancelEdit (object sender&quot;, DataGridCornmandEyentArgs&lt;BR&gt;ListsGrid.Editltemlndex = -I;&lt;BR&gt;. • • • • . , • • . . - . • , • . . . • . B i n d G r i d O ; •••• . • &apos; • &apos; • : • ••&apos;••&apos; &apos;&apos; : &quot; : ; ; • : V &apos; &amp;#92; . : , - - : • , . • • • ; . . . .. : •&lt;BR&gt;: protected void ListsGrid_Update(object sender, DataGridCoiranandEventArgs e)&lt;BR&gt;: : • &lt; •&apos;•&apos; . •.&apos;&apos;/. - : : &apos; : -&lt;BR&gt;if (Page.IsValid)&lt;BR&gt;{ &apos; Щ. •• - ; :&lt;BR&gt;:&lt;BR&gt;.;. //получить новые данные из диалоговых окон&lt;BR&gt;string ListName = ((TextBox)e.Item.FindControl(&quot;EditListName&quot;)).T...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Редактирование и обновление списков&lt;BR&gt;&lt;/SPAN&gt;М ы переходим к реализации методов, которые осуществляют редактирование&lt;BR&gt;и обновление списков:&lt;BR&gt;protected void ListsGrid_Edit (object sender, DataGridCoiranandEventArgs e)&lt;BR&gt;{&lt;BR&gt;ShowAddNewControls(false);&lt;BR&gt;//начать редактирование&lt;BR&gt;ListsGrid.Editltemlndex = (int)e.Item.Itemlndex;&lt;BR&gt;BindGridO;&lt;BR&gt;•• • i i i &amp;gt; i ушшшшш ш •••:&lt;BR&gt;:- • •&apos; : &quot; v ••.-•• ш&lt;BR&gt;protected void ListsGrid_CancelEdit (object sender&quot;, DataGridCornmandEyentArgs&lt;BR&gt;ListsGrid.Editltemlndex = -I;&lt;BR&gt;. • • • • . , • • . . - . • , • . . . • . B i n d G r i d O ; •••• . • &apos; • &apos; • : • ••&apos;••&apos; &apos;&apos; : &quot; : ; ; • : V &apos; &amp;#92; . : , - - : • , . • • • ; . . . .. : •&lt;BR&gt;: protected void ListsGrid_Update(object sender, DataGridCoiranandEventArgs e)&lt;BR&gt;: : • &lt; •&apos;•&apos; . •.&apos;&apos;/. - : : &apos; : -&lt;BR&gt;if (Page.IsValid)&lt;BR&gt;{ &apos; Щ. •• - ; :&lt;BR&gt;:&lt;BR&gt;.;. //получить новые данные из диалоговых окон&lt;BR&gt;string ListName = ((TextBox)e.Item.FindControl(&quot;EditListName&quot;)).Text;&lt;BR&gt;string ListDescr = ((TextBox)e.Item.FindControl(&quot;EditListDescr&quot;)).Text;&lt;BR&gt;int ListID = (int)ListsGrid.DataKeys[e.Item.Itemlndex]; Ш&lt;BR&gt;NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString()};&lt;BR&gt;//обновить значения&lt;BR&gt;lists.Update(ListID, ListName, ListDescr);&lt;BR&gt;ListsGrid.Editltemlndex = -1; •&lt;BR&gt;BindGridO;&lt;BR&gt;Первая процедура ListGrid_Edit(), вызываемая при наступления события,&lt;BR&gt;прячет управляющие элементы для включения новой строки и присваивает свойст-&lt;BR&gt;ву Editltemlndex в качестве значения индекс редактируемой строки; это значение&lt;BR&gt;извлекается из объекта item, который представляется в качестве свойства объек-&lt;BR&gt;та е, передаваемого функции в качестве параметра. Наконец, опять вызывается&lt;BR&gt;метод BindGridO для привязки данных текущей строки к двум текстовым окнам.&lt;BR&gt;Когда нажимается иконка X, свойству Editltemlndex присваивается -1 и таблица&lt;BR&gt;обновляется.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 821&lt;BR&gt;Наибольший интерес представляет то, каким образом происходит обновление&lt;BR&gt;строки, осуществляемое процедурой ListGrid_update (). Выполнение кода проис-&lt;BR&gt;ходит, только если страница является допустимой, т. е. когда соблюдены все пра-&lt;BR&gt;вила проверки допустимости управляющих элементов. В этом случае текстовое&lt;BR&gt;окно Name должно содержать допустимое имя. При успешной проверке выполнение&lt;BR&gt;функции продолжается, в результате чего извлекаются текущие значения из обоих&lt;BR&gt;текстовых окон. Ссылка на каждое из окон возвращается методом Findcontroi о&lt;BR&gt;объекта item, после чего их содержимое считывается посредством свойства Text.&lt;BR&gt;Для считывания текста из управляющего элемента TextBox необходимо текстовое&lt;BR&gt;окно, которое не возвращается методом Findcontroi () в явном виде, поэтому при-&lt;BR&gt;ходится вручную приводить возвращаемый объект к типу TextBox. Последний не-&lt;BR&gt;обходимый параметр — это идентификатор обновляемой строки, получить который&lt;BR&gt;не составляет никакого труда, поскольку данная колонка была объявлена в качест-&lt;BR&gt;ве первичного ключа таблицы данных, поэтому вся работа сводится к считыванию&lt;BR&gt;значения свойства. В заключение создается объект ListsDB и вызывается метод&lt;BR&gt;updateO, которому передается идентификатор списка, а также новые имя и описа-&lt;BR&gt;ние; в результате этого изменения вносятся в базу данных, и остается только об-&lt;BR&gt;новить таблицу, чтобы эти изменения нашли в ней свое отражение.&lt;BR&gt;Удаление списка&lt;BR&gt;Процедура обработки события ListGrid_Deiete() обладает в точности такой же&lt;BR&gt;структурой, что и только что рассмотренные события, хотя она несколько проще;&lt;BR&gt;единственный параметр, который необходимо передавать методу Delete () объекта&lt;BR&gt;ListsDB,— это идентификатор списка, возвращаемый перечислимым свойством&lt;BR&gt;DataKey:&lt;BR&gt;• protected void ListsGrid_Delete{object sender, DataGridCommandEventArgs e)&lt;BR&gt;ShowAddControls(false);&lt;BR&gt;ListsGrid.Editltemlndex = -1;&lt;BR&gt;NewsMailer»ListsDB lists = new NewsMailer.ListsDB(GetConnString());&lt;BR&gt;// получить идентификатор списка и удалить его&lt;BR&gt;Lists.Delete( (int)ListsGrid.DataKeys[e.Item.Itemlndex] );&lt;BR&gt;BindGridO;&lt;BR&gt;} . •&lt;BR&gt;Создание списка&lt;BR&gt;Последнее, с чем нам осталось познакомиться,— это добавление новой строки.&lt;BR&gt;При нажатии кнопки Create на экран выводятся два текстовых окна и соответству-&lt;BR&gt;ющие иконки для подтверждения или отказа от выполнения операции, в то время&lt;BR&gt;как сама кнопка Create становится невидимой. Кроме того, свойству таблицы дан-&lt;BR&gt;ных Edititemindex присваивается значение - 1 , что предотвращает выполнение ка-&lt;BR&gt;ких бы то ни было операций редактирования. Ниже приводится код для обработки&lt;BR&gt;этого события, а также код функции, которая выводит или прячет управляющие&lt;BR&gt;элементы в зависимости от значения передаваемого ей логического параметра:&lt;BR&gt;protected void: Create_Click(object sender, EventArgs e)&lt;BR&gt;{ .&lt;BR&gt;// показать диалоговые окна и кнопки для добавления новой записи&lt;BR&gt;ShowAddNewControls(true);&lt;BR&gt;ListsGrid.Editltemlndex = -1;&lt;BR&gt;BindGridO ; &apos;&lt;BR&gt;822 Практический пример&lt;BR&gt;protected void ShowAddNewControls(bool ShowControls)&lt;BR&gt;РШРР . • {&lt;BR&gt;// показать / спрятать управляющие элементы для добавления новой записи&lt;BR&gt;NewListNarne.Text^&quot; •; &apos; . .&lt;BR&gt;.::;•:.:•••;: NewListDescr.Text=&quot; •; .&lt;BR&gt;AddNewControlsRow.Visible = JShowControls; :&lt;BR&gt;CreateNewRow.Visible=IShowControls;&lt;BR&gt;PPPPi• &apos; •&apos;•: &apos;&quot; PPPP&apos;i-. :;&quot;&apos;:Ф:Щ!1:;::л!:::;:&apos;• •..&apos;;;::Р:ЙРPy-:?1^Ш1:;?.1К?Э&quot; :лШ&amp;gt;::Ш&lt;BR&gt;Иконка, добавляющая новый список, представляет собой не что иное, как&lt;BR&gt;кнопку, для которой обработка события &quot;щелчок мышью&quot; имеет следующий вид:&lt;BR&gt;protected void AddNew_Click(object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;if (Page.IsValid)&lt;BR&gt;Ш-ЙР. {&lt;BR&gt;NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString() );&lt;BR&gt;//добавить новую запись&lt;BR&gt;lists.Add(NewListName.Text, NewListDescr.Text);&lt;BR&gt;. ShowAddNewControls (false) ; :: &quot; :&lt;BR&gt;BindGridO ;&lt;BR&gt;Если страница является допустимой, как в случае события update о , то про-&lt;BR&gt;грамма получает содержимое двух текстовых окон и передает эти строки методу&lt;BR&gt;Add о объекта ListsDB. В данном случае код оказывается несколько проще, посколь-&lt;BR&gt;ку можно непосредственно ссылаться на оба окна, так как других управляющих&lt;BR&gt;элементов с такими именами не существует.&lt;BR&gt;Иконка, отменяющая операцию добавления, представляет собой управляющий&lt;BR&gt;элемент ButtonLink, который, будучи нажатым, прячет все управляющие элементы&lt;BR&gt;для имени и описания нового списка и восстанавливает все в том виде, в каком это&lt;BR&gt;выводилось по умолчанию. Ниже, приводится код для обработки события click:&lt;BR&gt;protected void CancelAddNew_Click(object sender, EventArgs e)&lt;BR&gt;Щ i &apos;&apos; . • &apos; • / : ; ; : - Й ^ р ^ Ш ^ Ш ^ ^ ^ . ^ •. •&apos;.&apos;,,:-;-^ ••:•&apos; &apos;•:•/; v.:.&apos;&lt;BR&gt;ShowAddNewControls(false);&lt;BR&gt;&amp;#92;P::Wi::^;:::)ЖР Ж v;-: ШШ&apos;&amp;pound;W¥:C;W:&amp;gt;::-ШР?ЖiPBwP:(Ш-:кШШШР;:;P •.i.:::;: •:•:••••. :• •&apos; •: •:: Ш&lt;BR&gt;9 • •&lt;BR&gt;Здесь следует обратить внимание на один очень важный момент. Нажатие&lt;BR&gt;кнопки приводит к тому, что страница отправляется обратно. В этот момент произ-&lt;BR&gt;водится проверка допустимости управляющих элементов с именем и описанием, и,&lt;BR&gt;если имя нового списка отсутствует, отправка страницы будет прекращена. Чтобы&lt;BR&gt;избавиться от этой проблемы, можно установить режим, при котором нажатие&lt;BR&gt;этой кнопки не приводит к проверке допустимости формы, присвоив ее свойству&lt;BR&gt;CuasesValidtion значение false.&lt;BR&gt;На этом код для данной страницы завершен. Для создания страницы потребо-&lt;BR&gt;валось не такое уж большое количество кода, особенно по сравнению с кодом, ко-&lt;BR&gt;торый был бы необходим при использовании традиционного ASP — даже простое&lt;BR&gt;создание многофункционального табличного представления данных потребовало&lt;BR&gt;бы несколько сотен (если не тысяч) строк сложного кода на ASP.&lt;BR&gt;Управление подписчиками&lt;BR&gt;Страница для управления подписчиками списков очень похожа на только что&lt;BR&gt;проанализированную страницу, поэтому в данном разделе мы остановимся только&lt;BR&gt;на ее отличиях. На рисунке (см. стр. 823) страница изображена в том виде, в каком&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в уежиме&lt;BR&gt;она выводится в процессе добавления&lt;BR&gt;нового подписчика. Пользователь про-&lt;BR&gt;извел попытку подписаться, не указав&lt;BR&gt;своего адреса электронной почты, поэ-&lt;BR&gt;тому программа проверки допустимости&lt;BR&gt;сообщает ему, что поле Emaii должно&lt;BR&gt;быть заполнено обязательно.&lt;BR&gt;Страница&lt;BR&gt;Subscribers, aspx&lt;BR&gt;Как видно на рисунке, эта страница&lt;BR&gt;отличается от предыдущей. Одно из от-&lt;BR&gt;личий заключается в том, что в таблице&lt;BR&gt;присутствует другое количество столб-&lt;BR&gt;цов и, кроме того, имеется раскрываю-&lt;BR&gt;щееся окно, в где можно осуществлять выбор списка рассылки и просматривать&lt;BR&gt;подписчиков этого списка. Помимо этого есть кнопка, которая переносит пользо-&lt;BR&gt;вателя на страницу, позволяющую отправить новое сообщение по данному списку&lt;BR&gt;рассылки.&lt;BR&gt;Что касается столбцов, то все отличия сводятся к добавлению нескольких&lt;BR&gt;новых столбцов с шаблонами, к изменению имени столбца при вызове метода&lt;BR&gt;DataBinder.Evaio, а также к изменению определенных свойств некоторых столб-&lt;BR&gt;цов без шаблонов. Код, относящийся к этой странице, оказывается довольно длин-&lt;BR&gt;ным. Ниже приводится его первая часть, в которой описывается комбинированное&lt;BR&gt;окно и кнопка Send Email (отправка электронной почты):&lt;BR&gt;&lt;asp:table id=&quot;TableLists&quot; runat=&quot;server&quot;• CssClass=&quot;Grid_General&amp;gt;&lt;BR&gt;&lt;asp:TableRow&amp;gt;&lt;BR&gt;&lt;asp:TableCell width=&quot;5Opx&quot;&lt;BR&gt;HorizontalAlign= &quot;Center &quot;&amp;gt;&lt;b&amp;gt;List :&lt;/bx/asp:TableCell&amp;gt;&lt;BR&gt;&lt;asp:TableCelI width=n280px&quot;&lt;BR&gt;&lt;asp:DropDownList runat = &quot;server&quot; ID=&quot;ListDropDownf&apos; ;&lt;BR&gt;DataTextField=&quot;Name&quot; DataValueField=&quot;ID&quot; width=»280pxn &apos;&lt;BR&gt;Class=&quot;TextBoxrl AutoPostBaGk.= l!True&quot;&lt;BR&gt;OnSelectedIndexChanger-&quot;ListsDropDown_IndexChanged&quot; /&amp;gt;&lt;BR&gt;&lt;/asp;TableCell&amp;gt; &amp;gt;&lt;BR&gt;&lt;asp:TableCell&amp;gt;&lt;BR&gt;&lt;asp:Button runat=&quot;server&quot; Text=&quot;Send Email&quot;&lt;BR&gt;ID=&quot;SendEmail&quot; CssClass=&quot;Button11&lt;BR&gt;OnClick=&quot;SendEmail_Click&quot; Width=&quot;100px&quot; /&amp;gt;&lt;BR&gt;&lt;/asp:TableCell&amp;gt;&lt;BR&gt;&lt;asp:TableRow&amp;gt; :&lt;BR&gt;:&lt;BR&gt;&lt;asp:table&amp;gt;&lt;BR&gt;Необходимо обратить внимание на то, что свойству раскрывающегося окна&lt;BR&gt;AutoPostBack присвоено значение true. Это приводит к тому, что страница будет&lt;BR&gt;отправляться обратно каждый раз, когда пользователь изменяет выбранный эле-&lt;BR&gt;мент. В свою очередь, это влечет за собой наступление события OnSeiectedmdex-&lt;BR&gt;Changed И, Соответственно, ВЫЗОВ процедуры LiStsDropDown_IndexChanged() .&lt;BR&gt;Остальная часть страницы аналогична тому, что мы видели раньше. Рассмотрим&lt;BR&gt;дополнительные строки, которые были добавлены к объявлению таблицы данных:&lt;BR&gt;&lt;asp:DataGrid id=&quot;SubscrGrid&quot; runat-&apos;1 server&quot;&lt;BR&gt;AllowPaging=&quot;True&quot; :.{..•&lt;BR&gt;PageSize=&quot;20&quot;&lt;BR&gt;824 Практический пример&lt;BR&gt;PagerStyle-HorizontalAlign=nRight&quot;&lt;BR&gt;PagerStyle-PageButtonCount=H20&quot;&lt;BR&gt;PagerStyle-Mode=IINumericPages&quot;&lt;BR&gt;OnPageIndexChanged=&quot;SubscrGrid_J?ageChanged11&lt;BR&gt;В этих строках соответственно определяется, что данные будут выводиться&lt;BR&gt;в виде страниц по 20 строк и что пользователь будет иметь возможность осущест-&lt;BR&gt;влять поиск и перемещение по номерам страниц, расположенных внизу справа,&lt;BR&gt;а также задается процедура, которая будет обрабатывать события, связанные с из-&lt;BR&gt;менением страницы.&lt;BR&gt;Код поддержки для Subscribers.aspx&lt;BR&gt;Что касается кода на ASP.NET, то код поддержки для subscribers.aspx не&lt;BR&gt;очень отличается от страницы Lists. В нем появилось несколько строк для работы&lt;BR&gt;с вновь добавленными управляющими элементами. Этот код выполняется, когда&lt;BR&gt;происходит загрузка страницы:&lt;BR&gt;protected void Page_Load(object sender, EveiitArgs e)&lt;BR&gt;{ . •&lt;BR&gt;// получить ListID из QueryString&lt;BR&gt;string ListID -Request.Params[*ListID&quot;];&lt;BR&gt;SubscrGrid.Attributes[••ListlD*]. = ListID;&lt;BR&gt;.If (iPage, IsPostBack)&lt;BR&gt;&apos;{&lt;BR&gt;// загрузить все доступные списки в управляющий элемент DropDown&lt;BR&gt;NewsMailer.ListsDB lists.= new NewsMaiier.ListsDBCGetConnStringO);&lt;BR&gt;DataView myDV = lists.GetListsO .Tables [0] .DefaultView;&lt;BR&gt;ListsDropDown.DataSource ^ myDV;&lt;BR&gt;ListsDropDown.DataBindO ;&lt;BR&gt;If (ListID!=null)&lt;BR&gt;{ &apos; . • &apos; . . &apos; : . : . • .. ^ .:• • &apos; - • . / • - &quot; ; &apos; • , . ; ./• •&lt;BR&gt;// выбрать элемент DropDown в соответствии с ListID&lt;BR&gt;forearch (ListItem item in ListsDropDown.Items)&lt;BR&gt;if (item.Value==ListID) s&lt;BR&gt;ListsDropDown.Selectedlndex =&lt;BR&gt;ListsDropDown.Items.IndexOF(item);&lt;BR&gt;- &apos; • ••• &quot; ••••••• • &apos; • • • &quot; &amp;gt; • • • •••• ••• •&apos;•• &apos;• •&quot; •: ; k Щ / Ж Ч &apos;./:•.•&quot;•&apos;•• v &amp;#92; - &apos; : . . &apos; ; ; . Л : ; :&quot; ;• :&lt;BR&gt;V/ упорядочить управляющие элементы на странице&lt;BR&gt;BindGridO ;&lt;BR&gt;• &amp;gt; Ш-ШМ ^&lt;BR&gt;&amp;gt; I ••&quot;:&quot;-: Ш Ш ш&lt;BR&gt;С правой стороны каждой строки таблицы на страннице Lists.aspx располага-&lt;BR&gt;лась иконка, которая, при щелчке на ней мышью, переносила пользователя на&lt;BR&gt;страницу subscribers.aspx, чтобы он мог просмотреть всех подписчиков данного&lt;BR&gt;списка. Для этого использовалась ссылка на страницу subscribers.aspx, а в стро-&lt;BR&gt;ку запроса в качестве параметра добавлялся идентификатор списка. Далее это&lt;BR&gt;значение извлекается из строки запроса и сохраняется в качестве атрибута эле-&lt;BR&gt;мента, управляющего табличным представлением данных, так как оно будет исполь-&lt;BR&gt;зоваться в тот момент, когда в этом коде будет вызываться метод GetsubscribersO&lt;BR&gt;для данного списка.&lt;BR&gt;Двигаясь далее, мы обнаружим, что в дополнение к обычному вызову метода&lt;BR&gt;BindGrid () на этот раз используется раскрывающийся список, который наполняется&lt;BR&gt;имеющимися в наличии списками рассылки. Это осуществляется непосредственно&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в -режиме онлайн 825&lt;BR&gt;внутри данной процедуры посредством обращения к методу GetListsO класса&lt;BR&gt;ListsDB и привязки получаемой в результате таблицы в качестве источника данных&lt;BR&gt;для управляющего элемента. Вновь добавленные элементы считываются один за&lt;BR&gt;другим и выбирается элемент, идентификатор которого совпадает с идентификато-&lt;BR&gt;ром, хранящимся в строке запроса.&lt;BR&gt;В метод BindGrido ДДЯ этой страницы включен некоторый дополнительный код,&lt;BR&gt;считывающий идентификатор списка, для которого требуется извлечь подписчиков,&lt;BR&gt;и, кроме того, в ней ддя получения требуемого набора данных (то есть таблицы)&lt;BR&gt;ИСПОЛЬЗуетСЯ класс SubscribersDB:&lt;BR&gt;protected void BindGridO&lt;BR&gt;- . _ {&lt;BR&gt;int ListID;&lt;BR&gt;// получить значение ListID из атрибутов Grid&lt;BR&gt;if { SubscrGrid.Attributes[«ListID&apos;1 1= null )&lt;BR&gt;ListID = int. Parse(SubscrGrid.Attributes!&quot;List-ID&apos;]);&lt;BR&gt;else&lt;BR&gt;ListID = int.Parse (ListsDropDown.SelectedI.tem.Value);&lt;BR&gt;// получить всех подписчиков данного листа&lt;BR&gt;NewsMailer.SubscribersDB subscribers =&lt;BR&gt;new NewsMailer.SubscribersDB(GetConnString());&lt;BR&gt;DataView myDV = subscribers.GetSubscribers (&lt;BR&gt;ListID).Tables[OJ.DefaultView;&lt;BR&gt;// отсортировать все записи в соответствии с&lt;BR&gt;// атрибутом SortExpression DataGris&lt;BR&gt;if ( SubscrGrid.Attributes[&apos;SortExpression*]! = &quot; &apos;;&lt;BR&gt;myDV.Sort = SubscrGrid.Attributes[&quot;SortExpression&quot;];&lt;BR&gt;SubscrGrid.DataSource = myDV;&lt;BR&gt;SubscrGrid.DataBindO ;&lt;BR&gt;}&lt;BR&gt;Эта функция отвечает за выбор элемента в раскрывающемся списке:&lt;BR&gt;protected void ListsDropDown_IndexChanged(object sender. EventArgs e)&lt;BR&gt;{&lt;BR&gt;// загрузить страницу, чтобы показать записи выбранного листа&lt;BR&gt;Response.Redirect (&apos;Subscribers.aspx?ListID=&apos;r +&lt;BR&gt;ListsDropDown.Selectedltem.Value);&lt;BR&gt;•; -: : .•••:•-v&apos; :: &quot;&quot;•: wu • :• ш . :&apos;&amp;amp;ш&amp;amp;шшш^. шшшш. шшiiii .&apos; &apos;&lt;BR&gt;В результате появляется возможность повторно направить браузер на ту же са-&lt;BR&gt;мую страницу, но на этот раз с идентификатором выбранного элемента, что позво-&lt;BR&gt;лит произвести загрузку соответствующих подписчиков при очередном обращении&lt;BR&gt;К методу BindGrid ().&lt;BR&gt;Когда пользователь двигается по другим страницам таблицы данных, необходи-&lt;BR&gt;мо запретить переход в режим редактирования. Это означает, что, пока не будет&lt;BR&gt;произведена повторная привязка таблицы данных, необходимо спрятать элементы,&lt;BR&gt;управляющие добавлением новой строки, а также не выводить сообщение об&lt;BR&gt;ошибке, которая возникает, если мы пытаемся добавить уже существующего&lt;BR&gt;в списке подписчика. Необходимо присвоить свойству currentPageindex фактиче-&lt;BR&gt;ское значение, для того чтобы внести изменения в текущую страницу:&lt;BR&gt;protected void SubscrGrid_PageChanged(object sender,&lt;BR&gt;DataGridPageChangedEventArgs e)&lt;BR&gt;{&lt;BR&gt;SubscrGrid.EditItemlndex = -1&lt;BR&gt;AddError.Visible = false;&lt;BR&gt;826 Практический пример&lt;BR&gt;ShowAddNewControls(false);&lt;BR&gt;// изменить текущую страницу для чтения данных&lt;BR&gt;SubscrGrid.CurrentPagelndex = e.NewPagelndex;&lt;BR&gt;BindGridO ?&lt;BR&gt;В заключение процедура, которая обрабатывает событие, наступающее при на-&lt;BR&gt;жатии кнопки Send Email, передает управление на страницу sendEmaii.aspx&lt;BR&gt;с идентификатором текущего списка в качестве параметра — точно так же, как&lt;BR&gt;это делалось для раскрывающихся списков:&lt;BR&gt;protected void SendHmail_jClick(object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;// вернуться к странице, чтобы отослать Email, •&lt;BR&gt;// добавить значение ListID к QueryString&lt;BR&gt;Response.Redirect(&quot;SerKiErna.il.aspx?ListID-&quot; +&lt;BR&gt;ListDropDovm.Selectedltem.Value) ;&lt;BR&gt;Отправка электронной почты подписчикам&lt;BR&gt;&amp;#92;&lt;BR&gt;•:.:::|.S*-:J./iC«i5.Se;K«&lt;BR&gt;ъ&lt;BR&gt;v&amp;gt;ou(&lt;sao&lt;BR&gt;• • • - : -&lt;BR&gt;использующейся по умолчанию SMTP-&lt;BR&gt;службы, которая инсталлируется вместе&lt;BR&gt;с Windows 2000 Server, поэтому не по-&lt;BR&gt;требуется ни каких-либо дополнительных&lt;BR&gt;средств, ни каких-либо серверов сторон-&lt;BR&gt;них производителей для отправки сообще-&lt;BR&gt;ний. Кроме того, можно предварительно&lt;BR&gt;просмотреть сообщение, хотя при этом&lt;BR&gt;строки, ограниченные символами &quot; # &quot; , не&lt;BR&gt;транслируются, поскольку предваритель-&lt;BR&gt;ный просмотр не является специфическим&lt;BR&gt;для какого-либо конкретного подписчика.&lt;BR&gt;На рисунке справа изображено предва-&lt;BR&gt;рительное представление тела сообще-&lt;BR&gt;ния с предыдущего рисунка.&lt;BR&gt;Мы достигли критической точки в реализации при-&lt;BR&gt;ложения — теперь требуется разработать и написать&lt;BR&gt;код для страницы, которая позволяла бы администра-&lt;BR&gt;тору составлять сообщение, рассылать его всем под-&lt;BR&gt;писчикам из списка и заносить его в архив в БД для&lt;BR&gt;последующего просмотра. Рисунок слева дает представ-&lt;BR&gt;ление о том, как это все должно функционировать.&lt;BR&gt;С помощью этой страницы администратор получает&lt;BR&gt;возможность создать само сообщение, отправляемое по&lt;BR&gt;электронной почте, и задать практически все опции,&lt;BR&gt;касающиеся отправки сообщений, которые являются&lt;BR&gt;общими для большинства клиентов: СС, ВСС, формат&lt;BR&gt;электронного сообщения (простой текст или HTML),&lt;BR&gt;приоритет, предмет сообщения и его тело. Кроме того,&lt;BR&gt;можно использовать несколько отформатированных&lt;BR&gt;специальным образом строк (располагающихся с правой&lt;BR&gt;стороны), которые будут автоматически заменяться на&lt;BR&gt;соответствующие им значения для каждого сообщения,&lt;BR&gt;отправляемого по электронной почте посредством&lt;BR&gt;-;&apos;оч: -о&apos; &amp;gt; -&quot;.- 1&quot; :i2O«&quot;5&quot;&amp;gt;*UstOosc.&apos;ip&lt;BR&gt;B-a&amp;amp;r tfSubscri ^ I - I . ^ L . &amp;gt;t-# tfSubscriberLa&lt;BR&gt;is seme nsv?s about C#:&lt;BR&gt;- you con use •&quot; • ••-&apos; A: v.-T y-: •»i dows ap&lt;BR&gt;C i&lt;BR&gt;racia^ o u r big « f f g r t t o p r o v i d e .you .wish frepi nov,&apos;.-, -J.-&lt;••&lt;BR&gt;(ч# code sunipk%s, news, articles: Issue u, .1.2&lt;BR&gt;1?ШЩщ^и &apos;• . -&lt;BR&gt;:гтт &apos;.&quot; ;&lt;rr.T r:r.v; .э,Ьо&apos;.;1 См&lt;BR&gt;• ; t j , ^ v « . u ^ ^ &quot;:: ;;;.•: ••;-;:;:;:^:&apos;y •&apos;-&quot; &quot;••:,•:•::;:•;;:::.:&apos;&lt;BR&gt;- ycu v.jj иге :: fa Ab°?,N&amp;pound;T .c.u W::...k-v.-? г^ргг &lt;ii vvc&apos;i •&lt;BR&gt;• Of&apos; r ,J :v;?- г..-jrt* *&lt;BR&gt;&apos;,&apos;.&amp;gt; nor;1 you .;:•;&amp;gt;:•:&lt;::;::= oyr b:^ tS&apos;t-rt Ю pow.:; yen r.&apos;.th fresh ncv.-; v/l&apos;i«&lt;BR&gt;;ri;-J th;yi/&apos;v у ом. j.,-!-r.».sn SMV^UJ lots of chocolate ,•*&lt;BR&gt;: •;:.&quot;. Ш sparr lime If ус-иЧткс ^о&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 827&lt;BR&gt;Страница SendEmaiLaspx&lt;BR&gt;Страница ASP.NET содержит код, аналогичный коду, встречавшемуся ранее,&lt;BR&gt;здесь он не будем воспроизводиться. Управляющие элементы в виде текстовых&lt;BR&gt;окон, уникальные для данной страницы, используются для вывода значений&lt;BR&gt;свойств NewsSubject и signature, которые хранятся в XML-файле с установками&lt;BR&gt;и которые извлекаются кодом поддержки и передаются, странице.&lt;BR&gt;Код поддержки для SendEamaiLaspx&lt;BR&gt;Табличная сетка для вывода данных не используется на этой странице, поэтому&lt;BR&gt;данный файл с кодом поддержки существенно отличается от тех двух файлов с ко-&lt;BR&gt;торыми мы сталкивались перед этим. Рассмотрим код метода Page_Load(), в кото-&lt;BR&gt;ром части программы, отличающиеся от предшествующих файлов, выделены&lt;BR&gt;серым цветом:&lt;BR&gt;// Используются две переменные для хранения конфигурационных установок&lt;BR&gt;public string Signature_Value;&lt;BR&gt;public string Subject_Value;&lt;BR&gt;protected void Page_Load(object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;string ListID = Request.Params[&quot;ListlD&quot;]&lt;BR&gt;if (IPage.IsPostBack)&lt;BR&gt;// загрузить все списки, перечисленные в управляющем элементе DropDown&lt;BR&gt;NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString(});&lt;BR&gt;DataView myDV = lists.GetLists().Tables[0].DefaultView;&lt;BR&gt;ListsDropDown.DataSource = myDV;&lt;BR&gt;// загрузить подписи и новые объекты из базы данных&lt;BR&gt;NewsMaiier.Appsettings settings -&lt;BR&gt;NewsMailer. AppConf ig.GetSettings (Server.MapPatMGetSettingsFile () ) ) ;&lt;BR&gt;Signature_Value = settings.Signature;&lt;BR&gt;Subject_Value = settings.NewsSubject;&lt;BR&gt;Page.DataBind();&lt;BR&gt;if (ListID!=null)&lt;BR&gt;{&lt;BR&gt;foreach (Listltem item in ListsDropDown.Items)&lt;BR&gt;if (item.Value==ListID)&lt;BR&gt;ListsDropDown.Selectedlndex =&lt;BR&gt;ListsDropDown.Items.IndexOf(item) ;&lt;BR&gt;Модуль NewsMailerConf ig используется для получения всех установок из XML-&lt;BR&gt;файла, а сигнатура и предмет новостей сохраняются в общих переменных.&lt;BR&gt;Заметьте, что имя файла, в котором хранятся установки, извлекается либо из&lt;BR&gt;файла web.config, либо ИЗ КЭШ-памяти посредством функции GetSettingsFileO&lt;BR&gt;класса Baseciass, а возвращенное значение преобразуется в реальный путь с по-&lt;BR&gt;мощью вызова метода server.Mappathо, который позволяет получить полный путь&lt;BR&gt;к файлу.&lt;BR&gt;Когда выполняется метод DataBind о,осуществляющий привязку всех дочерних&lt;BR&gt;управляющих элементов текущей формы к данным, то происходит привязка к зна-&lt;BR&gt;чениям двух переменных — Signature_Value И Subject_Value — И ИХ ВЫВОД В тек-&lt;BR&gt;стовых окнах.&lt;BR&gt;828 Практический пример&lt;BR&gt;Ниже приводится код для кнопки Preview:&lt;BR&gt;protected void Preview__Click(object sender, EventArgs e)&lt;BR&gt;V - , . V - : : &apos; &amp;#92; •:; -; { &quot; ;/:&apos;;- :.. •;.,••&apos;•.,&apos;;:-: ••.&apos;.•;•&apos;, : &quot; t &apos; : - &quot; . •&quot;&apos; : &apos; ! l &apos; - : : J y - • • &apos; ; ; : v . ...&lt;BR&gt;string MsgText = . Body.Text;&lt;BR&gt;: int ListID = int.Parse(ListsDropDown.Selectedltem.Value);&lt;BR&gt;// заменить теги по спискам и установкам на их новые значения&lt;BR&gt;MsgText = NewsMailer.Utilities.ProcessListTags(MsgText,&lt;BR&gt;GetCoimS.tring () , List-ID) ;&lt;BR&gt;MsgText = NewsMailer.Utilities.ProcessListTags(MsgText, GetConnString());&lt;BR&gt;//осуществить кодировкутела, если это не формат HTML&lt;BR&gt;if (FormatDropDown.SelectedIndex==0)&lt;BR&gt;MsgText = HttpUtility.KtmlEncode(MsgText);&lt;BR&gt;// заменить новые линии символами &lt;br&amp;gt;&lt;BR&gt;MsgText- MsgText.Replace(&quot;&amp;#92;пя, &quot;&lt;Ъх&amp;gt;&quot;);&lt;BR&gt;// убрать символы возврата каретки&lt;BR&gt;MsgText=...MsgText. Replace (• &amp;#92;r •&quot;,.•••);&lt;BR&gt;MsgPreview.Text = MsgText;&lt;BR&gt;MsgPreview.Visible = true;&lt;BR&gt;В этом коде происходит вызов некоторых функций из класса u t i l i t i e s , кото-&lt;BR&gt;рые осуществляют замены определенных тегов на соответствующие им значения,&lt;BR&gt;кодирование текста в том случае, если в качестве формата выбран обыкновенный&lt;BR&gt;текст (например, тег &lt;ь&amp;gt; заменяется на &amp;amp;it;b&amp;amp;gt;), заменяют все переходы к но-&lt;BR&gt;вой строке на тег &lt;br&amp;gt; и удаляют символы &quot;возврат каретки&quot;, поскольку символы&lt;BR&gt;#&amp;#92;п&apos; и &apos;&amp;#92;г&apos; не распознаются в HTML. В завершение тело сообщения выводится&lt;BR&gt;в управляющем элементе предварительного просмотра.&lt;BR&gt;Перейдем к коду для кнопки Send Email:&lt;BR&gt;protected void Send_Click (object sender, EventArgs e)&lt;BR&gt;{ &apos;&lt;BR&gt;Server.ScriptTimeout = 3 600,-&lt;BR&gt;Strins MsgBady = Body.Text;&lt;BR&gt;Int ListID= int.Parse(ListDropDown.Selectedltem.Value);:&lt;BR&gt;String MsgSubject = NewsMailer.Utilties.ProcessListTags(&lt;BR&gt;Subject.Text, GetConnString(), List-ID) ;&lt;BR&gt;NewsMailer.AppSettings =&lt;BR&gt;NewsMailer.AppConfig.GetSettings(Server.MapPath(GetSettingsFile()));&lt;BR&gt;NewsMailer.NewsHistoryDB news = new NewsMailer. NewsHistoryDB(&lt;BR&gt;GetConnString());&lt;BR&gt;// заменить теги по спискам и установкам на их новые значения&lt;BR&gt;MsgBody = NewsMailer.Utilities.ProcessListTags(MsgBody,&lt;BR&gt;GetConnString(&apos;), ListlDOf-&lt;BR&gt;MsgBody - NewsMailer. Utilities. ProcessSettingsTags (MsgBody,&lt;BR&gt;GetConnString());&lt;BR&gt;// добавить новую запись в архив новостей&lt;BR&gt;news .Add(ListID, MsgSubject,MsgBody, (FormatDropDown.SeleC:tedIndexs==l)&apos;.) ;•&lt;BR&gt;//создать новое почтовое сообщение&lt;BR&gt;MaiMessage MailMsg = new MaiM^ssage () ;&lt;BR&gt;MailMsg.From•= settings.SenderName•+ * &lt;* + settings.SenderEmail. + &quot;&amp;gt;&quot;;&lt;BR&gt;MailMsg.Cc = CC.Text;&lt;BR&gt;MailMsg.Bcc = BCC.Text;&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 829&lt;BR&gt;MailMsg. Priority•.- (Mail-Priority) PriorityDropDown. Selectedlndex;&lt;BR&gt;MailMsg.BodyFormat = (MailFormat)FormatDropDown.Selectedlndex;&lt;BR&gt;MailMsg.Subject = MsgSubject;&lt;BR&gt;NewsMailer.SubscribersDB subscribers = new NewsMailer.SubscribersDB{&lt;BR&gt;. CetCormStringO ) ;&lt;BR&gt;//получить всех подписчиков данного листа..:.-.&lt;BR&gt;DataTabledt = subscribers.GetSubscribers(ListDB).Tables[0];&lt;BR&gt;foreach (DataRow dr in dt.Rows)&lt;BR&gt;•; и - Ш { • . ШшШ- ; Щ. •••&apos;••&apos; •&lt;BR&gt;//заменить теги подписчика на их новые значения&lt;BR&gt;MailMsg.То = (srting)dr[&quot;Email&quot;];&lt;BR&gt;MailMsg.Body = NewsMailer.Utilities.ProcessSubscriberTags(MsgBody,&lt;BR&gt;&apos; GetConnStringO , (int)dr[&quot;ID&quot;]) ;&lt;BR&gt;У/ послать это сообщение данному подписчику&lt;BR&gt;SmtpMai 1. Send (MailMsg&apos;);&apos;&lt;BR&gt;;!:.;:: } . .; &apos; &quot;&lt;BR&gt;//показать количество отосланньЕх: сообщений&lt;BR&gt;MsgPreview.Text = string.Format(&lt;BR&gt;*&lt;centerxb&amp;gt;{0} mails have been sent&lt;/b&amp;gt;&lt;/center&amp;gt;&quot;,&lt;BR&gt;dt. Rows .Count. ToString ()&apos;•);&lt;BR&gt;MsgPreview.Visible - true;&lt;BR&gt;ШШ. &apos; • • I &apos; ; &quot; ; . i $m ШШШШШШ^. Wm Ш Ш •-••••• ii ШВё il • • &amp;#92; i : Ш . . t&lt;BR&gt;Эта программа более длинная, но работает она аналогично Preview_ciick. Она&lt;BR&gt;выполняет следующие шаги:&lt;BR&gt;• Специальные теги, находящиеся в списке, и общие установки заменяются&lt;BR&gt;на соответствующие им значения, а при необходимости производится&lt;BR&gt;кодирование текста&lt;BR&gt;• Сообщение добавляется в архив с помощью метода Add о&lt;BR&gt;класса NewsHistory&lt;BR&gt;• Создается объект MaiiMessage и присваиваются значения его свойствам,&lt;BR&gt;общим для всех подписчиков&lt;BR&gt;• Для получения всех подписчиков текущего списка используется&lt;BR&gt;экземпляр класса SubscribersDB&lt;BR&gt;• Для каждого подписчика, полученного в результате запроса,&lt;BR&gt;производится установка его адреса электронной почты в качестве&lt;BR&gt;адреса назначения для отправляемого объекта, после чего происходит&lt;BR&gt;отправка почты&lt;BR&gt;• В управляющем элементе предварительного просмотра выводится&lt;BR&gt;число отправленных сообщений&lt;BR&gt;В рассмотренном коде существует несколько моментов, на которые следует&lt;BR&gt;обратить внимание. Прежде всего в дополнение к обычным пространствам имен,&lt;BR&gt;которые объявлялись и для других страниц, на этот раз необходимо объявлять еще&lt;BR&gt;и пространство имен system.web.Maii, содержащее в себе классы, позволяющие&lt;BR&gt;создавать сообщения и отправлять их по электронной почте посредством использу-&lt;BR&gt;ющейся по умолчанию SMTP-службы, инсталлируемой на Windows 2000 Server.&lt;BR&gt;Следующий момент, на который следует обратить внимание, имеет отношение&lt;BR&gt;к самой первой строке кода:&lt;BR&gt;Server.ScriptTimeout = 3600;&lt;BR&gt;830 Практический пример&lt;BR&gt;Отправка отдельного сообщения — очень быстрое задание, однако если есть не-&lt;BR&gt;сколько тысяч подписчиков, то на это может потребоваться значительное время —&lt;BR&gt;несколько минут или даже больше. Те из вас, кто уже знаком с программирова-&lt;BR&gt;нием на традиционном ASP, знают, что по умолчанию странице дается 90 секунд&lt;BR&gt;на выполнение кода сценария и на отправку всего сгенерированного HTML-кода&lt;BR&gt;браузеру. Это значение, использующееся по умолчанию, может быть изменено&lt;BR&gt;администратором IIS, либо &quot;зашито&quot; в программу страницы — что мы в данном&lt;BR&gt;случае и делаем, устанавливая максимальное время, в течение которого страница&lt;BR&gt;должна завершить свое выполнение, равное одному часу.&lt;BR&gt;Класс Utilities&lt;BR&gt;В файле sendEmaii.cs с кодом поддержки для замены специальных тегов в теле&lt;BR&gt;и предмете сообщения используется класс u t i l i t i e s . Ниже приводится исчерпы-&lt;BR&gt;вающий список методов класса. Обратите внимание на то, что они описаны как&lt;BR&gt;статические; это означает, что, для того чтобы ими воспользоваться, нет необходи-&lt;BR&gt;мости создавать экземпляр данного класса:&lt;BR&gt;Класс Utilities&lt;BR&gt;Метод Описание&lt;BR&gt;public static string ReadTextFile(string FilePath)&lt;BR&gt;public static bool SaveRextFile(string FilePath,&lt;BR&gt;string FileText)&lt;BR&gt;public static string&lt;BR&gt;ProcessListTags(string Message,&lt;BR&gt;string ConnString,&lt;BR&gt;int ListID)&lt;BR&gt;public static string&lt;BR&gt;ProcessSubscriberTags (string Message,&lt;BR&gt;string ConnString,&lt;BR&gt;int SubscrlD)&lt;BR&gt;public static string&lt;BR&gt;ProcessSettingsTags (string Message,&lt;BR&gt;string SettingsFilePath)&lt;BR&gt;Позволяет получать содержимое заданного файла&lt;BR&gt;Сохраняет строку FileText в заданном файле&lt;BR&gt;и возвращает логическое значение,&lt;BR&gt;свидетельствующее об успешном или&lt;BR&gt;неуспешном завершении операции&lt;BR&gt;Заменяет теги списка, обрамленные символами &quot;#&quot;,&lt;BR&gt;на значения, хранящиеся в базе данных&lt;BR&gt;Заменяет теги подписчика, обрамленные&lt;BR&gt;символами &quot;#&quot;, на значения, хранящиеся в БД&lt;BR&gt;Заменяет теги установок, обрамленные&lt;BR&gt;символами &quot;#&quot;, на значения, хранящиеся в Б Д&lt;BR&gt;List: [с*&lt;BR&gt;&lt;ИКЙЗ лф**&amp;amp; * vowС*1 w Ss*«e ^&lt;BR&gt;С* - Jssua •» Г 07/li/Cl .:*&lt;BR&gt;f7 uZ/lvi&apos;i .,.&apos;•&lt;BR&gt;A&lt;BR&gt;Работа&lt;BR&gt;с архивом новостей&lt;BR&gt;Страница архива новостей выводит все&lt;BR&gt;предыдущие новости для всех списков&lt;BR&gt;рассылки либо в виде прямого текста,&lt;BR&gt;либо в виде HTML — в зависимости от&lt;BR&gt;того, в каком формате они отправля-&lt;BR&gt;лись. На рисунке слева представлен&lt;BR&gt;внешний вид страницы архива.&lt;BR&gt;Страница&lt;BR&gt;NewsHistory. aspx&lt;BR&gt;Эта страница использует управляю-&lt;BR&gt;щий элемент табличного представления&lt;BR&gt;данных, но вместе с тем она обладает&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 831&lt;BR&gt;некоторыми уникальными особенностями. Обратите внимание на то, что выбран-&lt;BR&gt;ный ряд выводится другим цветом, нежели все остальные, а у столбца ISHTML есть&lt;BR&gt;окно выбора, указывающее на то, должен ли вывод производится в виде HTML.&lt;BR&gt;Поле Date указывает на дату отправления данного сообщения. Поскольку большая&lt;BR&gt;часть кода не отличается от кода предыдущих страниц, мы не будем приводить весь&lt;BR&gt;текст полностью, а приведем только код, описывающий столбцы ISHTML И Date.&lt;BR&gt;&lt;Columns&amp;gt;&lt;BR&gt;. . . Code removed for clarity&lt;BR&gt;&lt;asp:BoundColumn HesderText=&quot;Subject&quot; DataField=&quot;Subject&quot;&lt;BR&gt;Readonly=&quot;True&quot; SortExpression=&quot;Subject&quot; /&amp;gt;&lt;BR&gt;&lt;asp:TemplateColumn HeaderText=&quot;IsHTML&quot;&lt;BR&gt;ItemStyle-Width^&apos;eQpx&quot; IternStyle-Horizoni:alAlign = &quot;Center&quot;&amp;gt;&lt;BR&gt;;• • &lt;ItemTemplate&amp;gt;&lt;BR&gt;V: : : &lt;asp:CheckBox runat-&quot; server*&quot; Enabled^&quot;false&quot;&lt;BR&gt;&quot;Л(;):ф:. &apos;•^•п:::у:. Checked=&apos;&lt;%#&lt;BR&gt;;-:;:;:.&apos;,:..;;:;.&amp;gt;-&apos;-.,;::-:::;;:,::,:.y ••••,,:-&lt;BR&gt;(bool)DataBinder.Eval(Container.Dataltem, &quot;IsHTML&quot;)&lt;BR&gt;/ &amp;gt; &apos;&quot;&quot;&quot; &apos; . : : . . , &apos; . . • • • &apos; ^ / . &apos; ; • &apos; • &quot; • . . ; • ; . . . &apos; . ; • ; : &amp;#92; &apos;&lt;BR&gt;• &lt;/Ite.mTemplate&amp;gt; •&lt;BR&gt;&lt;/asp:TempiateColumn&amp;gt; •&lt;BR&gt;&lt;asp:TemplateColumn HeaderText=&quot;Date&quot;&lt;BR&gt;SortExpre3sion=llSentDatetf ItemStyle-Width=&quot;9Qpx&quot;&amp;gt;&lt;BR&gt;&lt;ItemTemplate&amp;gt;&lt;BR&gt;&lt;asp:Label runat=&quot;server&quot;&lt;BR&gt;Text==&apos;&lt;%# string.Format(-{0:MM/dd/yy}&quot;,&lt;BR&gt;DateTime.Parse(DataBinder.Eval(Container.Dataltem,&lt;BR&gt;&quot;SentDate&quot;) .ToStringO ) ) %&amp;gt;&apos;&lt;BR&gt;/&amp;gt;&lt;BR&gt;&lt;/ItemTemplate&amp;gt;&lt;BR&gt;&apos; ••&apos;• &apos;.. &apos; :• : &lt;/asp:TemplateColumn&amp;gt; •&lt;BR&gt;Как и для страницы Send Email, где мы привязываем общую переменную к текс-&lt;BR&gt;товому окну, в данном случае столбец is HTML может использоваться в режиме&lt;BR&gt;&quot;только чтение&quot;, и в нем содержится отключенное окно выбора (отключенное,&lt;BR&gt;поскольку информация о прошлых сообщениях не может изменяться администра-&lt;BR&gt;тором посредством этой страницы), значение которого устанавливается в соответ-&lt;BR&gt;ствии со значением поля ISHTML таблицы NewsHistory, хранящейся в базе данных,&lt;BR&gt;и приводится к типу bool. .&lt;BR&gt;Чтобы ПОЛуЧИТЬ Значения ПОЛЯ Date, ИСПОЛЬЗуеТСЯ меТОД DateTimeParse (), ПО-&lt;BR&gt;ЗВОЛЯЮЩИЙ преобразовать строку из базы данных в значение типа DateTime, кото-&lt;BR&gt;рое затем снова преобразовывается в строку для вывода на экран.&lt;BR&gt;Код поддержки для NewsHistory. aspx&lt;BR&gt;Пояснения, которыми мы сопроводим данный код, будут очень короткими, по-&lt;BR&gt;скольку большая часть операций, уже обсуждалась для других файлов с кодом под-&lt;BR&gt;держки. Единственной новой особенностью, заслуживающей обсуждения, является&lt;BR&gt;процедура, обрабатывающая событие таблицы данных OnSelectedlndexChanged.&lt;BR&gt;Когда некоторая строка оказывается выбранной, то тело соответствующего сооб-&lt;BR&gt;щения извлекается, перекодируется в обычный тест и выводится в управляющем&lt;BR&gt;элементе предварительного просмотра:&lt;BR&gt;protected void NewsGrid_SelectionChanged(object sender. EventArgs e)&lt;BR&gt;string Body;&lt;BR&gt;. ..: NewsMailer.NewsHistoryDB news = new NewsMailer.NewsHisroryDB (GetConnStringO );&lt;BR&gt;832 Практический пример&lt;BR&gt;If получить ID выбранной строки&lt;BR&gt;int NewsID = int.Parse(NewsGrid.DataKeys[NewsGrid.Selectedlndex].ToStringO);&lt;BR&gt;// получить массив новостей из базы данных&lt;BR&gt;Body = news. GetDetails(NewsID) [&apos;Body].ToStringO;&lt;BR&gt;// если формат новостей не HTML, осуществить кодировку текста Body&lt;BR&gt;if (]Convert.ToBoolean(news.GetDetails(NewsID)[&quot;IsHTML&quot;]))&lt;BR&gt;Body = HttpUtility.HtmlEncode(Body);&lt;BR&gt;// заменить новые строки символами &lt;br&amp;gt;, чтобы показать их з элементе Label&lt;BR&gt;Body = Body.Replace (Ли* , &quot; ,Ъг&amp;gt;п) ;&lt;BR&gt;Body = Body. Replace ( *&amp;#92;*r&quot;, &quot; &quot;) ;&lt;BR&gt;// показать тело Body в элементе &quot;предварительный просмотр*&lt;BR&gt;MsgPreview.Text - Body;&lt;BR&gt;Msg Preview.Visible = true;&lt;BR&gt;Обратите внимание на то, что нам не приходится в данном случае заменять ни-&lt;BR&gt;каких специальных тегов, поскольку все они были заменены перед тем, как сооб-&lt;BR&gt;щение было помещено в архив, хранящийся в базе данных.&lt;BR&gt;Кроме того, в тот момент, когда администратор изменяет просматриваемую&lt;BR&gt;страницу таблицы данных, нам необходимо отказаться от выбранной строки, по-&lt;BR&gt;скольку эти действия автоматически не выполняются:&lt;BR&gt;protected void NewsGrid_PageChanged(Object sender, DataGridPageEventArgs e)&lt;BR&gt;{&lt;BR&gt;UnselectGridltemO ;&lt;BR&gt;/ / изменить текущую страницу для чтения данных&lt;BR&gt;NewsGrid.CurrentFagelndex - e.NewPageIndex;&lt;BR&gt;BindGridO ;&lt;BR&gt;}&lt;BR&gt;protected void UnselectGridltemO&lt;BR&gt;{&lt;BR&gt;// спрятать элемент &quot;предварительный просмотр&quot;&lt;BR&gt;NewsGrid.Selectedlndex = -1;&lt;BR&gt;MsgPreview.Text = * T;&lt;BR&gt;MsgPreview.Visible ~ false;&lt;BR&gt;Ш&lt;BR&gt;!tewt&amp;amp;«»tr««r - &quot; - &lt; - • • ; „ • 0 &quot;&lt;BR&gt;- • - ; &apos;• * , .*•-- **&lt;BR&gt;. . ,_„ .. :&lt;BR&gt;МЙММЯМ л&lt;BR&gt;В&lt;BR&gt;Изменение установок&lt;BR&gt;в режиме онлайн&lt;BR&gt;Нам уже неоднократно приходилось использо-&lt;BR&gt;вать значения, хранящиеся в XML-файле с установ-&lt;BR&gt;ками NewsMailer. Settings, которые МЫ определили&lt;BR&gt;в момент создания этого файла. Теперь нам потре-&lt;BR&gt;буется web-страница, позволяющая модифицировать&lt;BR&gt;эти установки в режиме онлайн — без необходимо-&lt;BR&gt;сти садиться перед web-сервером и вручную вно-&lt;BR&gt;сить изменения в базу данных. Страница, о которой&lt;BR&gt;идет речь, изображена на рисунке слева.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 833&lt;BR&gt;Страница Settings.aspx&lt;BR&gt;Страница ASP.NET формируется с помощью набора управляющих элементов,&lt;BR&gt;к которым привязываются соответствующие установки, хранящиеся в базе данных&lt;BR&gt;Settings. Они привязываются к общим переменным, значения которых задаются&lt;BR&gt;в коде поддержки, как и для страницы Send Email. Настоящая страница является&lt;BR&gt;очень большой, для иллюстрации ее работы мы приводим участок кода, в котором&lt;BR&gt;описывается поле Sender Email, а также происходит наполнение соответствующего&lt;BR&gt;текстового окна с выполнением дополнительной проверки допустимости:&lt;BR&gt;&lt;asp:TableRow&amp;gt;&lt;BR&gt;&lt;asp:TableCell Text=&quot;News Sender Email:&quot; /&amp;gt;&lt;BR&gt;&lt;asp:TableCel1&amp;gt;&lt;BR&gt;&lt;asp:TextBox runat=&quot;server&quot; Width=M500px&quot; ID-&quot;SenderEmail&quot;&lt;BR&gt;Сlass-&quot;TextBox&quot; Text=&apos;&lt;%# SenderEmailJValue %&amp;gt;&apos; /&amp;gt;&lt;BR&gt;&lt;asp:RequiredFieldValidator runat=&quot;server&quot;&lt;BR&gt;ContrclToValidate--&quot; SenderEnia.il&quot; ..&lt;BR&gt;Display=&quot;dynamic&quot;&amp;gt;&lt;br&amp;gt;* This field is required&lt;BR&gt;&apos; &lt;/asp:RequiredFieldValidator&amp;gt; :...,•&lt;BR&gt;&lt;asp:RegularExpressionValidator runat=&quot;server&quot;&lt;BR&gt;&apos; validationExpression^&quot;. *§. *&amp;#92; . . *w&lt;BR&gt;ControlToValidate=&quot;SenderEmail&quot;&lt;BR&gt;Display= &quot;dynamic&quot;&amp;gt;&lt;br&amp;gt;* This Email address is not; valid&lt;BR&gt;&lt;/asp:RegularExpressionVali -dator&amp;gt;&lt;BR&gt;&lt;/asp:TableCell&amp;gt;&lt;BR&gt;&lt;/asp:TableRow&amp;gt;&lt;BR&gt;Приведенный выше управляющий элемент является особенным, поскольку&lt;BR&gt;в нем присутствует не один, а два элемента, предназначенных для проверки допус-&lt;BR&gt;тимости: один из них позволяет гарантировать, что текстовое окно не является пу-&lt;BR&gt;стым в момент отправки формы, а второй — что строка с адресом электронной&lt;BR&gt;почты представлена в допустимом формате. В последнем случае используется&lt;BR&gt;ReguiarExpressionVaiidator, и, как следует из его названия, он выполняет про-&lt;BR&gt;верку допустимости регулярного выражения. В настоящем примере используется&lt;BR&gt;следующее выражение:&lt;BR&gt;&lt;asp:ReguiarExpressionVaiidator runat=&quot;server&quot;&lt;BR&gt;validationExpression=&quot; . * @ . * &amp;#92; . .*&quot; .. : . ;:&apos;:::&apos;::: ;4v&amp;gt; •;-*•;: • &apos;••-.••.•:.r&apos;::&apos;.:&quot;&apos;,&apos;--&apos;::/-ControlToValidate=&quot;SenderEmail&quot;&lt;BR&gt;Display=&quot;dynamicI1&amp;gt;&lt;br&amp;gt;* This Email address is not valid&lt;BR&gt;&lt;/asp:RegularExpressionValidator&amp;gt;&lt;BR&gt;Это означает, что строка должна начинаться с символов (.*), затем в ней должен&lt;BR&gt;находиться символ &apos;@&apos;, потом произвольные символы, затем точка (для которой&lt;BR&gt;используется escape-последовательность &amp;#92;.) и, наконец, произвольные символы.&lt;BR&gt;Например, mbeiiinaso@vb2themax.com представляет собой допустимый адрес элек-&lt;BR&gt;тронной ПОЧТЫ, В ТО время KaKmbellinaso@vb2themax ИЛИ mbellinaso.libero.it —&lt;BR&gt;недопустимые адреса.&lt;BR&gt;Регулярные выражения представляют собой весьма мощный инструмент для&lt;BR&gt;проверки допустимости содержимого управляющего элемента, поскольку названные&lt;BR&gt;выражения могут быть детальными и сложными; их использованию посвящены&lt;BR&gt;целые книги. Кроме того, существует возможность при написании функции, произ-&lt;BR&gt;водящей проверку допустимости, использовать метод CustomVaiidator, который&lt;BR&gt;позволяет осуществлять еще более жесткий контроль.&lt;BR&gt;834 Практический пример&lt;BR&gt;Код поддержки для файла Settings.aspx&lt;BR&gt;Код поддержки для внесения изменений в установки состоит из двух процедур:&lt;BR&gt;одна из них — это метод Page_Load(), предназначенный для извлечения установок&lt;BR&gt;из базы данных с помощью объектов AppConf ig и AppSettings и привязки их к со-&lt;BR&gt;ответствующим серверным управляющим элементам посредством вызова метода&lt;BR&gt;Page.DataB ind():&lt;BR&gt;protected void Page_JL.oad(object sender,EventArgs e) •&lt;BR&gt;• • • ••• • &quot; V • &lt; ./ .. • • ; &apos; -&lt;BR&gt;if ( UsFostBack) ;&lt;BR&gt;ШЩ••/.••:• &quot;&apos; • , ^ &lt; &apos; •&apos; ••••&quot;•;&apos; ;&lt;BR&gt;// загрузить Бее установки&lt;BR&gt;NewsMailer.AppSettings settings =&lt;BR&gt;NewsMailer. AppConf ig GetSettings (Server.MapPath(GetSettingsFiIe ().).);&lt;BR&gt;SubscribeURL_Value - settings.SubscribeURL;&lt;BR&gt;SenderName_Value = settings.SenderName;&lt;BR&gt;SenderEmail_Value ~ settings.SenderEmail; :&lt;BR&gt;NewsSubject_Value = settings.NewsSubject;&lt;BR&gt;SubscrSubject_Value = settings.SubscrSubject; : ;&lt;BR&gt;; SubscrMessage__Value - settings.SubscrMessage; : : •{.&lt;BR&gt;UnSubscrSubj ect__Value = settings.UnSubscrSubject;&lt;BR&gt;x : :: . •&apos;; UnSubscrMessage_Value = sett ings. UnSubscrMessage;&lt;BR&gt;; Signature_Value = settings.Signature;&lt;BR&gt;. SendSubscrEmai&apos;lJvalue = sett ings. SendSubscr Email;&lt;BR&gt;SendUnSubscrEmail_Value,= settings.SendUnSubscrEmail;&lt;BR&gt;••• &apos;:&apos; ••&apos;;• .:• , • &apos;•.&apos;•,•..,•&apos;• : .: •,• • P a g e . D a t a B i n d ( ) . ; . &apos; . • , . ; .••••&apos;:. , . &apos;/•..••&apos;•&apos;- ; . . : ; &apos; &apos; V &apos;;.}:•:&apos;,•/&apos;•&apos;&apos;.&apos;.[ . . . ... . .&lt;BR&gt;Вторая процедура — это update_ciick(), которая вызывается в момент, когда&lt;BR&gt;мышь щелкает кнопку Update. Эта процедура собирает новые значения установок,&lt;BR&gt;находящиеся в управляющих элементах, присваивает их свойствам нового объекта&lt;BR&gt;AppSettings и вызывает метод SaveSettings о объекта AppConf ig для сериализа-&lt;BR&gt;ЦИИ объекта settings В XML-фаЙЛ (в данном Случае — В NewsMailer. Settings):&lt;BR&gt;protected void Update_Click{object sender,EventArgs e)&lt;BR&gt;. . { . •. •, . • • • • . &apos; • : , • • . . • . • • • •: ;;. : &apos; &quot; : . v . . • •&apos;; v&lt;BR&gt;NewsMailer.AppSettings settings = new NewsMailer.AppSettings();&lt;BR&gt;// установить новые значения для всех свойств&lt;BR&gt;settings.SubscribeURL = SubscribeURL.Text;&lt;BR&gt;settings.SenderName = SenderName.Text ; ; •;&lt;BR&gt;settings.SenderEmail -SendarEmai.Text ; :&lt;BR&gt;settings.NewsSubject = NewsSubject.Text; :&lt;BR&gt;settings.SubscrSubject = SubscrSubject.Text;&lt;BR&gt;settings.SubscrMessage ~ SubscrMessage.Text;&lt;BR&gt;settings.UnSubscrSubject = UnSubscrSubject.Text;&lt;BR&gt;settings.UnSubscrMessage = UnSubscrMessage.Text;&lt;BR&gt;settings.Signature = Signature.Text ;&lt;BR&gt;settings.SendSubscrEmail = SendSubscrEmail.Checked;&lt;BR&gt;settings.SendUnSubscrEmail&apos;= SendUnSubscrEmail.Checked;&lt;BR&gt;NewsMailer .AppConf ig. SaveSettings (Server. Map?ath( Get Sett ingsFil.e (.)•) , settings) ;&lt;BR&gt;Изменение внешнего представления в режине онлайн&lt;BR&gt;В самом начале этого раздела говорилось о том, что все стили для управляю-&lt;BR&gt;щих элементов хранятся в отдельной таблице стилей, а не внутри страницы. На&lt;BR&gt;самом деле, &quot;зашитые&quot; в программу цвета и другие параметры стилей внешнего&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 835&lt;BR&gt;il&lt;BR&gt;Тле eg&lt;BR&gt;СсГг cJiapqt» any &lt;«lir.bu:e of c-rv/ HTN&apos;.L Sfement (ca&apos;or&lt;BR&gt;;?&apos;u: x.;r,-.5:i&amp;#92;efi«&apos;&quot;.iJ -&apos;•--=, sans-serif;&lt;BR&gt;font: м J&amp;gt;ml V^rdanii, AriaL sans-serif;&lt;BR&gt;1ЙЖ--Г&apos;&quot;&apos;&quot;&lt;BR&gt;^ : / - «is&lt;BR&gt;I&lt;BR&gt;•;.c&amp;gt;... ;h:;&lt; -&amp;gt;г.у|й sheet used by ever,1 paqo. Vou&lt;BR&gt;i, uz&lt;: tv.c.) зг&amp;gt;й «fror&amp;gt; press ?ha Updato button to&lt;BR&gt;1&lt;BR&gt;J&lt;BR&gt;!•&lt;BR&gt;_J&lt;BR&gt;представления всегда оборачиваются&lt;BR&gt;головной болью, когда необходимо&lt;BR&gt;внести какие-либо изменения, так как&lt;BR&gt;приходится вручную проходить по&lt;BR&gt;всем страницам и изменять все вхож-&lt;BR&gt;дения для стиля, который мы хотим&lt;BR&gt;модифицировать. Наличие таблицы&lt;BR&gt;стилей позволяет существенно упрос-&lt;BR&gt;тить жизнь. Однако, все равно было&lt;BR&gt;бы хорошо иметь возможность редак-&lt;BR&gt;тировать таблицу стилей в режиме&lt;BR&gt;онлайн, вместо того, чтобы вносить&lt;BR&gt;изменения в файл на локальном&lt;BR&gt;компьютере, а затем отправлять этот&lt;BR&gt;файл обратно на сервер. Реализация&lt;BR&gt;страницы, которая позволяет редакти-&lt;BR&gt;ровать файлы, требует всего лишь не-&lt;BR&gt;скольких минут и нескольких строк&lt;BR&gt;кода, и к созданию именно такой стра-&lt;BR&gt;ницы мы сейчас и приступим.&lt;BR&gt;На рисунке слева представлен наш&lt;BR&gt;простой редактор таблиц стилей.&lt;BR&gt;Если вы знаете CSS, то вы получаете возможность изменять стили управляю-&lt;BR&gt;щих элементов ASP.NET, а полное изменение стиля всего пользовательского ин-&lt;BR&gt;терфейса — это вопрос нескольких секунд!&lt;BR&gt;Страница Layout.aspx&lt;BR&gt;Этот файл не очень отличается от других управляющих элементов ASP.NET,&lt;BR&gt;поэтому мы не будем приводить здесь весь код полностью. Изображенная ниже&lt;BR&gt;строка кода, однако, требует дальнейших пояснений:&lt;BR&gt;&lt;asp:Label ID=&quot;FileNamen runat=&quot;Server&quot; Text=&quot;Styles.&quot;ess&quot; Visible=&quot;false&quot; /&amp;gt;&lt;BR&gt;В этой строке объявляется скрытая надпись, которая используется для задания&lt;BR&gt;имени файла, подлежащего редактированию.; это означает, что, изменяя эту уста-&lt;BR&gt;новку, мы получаем возможность редактировать произвольный текстовый файл.&lt;BR&gt;Администратору по-прежнему необходимо выполнить повторную загрузку, если он&lt;BR&gt;изменяет путь к файлу в скрытых управляющих элементах, однако это оказывается&lt;BR&gt;намного проще и быстрее, чем изменять значения в файлах с кодом поддержки,&lt;BR&gt;поскольку в таком случае приходится заново транслировать и загружать весь мо-&lt;BR&gt;дуль. Всегда помните, что приложение должно распространяться в откомпилиро-&lt;BR&gt;ванном виде, а отсюда следует, что если какая-нибудь установка будет &quot;зашита&quot;&lt;BR&gt;в программу, то это приведет к тому, что администратор сайта, работающий уда-&lt;BR&gt;ленно, окажется не в состоянии изменить ее без помощи разработчи</content:encoded>
			<link>https://krutoto.ucoz.ru/news/redaktirovanie_i_obnovlenie_spiskov/2010-02-11-410</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/redaktirovanie_i_obnovlenie_spiskov/2010-02-11-410</guid>
			<pubDate>Wed, 10 Feb 2010 22:00:57 GMT</pubDate>
		</item>
		<item>
			<title>Управление конфигурацией данных</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Управление конфигурацией данных&lt;BR&gt;&lt;/SPAN&gt;Программа рассылки новостей может быть настроена со спе-&lt;BR&gt;циальными подтверждениями, именем и электронным адресом&lt;BR&gt;администратора, и некоторыми другими опциями (со всеми воз-&lt;BR&gt;можными опциями мы вскоре познакомимся). Использование же-&lt;BR&gt;стко заданных в программе значений этих опций является плохим&lt;BR&gt;подходом, так как при возникновении у администратора необходи-&lt;BR&gt;мости изменить некоторую опцию (например, свой адрес элект-&lt;BR&gt;ронной почты), ему придется вносить соответствующие изменения&lt;BR&gt;в исходный код, компилировать весь проект заново и загружать&lt;BR&gt;новый модуль. Это серьезная проблема, особенно если админист-&lt;BR&gt;ратор сайта не является программистом. Поэтому мы будем хра-&lt;BR&gt;нить все установки в виде внешнего файла, из которого их будет&lt;BR&gt;очень просто считывать и записывать, а также выводить на стра-&lt;BR&gt;ницу, позволяя администратору с легкостью изменять любые&lt;BR&gt;значения без повторной компиляции и пере...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Управление конфигурацией данных&lt;BR&gt;&lt;/SPAN&gt;Программа рассылки новостей может быть настроена со спе-&lt;BR&gt;циальными подтверждениями, именем и электронным адресом&lt;BR&gt;администратора, и некоторыми другими опциями (со всеми воз-&lt;BR&gt;можными опциями мы вскоре познакомимся). Использование же-&lt;BR&gt;стко заданных в программе значений этих опций является плохим&lt;BR&gt;подходом, так как при возникновении у администратора необходи-&lt;BR&gt;мости изменить некоторую опцию (например, свой адрес элект-&lt;BR&gt;ронной почты), ему придется вносить соответствующие изменения&lt;BR&gt;в исходный код, компилировать весь проект заново и загружать&lt;BR&gt;новый модуль. Это серьезная проблема, особенно если админист-&lt;BR&gt;ратор сайта не является программистом. Поэтому мы будем хра-&lt;BR&gt;нить все установки в виде внешнего файла, из которого их будет&lt;BR&gt;очень просто считывать и записывать, а также выводить на стра-&lt;BR&gt;ницу, позволяя администратору с легкостью изменять любые&lt;BR&gt;значения без повторной компиляции и перезагрузки.&lt;BR&gt;XML-файл установок&lt;BR&gt;Все установки обычно хранятся в базе данных или в текстовом файле. Если&lt;BR&gt;выбрать базу данных, то потребуется завести целую таблицу для хранения всего&lt;BR&gt;лишь нескольких установок. Можно бы хранить все установки либо в одной строке&lt;BR&gt;(со многими столбцами), либо по одной установке в каждой строке. Такое решение&lt;BR&gt;оказывается весьма простым — просто еще одна таблица и еще один класс в мо-&lt;BR&gt;дуле NewsMailerDB, однако оно означает неэффективное использование ресурсов&lt;BR&gt;базы данных. Хорошим решением является использование XML-файла, который&lt;BR&gt;обладает вполне подходящим форматом для хранения установок приложения.&lt;BR&gt;В .NET Framework также предусмотрены классы, позволяющие легко считывать&lt;BR&gt;и записывать все установки и представлять их в виде свойств класса несколькими&lt;BR&gt;строками кода. Этот код будет рассмотрен ниже, а пока начнем с объяснения са-&lt;BR&gt;мих установок.&lt;BR&gt;Файл NewsMaiier. settings используется для хранения строки соединения с ба-&lt;BR&gt;зой данных всех установок, а также приложения за исключением касающихся&lt;BR&gt;внешнего представления приложения. Все возможные установки перечислены&lt;BR&gt;в приводимой ниже таблице.&lt;BR&gt;Установки NewsSubject, [Un]SubscriptionSubject И [Un]SubscriptionMessage&lt;BR&gt;могут содержать в себе специальные теги, например, #subscriberFirstName# или&lt;BR&gt;806 Практический пример&lt;BR&gt;#ListDescription#, которые будут заменяться на соответствующие им значения&lt;BR&gt;перед отправкой каждого сообщения. Позднее в настоящем разделе мы детально&lt;BR&gt;разберем эту возможность.&lt;BR&gt;Название установки Тип&lt;BR&gt;Допускается&lt;BR&gt;значение null Описание&lt;BR&gt;SenderName&lt;BR&gt;SenderEmail&lt;BR&gt;NewsSubject&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;Да&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Signature&lt;BR&gt;SubscriptionSubject&lt;BR&gt;SubscriptionMessage&lt;BR&gt;UnSubscriptionSubj ect&lt;BR&gt;UnSubscriptionMessage&lt;BR&gt;SendSubscriptionEmail&lt;BR&gt;SendUnSubscriptionEmai1&lt;BR&gt;SubscribeURL&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;string&lt;BR&gt;bool&lt;BR&gt;bool&lt;BR&gt;string&lt;BR&gt;Да&lt;BR&gt;Нет&lt;BR&gt;Да&lt;BR&gt;Нет&lt;BR&gt;Да&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Имя отправителя новостей&lt;BR&gt;Адрес электронной почты отправителя&lt;BR&gt;новостей&lt;BR&gt;Предмет новостного сообщения,&lt;BR&gt;использующийся по умолчанию.&lt;BR&gt;У администратора есть возможность&lt;BR&gt;создать сообщение, добавив произвольный&lt;BR&gt;текст к этой строке непосредственно&lt;BR&gt;из страницы&lt;BR&gt;Подпись, которая будет автоматически&lt;BR&gt;добавляться в конец сообщения&lt;BR&gt;Предмет сообщения, отправляемого&lt;BR&gt;по электронной почте в качестве&lt;BR&gt;подтверждения успешной подписки&lt;BR&gt;Тело сообщения, отправляемого&lt;BR&gt;по электронной почте в качестве&lt;BR&gt;подтверждения успешной подписки&lt;BR&gt;Предмет сообщения, отправляемого&lt;BR&gt;по электронной почте в качестве&lt;BR&gt;подтверждения успешного отказа&lt;BR&gt;от подписки&lt;BR&gt;Тело сообщения, отправляемого&lt;BR&gt;по электронной почте в качестве&lt;BR&gt;подтверждения успешного отказа&lt;BR&gt;от подписки&lt;BR&gt;Если это значение равно t r u e , то новые&lt;BR&gt;подписчики будут получать по электронной&lt;BR&gt;почте подтверждение о том, что подписка&lt;BR&gt;прошла успешно&lt;BR&gt;Если это значение равно t r u e ,&lt;BR&gt;то существующие подписчики будут&lt;BR&gt;получать по электронной почте сообщение&lt;BR&gt;о том, что их подписка завершена&lt;BR&gt;Полный URL страницы Subscribe.ASP.NET,&lt;BR&gt;который используется для добавления или&lt;BR&gt;удаления пользователя из списка&lt;BR&gt;В этой таблице приводятся различные типы установок; все установки хранятся&lt;BR&gt;в XML-файле в виде строк. Этот тип обозначает тип свойства класса, которому&lt;BR&gt;(свойству) соответствует значение данной установки. Столбец &quot;Допускается значе-&lt;BR&gt;ние null&quot; имеет аналогичный смысл: в нем описываются установки, которые могут&lt;BR&gt;отсутствовать в файле установок. Не существует никакого файла со схемой, кото-&lt;BR&gt;рая позволяла бы получать подтверждение того, что та или иная установка на&lt;BR&gt;самом деле присутствует в файле установок — страница ASP.NET, которая ис-&lt;BR&gt;пользуется для их считывания и изменения, отвечает за сохранение допустимости&lt;BR&gt;структуры файла.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 807&lt;BR&gt;XML-файл выглядит приблизительно следующим образом:&lt;BR&gt;&lt;?xml version^&apos;l .0&quot; encodings&quot;utf-8&quot;?&gt;&lt;BR&gt;&lt;AppSettings&amp;gt; :&lt;BR&gt;&lt;SenderName&amp;gt;NewsMailer Team&lt;/SenderName&amp;gt; •. &apos; :&lt;BR&gt;&lt;SenderEmail&amp;gt;admin@newsmailerserver.com&lt;/SenderEmail&amp;gt;&lt;BR&gt;&lt;NewsSubject&amp;gt;News 4 you: #ListName#&lt;/ NewsSubject&amp;gt;&lt;BR&gt;; , &lt;Signature&amp;gt;The NewsMailer Team&lt;/Signature&amp;gt; :&lt;BR&gt;&lt;SubscrSubject&amp;gt;Welcome to the mailing list #ListName#&lt;/SubscrSubject&amp;gt;&lt;BR&gt;&lt;SubscrMessage&amp;gt;Welcome dear subscriber&lt;/SubscrMessage&amp;gt;&lt;BR&gt;&lt;UnSubscrSubj ect&amp;gt;Bye bye from #ListName#&lt;/UnS&apos;ubscrSubj ect&amp;gt;&lt;BR&gt;&lt;UnSubscrMessage&amp;gt;You&apos;ve been removed from #ListName#&lt;/UnSubscrMessage&amp;gt;&lt;BR&gt;&lt;SendSubscrEmail&amp;gt;true&lt;/SendSubscrEmail&amp;gt;&lt;BR&gt;&lt;SendUnSubscrEmail&amp;gt;true&lt;/SendUnSubscrEmail&amp;gt;&lt;BR&gt;&lt;SubscribeURL&amp;gt;http://localhost/newsmailer/subscribe.aspx&lt;/SubscribeURL&amp;gt;&lt;BR&gt;• ••,&apos;•••&lt;•/ A p p S e t t i n g s &amp;gt;&lt;BR&gt;Модуль NewsMailerConfig&lt;BR&gt;Сериализация объекта — это процесс сохранения состояния данного объекта&lt;BR&gt;в памяти или в виде постоянного двоичного или ASCII-файла. Под состоянием&lt;BR&gt;объекта понимается множество всех его свойств, значений и ссылок на другие&lt;BR&gt;объекты. Напротив, десериализация приводит к созданию нового объекта, состоя-&lt;BR&gt;ние которого определяется данными, хранящимися в некотором файле. .NET Framework&lt;BR&gt;существенно упрощает выполнение сериализации и десериализации за счет&lt;BR&gt;множества классов, которые позволяют работать с несколькими различными фор-&lt;BR&gt;матами хранения.&lt;BR&gt;Если вы используете VS.NET, создайте для начала новый проект типа class&lt;BR&gt;Library и переименуйте установленный по умолчанию файл класса в AppConfig.cs.&lt;BR&gt;Если вы набираете текст с помощью текстового редактора, то сохраните этот файл&lt;BR&gt;в директории NewsMaiier&amp;#92;config. Ниже приводится сводная таблица класса&lt;BR&gt;AppSettings, который отвечает за создание XML-файлов, подобных приведенному&lt;BR&gt;выше, из сериализованных экземпляров. Этот файл состоит из множества общих&lt;BR&gt;свойств, имена которых совпадают с именами соответствующих свойств из XML-&lt;BR&gt;файла.&lt;BR&gt;Все свойства класса AppSettings помечены атрибутом XmlElement. Это сделано&lt;BR&gt;именно так, поскольку требуется, чтобы все эти свойства могли быть сериализова-&lt;BR&gt;ны в виде XML, а для этого используется класс xmiseriaiizer из пространства&lt;BR&gt;имен System.Xml.Serialization. Поскольку класс AppSettings не обладает мето-&lt;BR&gt;дами, позволяющими ему сериализовать и десериализовать себя, эта задача возла-&lt;BR&gt;гается на класс поддержки AppConfig, также хранящийся в файле AppConfig.cs.&lt;BR&gt;Вот содержимое этого класса:&lt;BR&gt;Класс AppConfig&lt;BR&gt;Метод Описание&lt;BR&gt;public static AppSettings GetSettings (string fileName) Находит XML-файл, в котором хранятся&lt;BR&gt;все установки, и создает объект класса&lt;BR&gt;AppSettings, содержащий эти данные&lt;BR&gt;public static void SaveSettings (string fileName, Получает объект AppSettings&lt;BR&gt;AppSettings data) и записывает хранящиеся в нем данные&lt;BR&gt;в указанный XML-файл&lt;BR&gt;808 Практический пример&lt;BR&gt;Эти два метода достаточно сложны, поэтому мы объясним их более подробно.&lt;BR&gt;Для начала приведем код метода GetSettingsO:&lt;BR&gt;public static AppSettings GetSettings(string fileName)&lt;BR&gt;;: HttpContext = HttpContext.Current;&lt;BR&gt;AppSettings data = (AppSettings)context.Cache[&quot;AppSettings*];&lt;BR&gt;if (data == null)&lt;BR&gt;{&lt;BR&gt;XmlSerializer serializer = new XmlSerializer(typeof(AppSettings));&lt;BR&gt;try&lt;BR&gt;{&lt;BR&gt;// создать файловый поток для чтения XML-документа&lt;BR&gt;: FiieStream fs = new FileStream(filename. FileMode,Open);&lt;BR&gt;XmlReader ~ new XmlTextReader (fs);&lt;BR&gt;: i;; : // посмотреть состояние объекта :&lt;BR&gt;data - (AppSettings)seriallizer.Deserialize(reader);&lt;BR&gt;reader.CloseO ;&lt;BR&gt;: : : ; ; context.Cache.Insert(•AppSettings&quot;, data,&lt;BR&gt;: new CacheDependency(filename));&lt;BR&gt;} &apos; &quot;&apos;..&apos; ..;,-:&lt;BR&gt;:;&lt;BR&gt;• : catch (System.10.FileNotFoundException) ; :&lt;BR&gt;{ ••&apos;.&apos;• &apos; &apos; :.--:.: ••:•&lt;BR&gt;// если файл не найден, вернуть новый пустой класс&lt;BR&gt;data = new AppSettings () ;&lt;BR&gt;) &apos; I • l l l l i l l&lt;BR&gt;return data;&lt;BR&gt;}&lt;BR&gt;Прежде всего данный метод осуществляет проверку, не находится ли объект&lt;BR&gt;с данными установками в кэш-памяти, куда он попадает при первом обращении&lt;BR&gt;к методу. Если объект уже находится в кэш-памяти, то метод GetSettingsO про-&lt;BR&gt;сто возвращает эти данные. Если объект в кэш-памяти отсутствует, то сначала со-&lt;BR&gt;здается объект XmlSerializer, затем осуществляется открытие параметра файла,&lt;BR&gt;указанного в качестве первого, после чего для потока файла создается объект&lt;BR&gt;XmlTextReader. В завершение состояние объекта извлекается посредством метода&lt;BR&gt;Deserialize () объекта XmlSerializer, а ПОЛученНЫЙ В результате всех ЭТИХ дей-&lt;BR&gt;ствий объект AppSettings помещается в кэш-память для последующего использо-&lt;BR&gt;вания.&lt;BR&gt;В этой программе есть несколько примечательных моментов. Первый заключа-&lt;BR&gt;ется в том, что путь к файлу с установками не &quot;зашит&quot; в программу, а передается&lt;BR&gt;в качестве параметра. Это необходимо, поскольку данный код будет откомпилиро-&lt;BR&gt;ван в модуль и может быть использован произвольным клиентом, поэтому файл&lt;BR&gt;с установками может располагаться в различных местах.&lt;BR&gt;Вторым любопытным моментом является способ, с помощью которого установ-&lt;BR&gt;ки переносятся в кэш. Обратите внимание на следующую строку кода:&lt;BR&gt;Context.Cache.Insert(&quot;AppSettings&quot;, data, new CacheDependency(fileMame));&lt;BR&gt;Третий параметр означает, что информация, хранящаяся в кэш-памяти, зависит&lt;BR&gt;от файла, который передается в качестве параметра. Если этот файл обновляется,&lt;BR&gt;то информация, хранящаяся в кэш-памяти, более не считается правильной, поэто-&lt;BR&gt;му при повторном обращении к установкам необходимо выполнить десериализа-&lt;BR&gt;цию файла еще раз. Тот факт, что состояние файла отслеживается автоматически,&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 809&lt;BR&gt;является замечательной особенностью кэширования в ASP.NET, которая позволя-&lt;BR&gt;ет вносить изменения в содержимое файла установок с помощью произвольного&lt;BR&gt;редактора, перезагружать файл и при этом знать, что все установки будут перезаг-&lt;BR&gt;ружены в кэш-память.&lt;BR&gt;И последний момент: когда состояние объекта перезагружается из файла, то&lt;BR&gt;все установки, хранящиеся в XML-файле в виде строк, автоматически приводятся&lt;BR&gt;к тому типу, которым обладает соответствующее свойство.&lt;BR&gt;Метод Savesettingso обладает структурой, аналогичной структуре метода Get-&lt;BR&gt;Settings О:&lt;BR&gt;&quot; public static void SaveSettings(string FileName, AppSettings data)&lt;BR&gt;{&lt;BR&gt;XmlSerializer =; new XmlSerializer (typeof (AppSettings) );&lt;BR&gt;II Создать XmiTextWriter используя FileStream&lt;BR&gt;FileStream fs = new FileStream(fileName, FileMode.Create);&lt;BR&gt;XmiTextWriter writer = new XmiTextWriter (fs, new UTF8 Encoding&apos;() ) ;&lt;BR&gt;// Осуществить сериализацию, используя XmiTextWriter&lt;BR&gt;serializer.Serialize(writer, data);&lt;BR&gt;writer.Close();&lt;BR&gt;ЩщЩташш&lt;BR&gt;i *j&lt;BR&gt;- Ш References&lt;BR&gt;|&lt;BR&gt;I L~ Ш AssembiyInfoConf.es&lt;BR&gt;ЁЗ- • Ш NewsMailerDB&lt;BR&gt;^ Solution Explorer | &lt;d$ Cia?&amp;gt; View&lt;BR&gt;Единственный новый момент заключается в том, что некото-&lt;BR&gt;рые символы, например &apos;&lt;&apos; и &apos;&amp;gt;&apos;, кодируются, поскольку с точки&lt;BR&gt;зрения XML они обладают особым смыслом (они используются&lt;BR&gt;для обрамления XML-тегов). Способ такого кодирования задает-&lt;BR&gt;ся В КОНСТрукторе объекта XmiTextWriter.&lt;BR&gt;Компиляция модуля&lt;BR&gt;Если вы вели разработку в Visual Studio.NET, то ваш Solution&lt;BR&gt;Explorer должен принять вид, изображенный на рисунке слева.&lt;BR&gt;При этом в режиме Class&lt;BR&gt;картинка, представленная на&lt;BR&gt;View должна выводиться следующая&lt;BR&gt;рисунке справа.&lt;BR&gt;Управление&lt;BR&gt;пользовательским интерфейсом&lt;BR&gt;Разработка базы данных и бизнес-классов завершена, т. е.&lt;BR&gt;большая часть работы уже выполнена. Теперь мы собираемся за-&lt;BR&gt;няться разработкой пользовательского интерфейса приложения,&lt;BR&gt;а также использовать бизнес-классы для чтения и записи данных&lt;BR&gt;из базы данных.&lt;BR&gt;Прежде чем переходить к рассмотрению кода на ASP.NET&lt;BR&gt;и С#, взглянем на некоторую часть результатов, к которым мы&lt;BR&gt;стремимся (см. рис. на стр. 810).&lt;BR&gt;Страница, изображенная на указанном рисунке, позволяет ад-&lt;BR&gt;министратору просматривать имеющиеся в наличии списки рас-&lt;BR&gt;сылки, создавать, уничтожать или редактировать эти списки,&lt;BR&gt;а также переходить к списку подписчиков или к другим страницам&lt;BR&gt;приложения. В таблице на данной странице показаны все списки,&lt;BR&gt;которые были получены из базы данных, в ней также выводятся&lt;BR&gt;• ^ Е Я Е&lt;BR&gt;е - о w«&lt;BR&gt;и&lt;BR&gt;1•&lt;BR&gt;&amp;gt;.. • ,t,&amp;#92;M,i &apos;-, ~*&lt;BR&gt;miiTHiii&lt;BR&gt;-г,ф (JetOc{«!s(ir»t)&lt;BR&gt;•**&amp;pound; Bases ^tnd Merf^ces&lt;BR&gt;*i|# AdtffUMtrinQj »Ь*ЧЬ string)&lt;BR&gt;-%ф 6atSJw&lt;rlO0fttHrinfl)&lt;BR&gt;• ? F : . - * Г .&lt;BR&gt;810 Практический пример&lt;BR&gt;IS &lt;VewsM«ili?r vi,0 Copynght 20&lt;BR&gt;11 Usls f Subsetors i SoniJFn&lt;BR&gt;jjs^nd 5fi^ &amp;pound;rnsi to a list *•&lt;BR&gt;ШШЯ&lt;BR&gt;ij? 2Г i VB.NST&lt;BR&gt;j j f Ш z * A S P J M S T г *&lt;BR&gt;&lt;iil i fcmvs l i i s t o r&lt;BR&gt;i&lt;BR&gt;ШИШ&lt;BR&gt;Visual Basic.NET- оё¥« rui ц&lt;BR&gt;rd 1 Settings i&lt;BR&gt;I! &lt;**&lt;BR&gt;Щ&lt;BR&gt;1&amp;gt;&lt;BR&gt;их свойства и предусматривается воз-&lt;BR&gt;можность их сортировки по значению&lt;BR&gt;одного из следующих свойств: ID,&lt;BR&gt;Name, Description. Все ИКОНКИ, ВЫВО-&lt;BR&gt;дящиеся в таблице (рисунки, распо-&lt;BR&gt;ложенные левее столбца ID И правее&lt;BR&gt;столбца Description), представляют&lt;BR&gt;собой гиперссылки на другие страни-&lt;BR&gt;цы, позволяющие выполнять какие-&lt;BR&gt;либо другие действия над данным&lt;BR&gt;списком или над данной строкой.&lt;BR&gt;Ниже приводится перечень иконок,&lt;BR&gt;которые могут располагаться внутри&lt;BR&gt;таблицы с описанием выполняемых&lt;BR&gt;ими действий.&lt;BR&gt;Если вы когда-либо программиро-&lt;BR&gt;вали на обычном ASP, то вы, вероятно,&lt;BR&gt;думаете, что для этой таблицы потре-&lt;BR&gt;буется большой объем сложного кода,&lt;BR&gt;позволяющего управлять гиперссылка-&lt;BR&gt;ми, рисунками, изменением цвета строк,&lt;BR&gt;сортировкой данных и т. п. Но вы уди-&lt;BR&gt;витесь, насколько просто всего этого&lt;BR&gt;можно добиться с помощью ASP.NET&lt;BR&gt;и нескольких строк кода на С#.&lt;BR&gt;Все приложение состоит из несколь-&lt;BR&gt;ких страниц ASP.NET, большинство из&lt;BR&gt;которых относится к административно-&lt;BR&gt;му разделу. На диаграмме (см. стр. 811)&lt;BR&gt;приводится стандартное расположение&lt;BR&gt;страницы, а также полный список всех&lt;BR&gt;страниц, имен файлов, в которых они&lt;BR&gt;хранятся, и соответствующих файлов&lt;BR&gt;и классов с кодом поддержки.&lt;BR&gt;Иконка Описание&lt;BR&gt;_&lt;BR&gt;Редактирование записи&lt;BR&gt;Удаление записи&lt;BR&gt;Переход на страницу, на которой выводятся&lt;BR&gt;подписчики данного списка рассылки&lt;BR&gt;Переход на страницу, на которой выводятся&lt;BR&gt;прошлые сообщения, отправленные&lt;BR&gt;в соответствии с данным списком рассылки&lt;BR&gt;Переход на страницу, на которой составляется&lt;BR&gt;и отправляется новое сообщение подписчикам,&lt;BR&gt;входящим в данный список рассылки&lt;BR&gt;Создание&lt;BR&gt;пользовательских управляющих элементов&lt;BR&gt;Если есть некоторые составные части пользовательского интерфейса, которые&lt;BR&gt;требуется использовать более, чем на одной странице, то следует подумать о том,&lt;BR&gt;каким образом можно использовать код повторно без копирования и переноса его&lt;BR&gt;из одной страницы в другую. В данной программе мы хотим иметь возможность&lt;BR&gt;общего использования заголовка и нижней части страницы, которые соответствен-&lt;BR&gt;но представляют собой верхнее меню и маленькую иконку, расположенную внизу&lt;BR&gt;справа непосредственно под таблицей и позволяющую возвращаться на начало&lt;BR&gt;страницы. В традиционном ASP потребовалось бы включить два отдельных файла&lt;BR&gt;посредством директивы &lt;I--#INCLUDE --&amp;gt;, однако в ASP.NET есть лучшая альтер-&lt;BR&gt;натива — пользовательские управляющие элементы. С их помощью можно выде-&lt;BR&gt;лить общий код в отдельный файл, который может быть в дальнейшем использован&lt;BR&gt;везде, где в этом возникнет необходимость, путем присваивания имени импортиру-&lt;BR&gt;емому управляющему элементу, изменения его общих свойств или вызова общих&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 811&lt;BR&gt;Меню&lt;BR&gt;(Header.ascx)&lt;BR&gt;Страница ASBNET&lt;BR&gt;Нижняя часть&lt;BR&gt;(Footer.ascx)&lt;BR&gt;Страницы ASP.NET&lt;BR&gt;Страницы управления Прочие страницы&lt;BR&gt;щ&lt;BR&gt;i l l&lt;BR&gt;ь о&lt;BR&gt;Модуль NewsMailer.dll (классы кода поддержки)&lt;BR&gt;со со&lt;BR&gt;Si 8%&lt;BR&gt;&amp;amp;9&lt;BR&gt;методов, которыми он обладает. Другими словами, это не просто участок кода,&lt;BR&gt;вставляемый в нашу страницу, он представляет собой графический компонент,&lt;BR&gt;обладающий собственным именем и атрибутами. Являясь серверным компонентом,&lt;BR&gt;он, как и другие серверные компоненты ASP.NET, обрабатывается на сервере,&lt;BR&gt;а все, что получает браузер пользователя, — это стандартный HTML, совмести-&lt;BR&gt;мый с любым браузером.&lt;BR&gt;В нашем проекте используются два пользовательских управляющих элемента:&lt;BR&gt;Пользовательский&lt;BR&gt;управляющий элемент Описание&lt;BR&gt;Header.ascx&lt;BR&gt;Footer.ascx&lt;BR&gt;Осуществляет добавление заголовка, общего для всех страниц web-сайта.&lt;BR&gt;Этот управляющий элемент состоит из трех частей:&lt;BR&gt;• Раздел заголовка, представленного в виде таблицы,&lt;BR&gt;в которой хранятся текст и логотип.&lt;BR&gt;• Еще одна таблица, в которой хранятся ссылки на другие web-страницы.&lt;BR&gt;• Надпись, представляющая собой текст, который описывает&lt;BR&gt;каждую из ссылок, когда на нее указывает курсор мыши.&lt;BR&gt;Содержит всего лишь образ ссылки, которая переносит пользователя&lt;BR&gt;обратно на начало страницы.&lt;BR&gt;812 Практический пример&lt;BR&gt;Использование пользовательских&lt;BR&gt;управляющих элементов на web-странице&lt;BR&gt;Чтобы использовать управляющий элемент из web-страницы, необходимо заре-&lt;BR&gt;гистрировать его из этой страницы, указав имя исходного файла и префикс, позво-&lt;BR&gt;ляющий отличать его от других серверных управляющих элементов. Следующие&lt;BR&gt;две строки должны быть включены в начало страницы:&lt;BR&gt;&lt;%@ Register TagPrefix=!lNewsMailer&quot; TagName--&quot;Header&quot; src-&quot;Header.ascx&quot; %&amp;gt;&lt;BR&gt;&lt;%@ Register TagPrefJ.x-!1NewsMailer&quot; TagName=&quot;Footer&quot; src=&quot;Footer.ascx11 %&amp;gt;&lt;BR&gt;Ниже приводится код, который позволяет добавить пользовательские управля-&lt;BR&gt;ющие Элементы Header И Footer на обычную Страницу:&lt;BR&gt;&lt;html&amp;gt;&lt;BR&gt;&lt;head&amp;gt;&lt;BR&gt;&lt;title&amp;gt;NewsMailer: Subscribers&lt;/title&amp;gt;&lt;BR&gt;&lt;link rel=&quot;stylesheet&quot; HREF=&quot;Styles.ess&quot; TYPE=&quot;text/ess&quot;&amp;gt;&lt;BR&gt;&lt;/head&amp;gt;&lt;BR&gt;&lt;body&amp;gt;&lt;BR&gt;&lt;!— Insert the menu user control — &amp;gt;&lt;BR&gt;&lt;NewsMailer:Header id=&quot;Menu&quot; runat=&quot;server&quot; /&amp;gt;&lt;BR&gt;&lt;b&amp;gt; Some HTML code&lt;/b&amp;gt;&lt;BR&gt;runat^&quot;server&quot; /&amp;gt;&lt;BR&gt;а&amp;gt;/ «*• fwvkm tafe&lt;BR&gt;&lt;!— Insert the footer — &amp;gt;&lt;BR&gt;&lt;NewsMailer:Footer id=&quot;Footer&quot;&lt;BR&gt;&lt;/body&amp;gt;&lt;BR&gt;&lt;/html&amp;gt;&lt;BR&gt;Страница управления списками&lt;BR&gt;На ранее представленном рисунке страница управления списками рассылки&lt;BR&gt;изображена в том виде, в каком она появляется на экране сразу после загрузки.&lt;BR&gt;Однако ее внешний вид может претерпевать определенные изменения в зависи-&lt;BR&gt;мости от предпринимаемых дей-&lt;BR&gt;ствий. Вот что вы увидите, если&lt;BR&gt;нажмете на иконку с изображе-&lt;BR&gt;нием блокнота и ручки, располо-&lt;BR&gt;женную у самого левого края,&lt;BR&gt;для того чтобы отредактировать&lt;BR&gt;список (см. рис. слева).&lt;BR&gt;Свойства Name И Description&lt;BR&gt;текущей страницы выводятся&lt;BR&gt;внутри двух текстовых окон, и у&lt;BR&gt;администратора есть возмож-&lt;BR&gt;ность изменить эти значения,&lt;BR&gt;после чего щелкнуть мышью&lt;BR&gt;либо на зеленой иконке с галоч-&lt;BR&gt;кой, чтобы сохранить эти изме-&lt;BR&gt;нения в базе данных, либо на X,&lt;BR&gt;для того чтобы отказаться от этой операции. Обратите внимание на то, что стол-&lt;BR&gt;бец ID не подлежит редактированию, поскольку он используется в качестве счет-&lt;BR&gt;чика и его значение не может быть изменено, а также на то, что списки&lt;BR&gt;отсортированы по имени, а не по ID, как прежде. Для сортировки необходимо&lt;BR&gt;щелкнуть мышью на заголовке того столбца, по значениям которого вы хотите&lt;BR&gt;произвести сортировку.&lt;BR&gt;Hosting offers izt ASP.NgT applications&lt;BR&gt;vjsva? BssfciiST • ftfcwi and tips&lt;BR&gt;Практический пример 2 — Менеджер &apos;рассылки новостей в режиме онлайн 813&lt;BR&gt;Для того чтобы добавить новый список, администратор должен щелкнуть мышью&lt;BR&gt;на кнопке Button, расположенной слева вверху основной страницы. Вот к какому&lt;BR&gt;результату это приведет:&lt;BR&gt;Add New Mame iOescription&lt;BR&gt;I&lt;BR&gt;На экран выводятся два пустых текстовых окна, и администратор заполняет их,&lt;BR&gt;вводя названия и описание того списка рассылки, который он собирается созда-&lt;BR&gt;вать. Выполнение этой операции может быть подтверждено или отменено посред-&lt;BR&gt;ством двух иконок, расположенных с левой стороны. В обоих случаях (это также&lt;BR&gt;справедливо и для редактирования) текстовые окна убираются, а картинка возвра-&lt;BR&gt;щается к своему первоначальному состоянию. Если нажать иконку для редактиро-&lt;BR&gt;вания новой строки, то такой эффект достигается почти автоматически, и тогда&lt;BR&gt;при добавлении новой строки приходится обрабатывать события управляющих&lt;BR&gt;элементов для вывода или свертывания текстовых окон самостоятельно. Этот про-&lt;BR&gt;цесс оказывается намного проще, чем может показаться на первый взгляд — для&lt;BR&gt;его осуществления необходимо написать всего лишь несколько строк кода, к чему&lt;BR&gt;мы перейдем буквально через минуту.&lt;BR&gt;Страница Lists&amp;#92;aspx&lt;BR&gt;Это страница ASP.NET, в которой описывается пользовательский интерфейс;&lt;BR&gt;в ней может также храниться код описания сценария, как и на страницах ASP.&lt;BR&gt;Одно из наиболее значимых преимуществ ASP.NET заключается в том, что код&lt;BR&gt;оказывается отделенным от пользовательского интерфейса за счет использования&lt;BR&gt;файлов с кодом поддержки — этот термин мы будем очень часто использовать по&lt;BR&gt;- ходу настоящего раздела (и который мы уже несколько раз использовали, не давая&lt;BR&gt;ему определения). В файле с кодом поддержки находится один или более классов,&lt;BR&gt;которые обрабатывают все события, возникающие в web-странице. Разделение этих&lt;BR&gt;двух уровней позволяет web-дизайнеру вносить изменения во внешнее представле-&lt;BR&gt;ние web-страниц без необходимости разбираться в запутанном коде на VBScript&lt;BR&gt;или Jscript, который распределен по всей странице вперемешку с HTML-кодом.&lt;BR&gt;Файлы с кодом поддержки могут быть откомпилированы в отдельный модуль, что&lt;BR&gt;существенно упрощает установку приложения (поскольку в этом случае приходит-&lt;BR&gt;ся загружать только один DLL-файл вместо нескольких исходных файлов с кодами&lt;BR&gt;на С#) и повышает уровень обеспечения безопасности вашего приложения в том&lt;BR&gt;смысле, что если кто-то получит доступ к серверу, то он не сможет также быстро&lt;BR&gt;прочитать бизнес-код, как в случае с ASP.&lt;BR&gt;Чтобы создать страницу Lists.aspx в VS.NET, выберите пункт меню Project |&lt;BR&gt;Add Web Form. При работе в любом другом редакторе просто создайте новый файл&lt;BR&gt;В папке NewsMailer.&lt;BR&gt;Исходный код для этой страницы слишком велик, чтобы приводить его цели-&lt;BR&gt;ком, поэтому будем останавливаться только на тех его участках, которые представ-&lt;BR&gt;ляют для нас интерес как для программистов на С#. В первой строке содержится&lt;BR&gt;описание того, какой базовый класс используется при обработке событий, возни-&lt;BR&gt;кающих на данной странице:&lt;BR&gt;&lt;%@ Page language=nc#&quot; Inherits^&quot;NewsMailer.Lists&quot; %&amp;gt;&lt;BR&gt;814 Практический пример&lt;BR&gt;В этом классе содержится весь код, который выполняется при загрузке данной&lt;BR&gt;страницы при нажатии клавиши, а также когда мы хотим добавить, удалить или&lt;BR&gt;отредактировать какой-либо список рассылки. Этот класс, называющийся Lists,&lt;BR&gt;входит в состав пространства имен NewsMaiier и компилируется в отдельный мо-&lt;BR&gt;дуль NewsMaiier.dll, к рассмотрению которого мы перейдем позднее. Страница&lt;BR&gt;автоматически просматривает папку с именем bin в корневой web-папке, находит&lt;BR&gt;модуль и реализует наследование от этого класса. Файл, в котором содержится ис-&lt;BR&gt;ходный код на С# (в данном случае это файл Lists.cs), представляет собой файл&lt;BR&gt;с кодом поддержки.&lt;BR&gt;Двигаясь далее по телу страницы, мы обнаруживаем форму с кодом для середи-&lt;BR&gt;ны web-страницы, расположенной между заголовком и нижней частью страницы.&lt;BR&gt;Первое, на что мы обращаем внимание,— это кнопка Create в верхнем левом углу&lt;BR&gt;непосредственно под заголовком. При нажатии этой кнопки появляются два тек-&lt;BR&gt;стовых окна и две иконки — для подтверждения и для отказа от данной операции,&lt;BR&gt;которые были продемонстрированы ранее. Остальная часть страницы остается без&lt;BR&gt;изменений. Ниже приводится код для этой кнопки:&lt;BR&gt;....... .... ... . . : , &lt;asp:TableRow ID=fiCreateNewRown&amp;gt; : /•.•&apos;&apos;•.&quot;•••&apos;..•&apos; .&lt;BR&gt;: &lt;asp:TableCell ColumnSpan+ *3&quot;&amp;gt; -y&apos;^{&apos;-&quot;&amp;gt;^•: ; : .&lt;BR&gt;&lt;asp:Button runat=&quot;server&quot; Text-&quot;Create&quot;&lt;BR&gt;ID=HCreate_Clic}cfl Width=&quot;80px&quot;&lt;BR&gt;OnClick=&quot;Create_Click1&apos; Width=&quot;80pxn&lt;BR&gt;/&amp;gt;&lt;BR&gt;• ; : .&apos;• ••:•• • .•• •, •• • &lt; / a s p : T a b l e C e l l &amp;gt; • •• ••• .•.•••••••••.•,.•,•:•.••••• •• . • • • •• : •,. : • • ••• „ • / . .&lt;BR&gt;&lt;/asp:TableRow&amp;gt; • .• &apos;••;&apos;••/• &apos; /•• .• V - - . ^ - &apos; : . ; :&lt;BR&gt;Далее идет строка таблицы, по умолчанию являющаяся невидимой, но которая&lt;BR&gt;становится видимой при щелчке мышью на кнопке Create. Эта часть программы&lt;BR&gt;позволяет модифицировать список и принять сделанные изменения или отказаться&lt;BR&gt;от них:&lt;BR&gt;&lt;asp:TableRow ID=&quot;AddNewContrclsRow11 Visible^&quot;false&quot;&amp;gt;&lt;BR&gt;&lt;asp:TableCell&amp;gt;&lt;BR&gt;&lt;asp:Image ImageURL=&quot;./Images/imgSpacer.gif&quot;&lt;BR&gt;• Width=n15px&quot;•.;Height =&quot;lpx&quot; runat=&quot;server&quot; /•&amp;gt;••:&lt;BR&gt;&lt;asp:LinkButton ID=&quot;AddNew&quot; runat-&quot;server&quot; /&amp;gt;&lt;BR&gt;Text=&quot;&lt;img beorder=0 scr=./Images/imgOK.gif&lt;BR&gt;• Alt=&apos;Add new list&apos;&amp;gt;&quot; .&lt;BR&gt;: OnClick-&quot;AddNew_Click&quot; • :&lt;BR&gt;. ; • . . ; , : . .. /&amp;gt; • • • •&lt;BR&gt;&lt;asp:Image ImageUKL=&quot;./Images/imgSpacer.gif&quot;&lt;BR&gt;Width=&quot;15px&quot; Height=&quot;lpx&quot; runat-&quot;server&quot; /&amp;gt;&lt;BR&gt;&lt;asp:LinkButton ID=&quot;CancelAddNew&quot; ;• :&lt;BR&gt;runat=&quot;server&quot; CausesValidation=&quot;false?l&lt;BR&gt;Text=&quot;&lt;img beorder=0 scr=./Images/imgCancel.gif&lt;BR&gt;Alt=&apos;Cancel editing mode&apos;&amp;gt;&quot;&lt;BR&gt;OnClick-11 Cancel AddNew_C.lick11&lt;BR&gt;/&amp;gt; &apos;§шшшйi : ^ ш ш ш ^ м ш щ : &amp;#92; • •-•;.&apos;:.:&quot;&lt;BR&gt;• ••••• : ш&lt;BR&gt;&lt;/asp:TableCell&amp;gt;&lt;BR&gt;&lt;/asp:Table Cell VerticalAlign=&quot;Top&quot;&amp;gt;&lt;BR&gt;&lt;asp:TextBox runat=&quot;server&quot; Class=&quot;TextBox&quot;&lt;BR&gt;ID=&quot;NewListName&quot; Width=&quot;150px&quot; /&amp;gt;&lt;BR&gt;: &lt;asp:ReguiredFieldValidatbr Id=&quot;ValidateNewName&quot; ;&lt;BR&gt;: - runat=&quot;server&quot; COntrplToValidate=&quot;NewListName/&lt;BR&gt;Displays&quot;dynamicM&lt;br&amp;gt;* Name is required&lt;BR&gt;. &lt;/asp:RequiredFieldValidator&amp;gt;&lt;BR&gt;&lt;/asp:TableCell&amp;gt;&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 815&lt;BR&gt;&lt;/asp:Table Cell VerticalAlign=&quot;Top&quot;&amp;gt;&lt;BR&gt;&lt;asp:TextBox runat—&quot;server&quot; Class=&quot;TextBox&quot;&lt;BR&gt;ID=&quot;NewListDescr&quot; Width=&quot;450px&quot; /&amp;gt;&lt;BR&gt;&lt;/asp:TableCell&amp;gt;&lt;BR&gt;&lt;/asp:TableRow&amp;gt;&lt;BR&gt;Обратите внимание на то, что все серверные управляющие элементы, к кото-&lt;BR&gt;рым требуется обеспечить доступ программным путем, обладают атрибутом ID,&lt;BR&gt;а весь код располагается внутри серверной формы. Также обратите внимание на&lt;BR&gt;то, что при создании нового списка рассылки задание его имени является необхо-&lt;BR&gt;димым, ЧТО Обеспечивается управляющим элементом RequiredFieldValidator. На-&lt;BR&gt;значение свойства controiTovaiidate (управляющий элемент, подлежащий проверке)&lt;BR&gt;очевидно, а свойство Display, которому присваивается значение dynamic, означает,&lt;BR&gt;что область для сообщения об ошибке будет выделяться в динамическом режиме.&lt;BR&gt;Одним из наиболее интересных серверных управляющих элементов является&lt;BR&gt;элемент табличного вывода, который в нашем приложении используется для выво-&lt;BR&gt;да списков рассылки. Этот управляющий элемент обладает широким спектром&lt;BR&gt;функциональных возможностей, для использования которых требуется всего лишь&lt;BR&gt;несколько строк кода: отличающиеся стили для подлежащих изменению строк,&lt;BR&gt;сортировка данных и постраничное разбиение данных. Однако наиболее важным&lt;BR&gt;представляется то, что этот управляющий элемент является полностью настраива-&lt;BR&gt;емым и основанным на использовании шаблонов. С помощью программного шаб-&lt;BR&gt;лона можно определить содержимое каждого столбца и указать способ, которым&lt;BR&gt;эти данные должны выводиться.&lt;BR&gt;Именно здесь задаются свойства управляющего элемента для табличного выво-&lt;BR&gt;да данных:&lt;BR&gt;&lt;asp:DataGrid id=&quot;ListsGrid&quot; runat=&quot;srver&quot;&lt;BR&gt;CssClass=&quot;Grid_General&quot;&lt;BR&gt;HeaderStyle~CssClass=HGrid_HeaderH&lt;BR&gt;ItemStyle-CssClass=&quot;Grid_Item&quot;&lt;BR&gt;AlternatingItemStyle~CssClass=&quot;Grid_AlternatingItein&quot;&lt;BR&gt;&apos; Ai lowSort ing-11 True&quot;&lt;BR&gt;: AutoGeneratedColumns^&quot;False&quot;&lt;BR&gt;DataKeyField=&quot;ID&quot;&lt;BR&gt;OnEditCornmand=&quot;ListsGrid_Edit&quot;&lt;BR&gt;OnCancelCommand=&quot;ListsGrid_CancelEditu&lt;BR&gt;OnUpdateCoramand=&quot;ListsGrid_Update&quot;&lt;BR&gt;OnDeleteCommand=&quot;ListsGrid_Delete&quot;&lt;BR&gt;OnSortCommand=&quot;ListsGrid_SortM &amp;gt;&lt;BR&gt;Задаются стили, которые будут использоваться при выводе различных состав-&lt;BR&gt;ляющих таблицы, кроме того, мы определяем, что эти данные могут быть отсорти-&lt;BR&gt;рованы, а также задаем столбец в исходной таблице, который будет использоваться&lt;BR&gt;в качестве первичного ключа данных таблицы (свойство DataKeyFieid). В послед-&lt;BR&gt;них строках описываются процедуры обработки событий, вызываемые для реали-&lt;BR&gt;зации различных операций над таблицей.&lt;BR&gt;Далее требуется объявить, каким образом будет представлен каждый столбец.&lt;BR&gt;Нам необходимы следующие столбцы:&lt;BR&gt;• Допускающий щелчок мышью рисунок для редактирования строки&lt;BR&gt;• Допускающий нажатие мышью рисунок для удаления строки&lt;BR&gt;• Столбец для вывода названия списка&lt;BR&gt;• Столбец для вывода описания списка&lt;BR&gt;816 Практический пример&lt;BR&gt;• Допускающий щелчок мышью рисунок для перехода к странице,&lt;BR&gt;где выводятся подписчики списка, который находится в текущей строке&lt;BR&gt;• Допускающий щелчок мышью рисунок для перехода к странице,&lt;BR&gt;на которой выводятся ранее отправленные сообщения&lt;BR&gt;для данного списка&lt;BR&gt;• Допускающий щелчок мышью рисунок для перехода к странице,&lt;BR&gt;которая позволяет отправить новое сообщение по электронной почте&lt;BR&gt;« всем подписчикам данного списка&lt;BR&gt;Поскольку табличное представление данных до сих пор в книге не встречалось,&lt;BR&gt;то мы подробно остановимся на его реализации. Ниже приводится код, необходи-&lt;BR&gt;мый для вывода первых двух столбцов:&lt;BR&gt;• • • • • • • • • • • . • • . . . :, .,•. &lt; C o l u m n s &amp;gt; &apos; &apos; : • , . . • • • • . • • . • . . . • . • : • • • • • . • • • . . • • . • . . • • . • • &apos;• • ^&lt;BR&gt;&lt;asp:EditCoimandColumn :&lt;BR&gt;ItemStyle-Width=&quot;25px&quot;&lt;BR&gt;EditText=&quot;&lt;img border=0 Alt=&apos;Edit this list&apos;&lt;BR&gt;src=./Images/imgEdit.gif&amp;gt;&quot;&lt;BR&gt;CancelText=&quot;&lt;img border=0 src=./Images/imgCancel.gif&amp;gt;&quot;&lt;BR&gt;UpdateText=&quot;&lt;img border-0 src=. /Images/imgOK.gd f&amp;gt;&quot;&lt;BR&gt;/ &amp;gt; • Л ^ • : • ,&lt;BR&gt;&lt;asp: ButtonColumn&lt;BR&gt;ItemStyle~Width=&quot;25px&quot;&lt;BR&gt;Text=&quot;&lt;img border=0 Alt=&apos;Delete this list&apos;&lt;BR&gt;• . •&apos;;.,. , &apos; src=. / I m a g e s / i m g D e l e t e . g i f &amp;gt; &quot; •••• • &quot;&quot;&apos;&apos;&quot; .&apos;• &apos;&lt;BR&gt;СommahdName=&quot;de1ete&quot;&lt;BR&gt;EditcoiumnButton — это особый столбец, содержащий ссылку на начало редак-&lt;BR&gt;тирования, a Buttoncolumn позволяет создавать обычные кнопки или ссылки. Для&lt;BR&gt;выполнения любой операции, которая может потребоваться, необходимо обраба-&lt;BR&gt;тывать событие click. Обратите внимание на то, что для представления кнопок&lt;BR&gt;свойство столбца Text задается с помощью тега &lt;img&amp;gt;. Если включить в программу&lt;BR&gt;обычную строку вместо этой HTML-строки, то мы получаем стандартную кнопку&lt;BR&gt;с надписью в виде этой строки.&lt;BR&gt;Ниже приводится программа для вывода столбцов, содержащих поля списка ID,&lt;BR&gt;Name И Description!&lt;BR&gt;&lt;asp:BoundColumn HeaderText=llIDlt ItemStyle-Width=&quot;30px11&lt;BR&gt;DataField=nID&quot; Readonly-&quot;True&quot; SortExpression=&quot;IDM /&amp;gt;&lt;BR&gt;&lt;asp:TemplateCclumn HeaderText=tlName&quot; SortExpression=&quot;Name&quot;&lt;BR&gt;itemStyle-Width=&quot;l&amp;pound;opx&quot;&lt;BR&gt;&lt;ItemTemplate&amp;gt;&lt;BR&gt;&lt;asp:Label runat=&quot;server&quot; Text=&apos;&lt;%#&lt;BR&gt;DataBinder.Eval(Container.Dataltem, &quot;Name&quot;) %&amp;gt;&apos; /&amp;gt;&lt;BR&gt;&lt;/ItemTemplate&amp;gt;&lt;BR&gt;&lt;EditItemTemplate&amp;gt;&lt;BR&gt;&lt;asp;TextBox ID=&quot;EditListName11 runat-&quot;server&quot;&lt;BR&gt;Text-^&lt;%# DataBinder.Eval (Container. Dataltem, &quot;Name&quot;) %&amp;gt;.&apos;&lt;BR&gt;Class=&quot;TextBox&quot;&lt;BR&gt;Width=&quot;150px11&lt;BR&gt;&lt;asp:ReguiredFieldValidator Id=&quot;ValidateEditName11&lt;BR&gt;runat=&quot;server&quot;&lt;BR&gt;ControlToValidate=&quot;EditListName&quot;&lt;BR&gt;Display=&quot;dynamic&quot;&amp;gt;* Name is required&lt;BR&gt;&lt;/asp:RequiredFieldValidator&amp;gt;&lt;BR&gt;&lt;/EditItemTemplate&amp;gt;&lt;BR&gt;&lt;/asp:TemplateColumn&amp;gt;&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 817&lt;BR&gt;&lt;asp:TemplateColumn HeaderText=&quot;Description&quot;&lt;BR&gt;• SortExpression=&quot;Description&quot;&amp;gt;&lt;BR&gt;&lt;ItemTempIate&amp;gt;&lt;BR&gt;&lt;asp:Label runat~&quot;server&quot; Text=&apos;&lt;%#&lt;BR&gt;DataBinder.Eval(Container.Dataltem, &quot;Description&quot;) %&amp;gt;&apos; /&amp;gt;&lt;BR&gt;&lt;/ItemTemplate&amp;gt; .:•••&lt;BR&gt;&lt;EditItemTemplate&amp;gt; ;.&lt;BR&gt;&lt;asp:TextBox ID=&quot;EditListDescrn runat=Hserver&quot;&lt;BR&gt;Text=&apos;&lt;%# DataBinder.Eval (Container.Dataltern,&lt;BR&gt;&quot;Description&quot;) %&amp;gt;&apos;&lt;BR&gt;: Class=&quot;TextBox&quot;&lt;BR&gt;Width=n380px&quot;&lt;BR&gt;/ &amp;gt; • . . . &apos; • • ••&lt;BR&gt;&lt;/EditItemTemplate&amp;gt;&lt;BR&gt;&lt;/asp:TemplateColumn&amp;gt;&lt;BR&gt;Первый столбец описывается в этой программе как обычный, не подлежащий&lt;BR&gt;редактированию столбец. Два других столбца позволяют продемонстрировать, ка-&lt;BR&gt;ким образом по шаблону можно создавать столбец, использующий управляющий&lt;BR&gt;элемент Label для вывода значения или управляющий элемент TextBox для его ре-&lt;BR&gt;дактирования. Соответствующее представление создается автоматически, когда мы&lt;BR&gt;входим в режим редактирования для данной строки или покидаем его. Обратите&lt;BR&gt;вниманиела то, что текст в управляющем элементе Label и в управляющих эле-&lt;BR&gt;ментах TextBox обрабатывается С ПОМОЩЬЮ метода DataBinder.Eval (), который&lt;BR&gt;возвращает значение соответствующего столбца для считываемой строки, а для&lt;BR&gt;добавления нового списка требуется задать его имя.&lt;BR&gt;Три остальных столбца представляют собой ссылки, которые позволяют пере-&lt;BR&gt;ходить на страницы с дополнительной информацией:&lt;BR&gt;&lt;asp:HyperLinkColumn :&lt;BR&gt;DataNavigateUrlField=HID&quot;&lt;BR&gt;: DataNavigateUrlFormatStrings&quot;Subscribers.aspx?ListID={0}&quot;&lt;BR&gt;: DataTextFormatString=&quot;&lt;img border^O Alt =&apos;Show subscribers&apos;&lt;BR&gt;src=./Images/in&amp;#92;gAddresses.gif &amp;gt;&quot;&lt;BR&gt;DataTextField=&quot;ID&quot;&lt;BR&gt;/&amp;gt;&lt;BR&gt;&lt;asp:HyperLinkColumn&lt;BR&gt;DataNavigateUrlField^ID&quot; :&lt;BR&gt;DataNavigateUrlFormatString:=&quot;NewsHistory.aspx?ListID={0}&quot;&lt;BR&gt;DataTextFormatString=H&lt;img border=0 Alt=&apos;Show past news for&lt;BR&gt;this list&apos; :s.rc=. /Images/imgMessage.gif&amp;gt;&quot;&lt;BR&gt;DataTextField=&quot;IDM&lt;BR&gt;; •. / &amp;gt; • • • ; : ^ : v V / r : .v. &quot; ^ i ^ •^•.••:-&apos;-: V / &apos; &apos; &apos; •&apos;• &quot; &quot; &apos; ,&apos;.&apos; &apos; :&amp;#92;&lt;BR&gt;&lt;asp:HyperLinkColumn&lt;BR&gt;DataNavigateUrlField=&quot;ID&quot;&lt;BR&gt;DataNavi&amp;amp;ateUrlFonnatString-&quot;SendEmail;aspx?ListID={d}&quot;&lt;BR&gt;DataTextFormatString=n&lt;img border=0 Alt=&apos;Send a new mail&lt;BR&gt;for this list&apos; src=./Images/imgMail.gif&amp;gt;&quot;&lt;BR&gt;DataTextField=&quot;ID&quot; :&lt;BR&gt;• : . /&amp;gt; ;•• . - &apos; • : • . : . ; &apos; :&lt;BR&gt;Эти нередактируемые гиперссылки представляются в виде образов, а URL-адреса,&lt;BR&gt;на которые они указывают, создаются с помощью шаблона строки, описываемого&lt;BR&gt;в DataNavigateUriFormatstring: вместо маркера {0} вставляется ID соответствую-&lt;BR&gt;щей строки.&lt;BR&gt;Класс BasePage&lt;BR&gt;Прежде чем приступить к изучению файла Lists.cs с кодом поддержки, о кото-&lt;BR&gt;ром упоминалось в предыдущем разделе, представим базовый класс, который бу-&lt;BR&gt;дет использоваться всеми классами из файлов с кодом поддержки, используемыми&lt;BR&gt;818 Практический пример&lt;BR&gt;в этом примере. Этот класс называется BasePage, и он является производным от&lt;BR&gt;класса System.web.ui.Page. Его описание сведено в следующую таблицу:&lt;BR&gt;Класс BasePage&lt;BR&gt;Метод Описание&lt;BR&gt;public string GetConnString () Извлекает строку соединения с базой данных&lt;BR&gt;из файла web.config — файла, в котором хранятся&lt;BR&gt;все установки конфигурации данного приложения&lt;BR&gt;public string GetSettingsFile () Извлекает имя файла, в котором хранятся все установки&lt;BR&gt;данного приложения, также находящегося в файле web.config&lt;BR&gt;Этот класс обладает двумя общими методами, которые наследуются всеми про-&lt;BR&gt;изводными классами. Это пример правильного использования объектно-ориенти-&lt;BR&gt;рованного подхода, поскольку строка соединения и имя файла с установками могут&lt;BR&gt;понадобиться ддя всех этих классов, и наилучшим решением будет поместить функ-&lt;BR&gt;циональную возможность доступа к этой информации в одном классе, вместо того&lt;BR&gt;чтобы копировать и переносить ее каждый раз, когда у какого-либо класса возни-&lt;BR&gt;кает в ней необходимость. Обе функции реализованы весьма простым способом —&lt;BR&gt;они осуществляют поиск строки соединения и имени файла с установками в приве-&lt;BR&gt;денном ниже разделе файла web.config, после чего помещают эту информацию&lt;BR&gt;в кэш-память:&lt;BR&gt;&lt;configuration&amp;gt;&lt;BR&gt;: &lt;appSettings&amp;gt;&lt;BR&gt;&lt;add key=&quot;ConnString&quot; value=&quot;Provider=Microsof t.Jet.OLEDB.4.0;&lt;BR&gt;Data Source=E:&amp;#92;Projects&amp;#92;NewsMailer&amp;#92;DB&amp;#92;NewsMailer.mdb&quot; /&amp;gt;&lt;BR&gt;&lt;add key=&quot;SettingsFilen value=&quot;NewsMailer.Settings&quot; /&amp;gt;&lt;BR&gt;&lt;/appSettings&amp;gt;&lt;BR&gt;&lt;/configuration&amp;gt;&lt;BR&gt;Необходимо изменить вышеупомянутый ключ connstring так, чтобы он правиль-&lt;BR&gt;но указывал на файл базы данных.&lt;BR&gt;Код поддержки для Lists, aspx&lt;BR&gt;После определения базового класса перейдем к рассмотрению того, что нахо-&lt;BR&gt;дится в файл^е Lists.aspx с кодом поддержки.&lt;BR&gt;Класс Lists&lt;BR&gt;В СПИСКе ДИреКТИВ using ЭТОТ КЛаСС наХОДИТСЯ В Пространстве Имен NewsMailer&lt;BR&gt;И является ПРОИЗВОДНЫМ ОТ BasePage:&lt;BR&gt;namespace MewsMailer&lt;BR&gt;{&lt;BR&gt;public class Lists : MewsMailer.BasePage&lt;BR&gt;После объявления нескольких защищенных управляющих элементов Web Form,&lt;BR&gt;мы подходим к тому месту, где реализованы функциональные возможности страни-&lt;BR&gt;цы. Ниже приводится обработчик, который запускается при загрузке страницы:&lt;BR&gt;. protected void Page_Load(object sender, EventArgs e)&lt;BR&gt;Щ Ш / - &apos; &apos; &apos;{ &apos; &apos; &apos; : ; &apos; : &amp;#92; V &quot; : &apos; ;&apos; •;;••;•.&quot;&apos;.&quot;••. ••&quot;, &apos; _ -.&quot;••. х / Г / Т Ч ^ : ••.•;•;•;•;&apos; •:• : V . . ; : : у - .-;._•:;;.&lt;BR&gt;if (IPage.IsPostBack)&lt;BR&gt;— 819&lt;BR&gt;метод BindGrido, который наполняет таб-&lt;BR&gt;protected void BindGrid ()&lt;BR&gt;Datavicw myDV = lists.GetLists(,.TablestO].Defaultview;&lt;BR&gt;2 «&lt;BR&gt;ListGrid.DataSource = myDV;&lt;BR&gt;Ust.Grid.DataBindO;&lt;BR&gt;вторного запроса к базе данных&lt;BR&gt;Н.„ .&lt;BR&gt;вд» -&lt;BR&gt;в „о„е„т „ерв о г о&lt;BR&gt;данные вообще не&lt;BR&gt;для вывода строк.&lt;BR&gt;Сортировка списков&lt;BR&gt;ShowAddNewControls{false);&lt;BR&gt;bistsGrid.Editltemlndex = -l;&lt;BR&gt;s —&lt;BR&gt;о т п Р а в к и но-&lt;BR&gt;в ы в о д и и ы е&lt;BR&gt;выводимые&lt;BR&gt;и вызывается метод&lt;BR&gt;820 Практический пример&lt;BR&gt;.11 установить атрибут SortExpression, который будет использоваться&lt;BR&gt;//для сортировки данных в методе -BindGr id&lt;BR&gt;ListsGrid.Attributes[&quot;SortExpression}=e.SortExpression.ToString{);&lt;BR&gt;BindGrid();&lt;BR&gt;} -. -.-. • ; Ш :--ъ&lt;BR&gt;Прежде всего эта функция прячет управляющие элементы для включения нового&lt;BR&gt;списка, если они видимы в данный момент. Затем она отменяет режим редактиро-&lt;BR&gt;вания строки, если он был. установлен. Наконец, она получает выражение сорти-&lt;BR&gt;ровки, по которому будет осуществляться фактическая сортировка, и название&lt;BR&gt;столбца, а затем обновляет содержимое управляющего элемента табличного пред-&lt;BR&gt;ставления данных, вызывая метод BindGr id ().&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/upravlenie_konfiguraciej_dannykh/2010-02-11-409</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/upravlenie_konfiguraciej_dannykh/2010-02-11-409</guid>
			<pubDate>Wed, 10 Feb 2010 22:00:05 GMT</pubDate>
		</item>
		<item>
			<title>Практический пример 2 - Менеджер рассылки новостей в режиме онлайн</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Практический пример 2 -&lt;BR&gt;&lt;/SPAN&gt;Менеджер рассылки новостей&lt;BR&gt;в режиме онлайн&lt;BR&gt;Программа рассылки новостей&lt;BR&gt;В предшествующих главах настоящей книги вы познакомились с тем, как про-&lt;BR&gt;граммировать на языке С# и как использовать этот язык программирования&lt;BR&gt;в приложениях Windows и простых приложениях ASP.NET. Теперь мы собираемся&lt;BR&gt;продемонстрировать, каким образом можно использовать многое из того, с чем вы&lt;BR&gt;познакомились, для создания web-приложения, которое может быть использовано&lt;BR&gt;в реальном web-сайте .NET.&lt;BR&gt;Ниже перечислены некоторые из тем, с которыми вы познакомитесь или кото-&lt;BR&gt;рые вы сможете лучше усвоить в результате прочтения этого практического при-&lt;BR&gt;мера:&lt;BR&gt;• Создание законченных web-приложений с помощью ASP.NET&lt;BR&gt;• Использование некоторых серверных управляющих элементов ASP.NET&lt;BR&gt;для создания пользовательского интерфейса с богатыми возможностями&lt;BR&gt;• Использование кода поддержки для разделения основного кода&lt;BR&gt;от пользоват...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Практический пример 2 -&lt;BR&gt;&lt;/SPAN&gt;Менеджер рассылки новостей&lt;BR&gt;в режиме онлайн&lt;BR&gt;Программа рассылки новостей&lt;BR&gt;В предшествующих главах настоящей книги вы познакомились с тем, как про-&lt;BR&gt;граммировать на языке С# и как использовать этот язык программирования&lt;BR&gt;в приложениях Windows и простых приложениях ASP.NET. Теперь мы собираемся&lt;BR&gt;продемонстрировать, каким образом можно использовать многое из того, с чем вы&lt;BR&gt;познакомились, для создания web-приложения, которое может быть использовано&lt;BR&gt;в реальном web-сайте .NET.&lt;BR&gt;Ниже перечислены некоторые из тем, с которыми вы познакомитесь или кото-&lt;BR&gt;рые вы сможете лучше усвоить в результате прочтения этого практического при-&lt;BR&gt;мера:&lt;BR&gt;• Создание законченных web-приложений с помощью ASP.NET&lt;BR&gt;• Использование некоторых серверных управляющих элементов ASP.NET&lt;BR&gt;для создания пользовательского интерфейса с богатыми возможностями&lt;BR&gt;• Использование кода поддержки для разделения основного кода&lt;BR&gt;от пользовательского интерфейса&lt;BR&gt;• Создание файла web-конфигурации для хранения установок пользователя&lt;BR&gt;для данного приложения и для обеспечения безопасности&lt;BR&gt;базового уровня&lt;BR&gt;• Использование объектно-ориентированных возможностей С#&lt;BR&gt;для создания и применения классов, в которых инкапсулирована&lt;BR&gt;бизнес-логика приложения -&lt;BR&gt;• Использование некоторых классов .NET Framework&lt;BR&gt;для работы с файлами, почтой и базами данных&lt;BR&gt;• Запись в базу данных и чтение из базы данных с помощью&lt;BR&gt;управляемого провайдера OLE DB и классов ADO.NET&lt;BR&gt;• Распространение компилированных приложений ASP.NET&lt;BR&gt;и их запуск через IIS&lt;BR&gt;796 Практический пример&lt;BR&gt;Общий обзор приложения&lt;BR&gt;Любому web-мастеру известны ключевые элементы, необходимые для разра-&lt;BR&gt;ботки успешного web-сайта. Вот некоторые из них:&lt;BR&gt;• Хорошее наполнение (контент)&lt;BR&gt;• Организация (удобство поиска и навигации)&lt;BR&gt;• Привлекательный дизайн&lt;BR&gt;• Взаимодействие с пользователем&lt;BR&gt;Успешный web-сайт должен обладать свежим, регулярно обновляемым и инте-&lt;BR&gt;ресным содержимым. Список адресов электронной почты может оказаться весьма&lt;BR&gt;полезным для постоянного уведомления подписчиков о новых возможностях —&lt;BR&gt;в качестве напоминания посетителям и стимула для регулярного посещения сайта.&lt;BR&gt;Управление таким списком может представлять определенные трудности. Адми-&lt;BR&gt;нистраторам приходится сопровождать список подписчиков, иметь дело с заявками&lt;BR&gt;на подписку и с отказами от подписки, а также отслеживать все отправленные со-&lt;BR&gt;общения.&lt;BR&gt;Приложение, представляемое в настоящей главе, сможет оказать помощь в ав-&lt;BR&gt;томатизации управления одним из таких списков. Эта программа — Менеджер&lt;BR&gt;рассылки новостей в режиме онлайн — позволяет автоматизировать большую часть&lt;BR&gt;задач, связанных с подпиской и управлением рассылкой новостей, а также упрос-&lt;BR&gt;тить выполнение администратором остальных действий. Эта программа позволяет:&lt;BR&gt;• Управлять множественными списками рассылок, давая администратору&lt;BR&gt;возможность добавлять, исключать или вносить изменения&lt;BR&gt;в списки и их свойства.&lt;BR&gt;• Осуществлять управление подписчиками из всех списков&lt;BR&gt;с возможностью задавать и изменять имя подписчика&lt;BR&gt;и относящуюся к нему персональную информацию.&lt;BR&gt;• Рассылать подписчикам сообщения по электронной почте в виде&lt;BR&gt;обычного текста или в HTML-формате. Все электронные сообщения&lt;BR&gt;могут автоматически снабжаться именем и адресом подписчика,&lt;BR&gt;содержать ссылку, позволяющую произвести отказ от подписки,&lt;BR&gt;а также любую другую информацию о списке (например, его название&lt;BR&gt;. и описание).&lt;BR&gt;• Управлять архивом новостей, рассылавшихся по всем спискам ранее,&lt;BR&gt;предоставляя администратору возможность читать и копировать&lt;BR&gt;предыдущие сообщения.&lt;BR&gt;• Создавать HTML-форму, позволяющую получать данные пользователя&lt;BR&gt;без необходимости писать какой бы то ни было код. Эта функциональная&lt;BR&gt;возможность оформлена в виде программы-мастера — администратор&lt;BR&gt;выбирает список, для которого ему требуется создать форму, задает&lt;BR&gt;несколько опций, после чего мастер самостоятельно создает&lt;BR&gt;весь необходимый код.&lt;BR&gt;• Задавать некоторые опции, например, имя и адрес отправителя, подпись,&lt;BR&gt;которая будет автоматически добавляться к каждому сообщению,&lt;BR&gt;предмет сообщения по умолчанию, а также сообщения о подписке&lt;BR&gt;и об отказе от подписки.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 797&lt;BR&gt;• Использовать возможность изменения внешнего представления&lt;BR&gt;приложения (цвета и размеры шрифтов) без внесения изменения&lt;BR&gt;в HTML-код или загрузки новых файлов.&lt;BR&gt;Самым существенным преимуществом такого решения является то, что больше&lt;BR&gt;не придется вручную управлять группой пользователей: приложение добавляет их&lt;BR&gt;в базу данных и исключает их оттуда. Вторым, и также важным преимуществом&lt;BR&gt;является то, что администратор получает возможность следить за подписчиками&lt;BR&gt;web-сайта в режиме онлайн, общаться с ними и даже вносить изменения во внеш-&lt;BR&gt;нее представление web-сайта из любой точки планеты. Все, что ему для этого тре-&lt;BR&gt;буется,— это компьютер с web-браузером и выход в Интернет.&lt;BR&gt;В данном примере предполагается, что для разработки приложения&lt;BR&gt;вы будете использовать Visual Studio.NET. Если это не такг то в программе,&lt;BR&gt;которую вы можете загрузить, содержатся указания как откомпилировать&lt;BR&gt;это приложение из командной строки.&lt;BR&gt;Модель приложения&lt;BR&gt;Хорошие приложения, построенные на основе использования баз данных,&lt;BR&gt;обычно разбиваются на уровни для представления, бизнес-логики и данных. Такая&lt;BR&gt;модель упрощает сопровождение приложения, а также дает лучшую масштабируе-&lt;BR&gt;мость, поскольку допускает установку приложения на различных серверах. Даже&lt;BR&gt;если приложение, которое мы собираемся разрабатывать, не требует повышенной&lt;BR&gt;масштабируемости, все равно это тот путь, по которому следует двигаться. Графи-&lt;BR&gt;ческое представление структуры нашего приложения представлено на следующей&lt;BR&gt;диаграмме:&lt;BR&gt;Службы пользователя&lt;BR&gt;Страницы ASP.NET&lt;BR&gt;• -• t Ь - &apos; • : • • • &apos; : • &apos; • • &apos; • &apos;&lt;BR&gt;Т &apos;. - . &apos; • • -&apos;•• - : &apos;: •&apos;&lt;BR&gt;Классы кода поддержки&lt;BR&gt;(NewsMailer.dll)&lt;BR&gt;/&lt;BR&gt;/&lt;BR&gt;Бизнес-службы&lt;BR&gt;/&lt;BR&gt;/&lt;BR&gt;Модуль доступа&lt;BR&gt;к базе данных&lt;BR&gt;(NewsMailerDB.dll)&lt;BR&gt;Модуль менеджера&lt;BR&gt;конфигурации приложения&lt;BR&gt;(NewsMailerConfig.dll)&lt;BR&gt;Службы данных&lt;BR&gt;Доступ к базе данных&lt;BR&gt;(NewsMailer.mdb)&lt;BR&gt;Файл конфигурации&lt;BR&gt;(NewsMailer. Settings)&lt;BR&gt;Уровень представления (службы пользователя) состоит из страниц ASP.NET&lt;BR&gt;с их кодом поддержки (откомпилированным в модуль). Уровень бизнес-служб со-&lt;BR&gt;держит в себе еще два модуля, которые обеспечивают простой доступ к данным.&lt;BR&gt;Настоящий раздел посвящен подробному объяснению реализации каждого из этих&lt;BR&gt;уровней и модулей.&lt;BR&gt;798 Практический пример&lt;BR&gt;Объекты данных и бизнес-объекты&lt;BR&gt;NLesiwtsDsMBaelirDB.dl (ListsDB.cs)&lt;BR&gt;(SuSbusbcsrcbibreiersrsDDBB.es)&lt;BR&gt;—(NNewewsHsHsitsoitoryryDDBB.es)&lt;BR&gt;NewsMailerConfig.dl&lt;BR&gt;AAppppSCeotntinggfis&lt;BR&gt;(AppConfig.es)&lt;BR&gt;Мы начнем обсуждение с уровня данных&lt;BR&gt;и бизнес-уровня. На диаграмме, приведенной&lt;BR&gt;на рисунке слева, показаны два модуля бизнес-&lt;BR&gt;уровня и общие классы, входящие в их состав.&lt;BR&gt;Модуль NewsMaiierDB.dll обеспечивает до-&lt;BR&gt;ступ к базе данных, в нем хранятся названия&lt;BR&gt;списков рассылки, подписчики и предыдущие&lt;BR&gt;Сообщения. Модуль NewsMailerConfig.dll&lt;BR&gt;обеспечивает доступ к XML-файлу, в котором&lt;BR&gt;хранятся установки и где все опции приложе-&lt;BR&gt;ния могут считываться и изменяться.&lt;BR&gt;Модель базы данных&lt;BR&gt;В целом приложение основывается на использовании базы данных, поэтому&lt;BR&gt;начнем обсуждение проекта с выбора и обсуждения модели базы данных. Мы ре-&lt;BR&gt;шили использовать базу данных Access вместо SQL Server по целому ряду причин.&lt;BR&gt;Базу данных Access проще конфигурировать, кроме того, ее наличие предусматри-&lt;BR&gt;вается в большинстве планов по работе с web-серверами, в то время как наличие&lt;BR&gt;SQL Server предусматривается только в наиболее сложных (и более дорогих) про-&lt;BR&gt;ектах по использованию web-серверов. Кроме того, поскольку выигрыш от исполь-&lt;BR&gt;зования менеджера рассылки новостей прежде всего получают небольшие web-&lt;BR&gt;сайты, мы предпочли написать приложение, которое может быть использовано&lt;BR&gt;всеми. Более того, использование SQL Server оправдано для широкомасштабных&lt;BR&gt;сайтов, при обращении к которым многим пользователям одновременно требуется&lt;BR&gt;установление соединения с базой данных. В нашем приложении регулярно уста-&lt;BR&gt;навливать соединение с базой данных будет только администратор. Пользователям&lt;BR&gt;потребуется соединение только для подписки или отказа от подписки, однако тако-&lt;BR&gt;го рода операций выполняются очень быстро, и представляется маловероятным,&lt;BR&gt;что очень большое количество пользователей решит подписаться одновременно.&lt;BR&gt;Поэтому если вам не приходится работать с десятками тысяч подписчиков, база&lt;BR&gt;данных Access является более адекватной. Тем не менее, по ходу обсуждения будет&lt;BR&gt;сделано несколько кратких замечаний, как можно перенести базу данных на SQL&lt;BR&gt;Server, чтобы воспользоваться ее мощью и скоростью. Совершенно очевидно, что&lt;BR&gt;если некоторые части сайта уже используют базу данных SQL Server (например,&lt;BR&gt;при разработке сайта электронной коммерции и использовании SQL Server для&lt;BR&gt;хранения наименований продукции&lt;BR&gt;и информации о ней), вам следует ин-&lt;BR&gt;тегрировать в нее и менеджера рас-&lt;BR&gt;сылки новостей, и все таблицы, с тем&lt;BR&gt;чтобы избежать использования двух&lt;BR&gt;разных баз данных.&lt;BR&gt;Перейдем к обсуждению модели&lt;BR&gt;базы данных. БД состоит из четырех&lt;BR&gt;таблиц, которые связаны между собой&lt;BR&gt;отношениями, изображенными на ри-&lt;BR&gt;сунке справа.&lt;BR&gt;Теперь мы переходим к подробному&lt;BR&gt;описанию этих таблиц и их отношений.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 799&lt;BR&gt;Таблица Lists&lt;BR&gt;Таблица Lists используется для хранения информации обо всех доступных спи-&lt;BR&gt;сках рассылки и имеет следующую структуру:&lt;BR&gt;Название&lt;BR&gt;столбца&lt;BR&gt;ID&lt;BR&gt;Name&lt;BR&gt;Description&lt;BR&gt;Тип&lt;BR&gt;AutoNumber&lt;BR&gt;Text&lt;BR&gt;Text&lt;BR&gt;Размер&lt;BR&gt;50&lt;BR&gt;250&lt;BR&gt;Допускается&lt;BR&gt;значение null&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Да&lt;BR&gt;Описание&lt;BR&gt;Уникальный идентификатор списка&lt;BR&gt;рассылки&lt;BR&gt;Имя списка рассылки&lt;BR&gt;Необязательное описание списка&lt;BR&gt;рассылки&lt;BR&gt;Таблица UsersData&lt;BR&gt;В таблице UsersData хранится персональная информация пользователей. Таб-&lt;BR&gt;лица имеет следующую структуру:&lt;BR&gt;Название&lt;BR&gt;столбца Тип Размер&lt;BR&gt;Допускается&lt;BR&gt;значение null Описание&lt;BR&gt;ID AutoNumber Нет&lt;BR&gt;FirstName&lt;BR&gt;LastName&lt;BR&gt;Email&lt;BR&gt;Text&lt;BR&gt;Text&lt;BR&gt;Text&lt;BR&gt;50&lt;BR&gt;50&lt;BR&gt;50&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Уникальный идентификатор&lt;BR&gt;пользователя&lt;BR&gt;Имя пользователя&lt;BR&gt;Фамилия пользователя&lt;BR&gt;Адрес электронной почты&lt;BR&gt;пользователя&lt;BR&gt;В данной таблице не содержится указания на то, к какому списку рассылки&lt;BR&gt;приписан пользователь, поскольку один пользователь может подписаться сразу на&lt;BR&gt;несколько различных списков. Наилучшая практика — избегать повторения одних&lt;BR&gt;и тех же деталей. К этому мы вынуждены были бы прибегнуть, если бы решили&lt;BR&gt;хранить подробную информацию о пользователях вместе с каждым из списков, на&lt;BR&gt;которые они подписались. Размещение данных о пользователях в виде отдельной&lt;BR&gt;таблицы позволяет не тратить места впустую, а если возникнет необходимость из-&lt;BR&gt;менить какую-либо информацию о пользователе (скажем, при изменении адреса&lt;BR&gt;электронной почты), то потребуется обновить только единственную запись для&lt;BR&gt;всех списков рассылки, на которые этот пользователь подписан.&lt;BR&gt;Таблица Subscribers&lt;BR&gt;Таблица Subscribers в основном используется для хранения связей между спи-&lt;BR&gt;ском и пользователем. В ней также хранится дата, когда пользователь первый раз&lt;BR&gt;подписался на этот список. Данная таблица имеет следующую структуру:&lt;BR&gt;Название&lt;BR&gt;столбца Тип Размер&lt;BR&gt;Допускается&lt;BR&gt;значение null Описание&lt;BR&gt;ID&lt;BR&gt;ListID&lt;BR&gt;AutoNumber&lt;BR&gt;Integer&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Уникальный идентификатор подписки&lt;BR&gt;Идентификатор списка, на который&lt;BR&gt;подписался пользователь&lt;BR&gt;800&lt;BR&gt;Название&lt;BR&gt;столбца Тип Размер&lt;BR&gt;Допускается&lt;BR&gt;значение null&lt;BR&gt;Практический пример&lt;BR&gt;Продолжение таблицы&lt;BR&gt;Описание&lt;BR&gt;UserID&lt;BR&gt;CreateDate&lt;BR&gt;Integer&lt;BR&gt;Date&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Идентификатор пользователя,&lt;BR&gt;который должен совпадать&lt;BR&gt;с идентификатором пользователя&lt;BR&gt;в таблице UserDataTable&lt;BR&gt;Дата создания данной подписки&lt;BR&gt;Таблица NewsHistory&lt;BR&gt;Таблица NewsHistory используется для хранения предыдущих сообщений, от-&lt;BR&gt;правленных подписчикам всех рассылочных списков, и имеет такую структуру:&lt;BR&gt;Название&lt;BR&gt;столбца Тип Размер&lt;BR&gt;Допускается&lt;BR&gt;значение null Описание&lt;BR&gt;ID&lt;BR&gt;ListID&lt;BR&gt;Subject&lt;BR&gt;Body&lt;BR&gt;IsHTML&lt;BR&gt;AutoNumber&lt;BR&gt;Text&lt;BR&gt;Text&lt;BR&gt;Memo&lt;BR&gt;Boolean&lt;BR&gt;200&lt;BR&gt;SentDate Date&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Да&lt;BR&gt;Нет&lt;BR&gt;Нет&lt;BR&gt;Уникальный идентификатор сообщения&lt;BR&gt;Название списка рассылки, в соответствии&lt;BR&gt;с которым рассылалось данное сообщение&lt;BR&gt;Предмет сообщения&lt;BR&gt;Тело сообщения&lt;BR&gt;Если значение равно true, это означает,&lt;BR&gt;что сообщение отправлялось&lt;BR&gt;в HTML-формате&lt;BR&gt;Дата отправки сообщения&lt;BR&gt;Отношения между таблицами&lt;BR&gt;Если вернуться немного назад и взглянуть на рисунок, на котором представле-&lt;BR&gt;ны отношения между таблицами, то можно увидеть, что между таблицами Lists&lt;BR&gt;И Subscribers И L i s t s И NewsHistory Существует отношение ОДИН КО МНОГИМ, так&lt;BR&gt;как каждый список может иметь несколько подписчиков и несколько отправлен-&lt;BR&gt;ных ранее сообщений. Аналогичным образом, один пользователь может подписать-&lt;BR&gt;ся более чем на один список, поэтому отношение между таблицами usersData&lt;BR&gt;и subscribers — также один ко многим.&lt;BR&gt;Задать отношения между таблицами с помощью Access очень просто. Пройдем&lt;BR&gt;эту процедуру последовательно, шаг за шагом. Откройте файл NewsMaiier.mdb&lt;BR&gt;и выберите пункт меню Tools | Relations. Появится диалоговое окно, в котором на&lt;BR&gt;переднем плане изображены четыре используемые таблицы, а на заднем — пустое&lt;BR&gt;окно. Последовательно выберите и добавьте в это окно одну за другой все таблицы,&lt;BR&gt;изображенные в первом диалоге, после чего закройте окно. Теперь в окне, которое&lt;BR&gt;изображалось на заднем плане, выводятся все четыре таблицы, и можно присту-&lt;BR&gt;пать к созданию отношений между ними. Сначала нужно привязать к таблице Lists&lt;BR&gt;таблицу Subscribers. Щелкните мышью на поле ListiD таблицы subscribers, пе-&lt;BR&gt;ренесите его в поле ID таблицы Lists и отпустите. Это приведет к появлению диа-&lt;BR&gt;логового окна, изображенного на рисунке на стр. 801.&lt;BR&gt;Два раскрывающихся списка в этом диалоговом окне позволяют выбирать&lt;BR&gt;поля, между которыми устанавливаются отношения. Если была проведена опера-&lt;BR&gt;ция переноса мышью, то необходимые поля уже являются выбранными, а описание,&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 801&lt;BR&gt;ID&lt;BR&gt;шдо&lt;BR&gt;Subject&lt;BR&gt;•siBrtTodMyL&lt;BR&gt;3&lt;BR&gt;a n s r .&lt;BR&gt;• Г C«c*de Update Rel-зЫ Field* •&lt;BR&gt;(7 Cascade Dd&lt;*« Rented Records&lt;BR&gt;J • 1&lt;BR&gt;расположенное в нижней части диалога, гласит&lt;BR&gt;&quot;один ко многим&quot;, что означает, что один список&lt;BR&gt;рассылки предназначается для множества под-&lt;BR&gt;писчиков. Вместо операции переноса мышью&lt;BR&gt;можно было щелкнуть мышью два раза на&lt;BR&gt;основном окне (с таблицами), что привело бы&lt;BR&gt;к переходу в то же диалоговое окно, но только&lt;BR&gt;без наличия выбранных полей таблиц, между&lt;BR&gt;которыми устанавливаются связи.&lt;BR&gt;Прежде чем окончательно создать отношение,&lt;BR&gt;требуется учесть еще один момент: необходи-&lt;BR&gt;мость установки Referenda! Integrity (ссылочная&lt;BR&gt;целостность) и включения Cascade Delete (кас-&lt;BR&gt;кадное удаление), как это показано на рисунке.&lt;BR&gt;Поступив таким образом, мы добьемся того, что&lt;BR&gt;при удалении некоторого списка привязанные&lt;BR&gt;к нему подписчики также будут автоматически&lt;BR&gt;удалены. Есть еще опция Cascade Update (кас-&lt;BR&gt;кадное обновление), которая гарантирует, что&lt;BR&gt;все значения ListiD в таблице subscribers бу-&lt;BR&gt;дут обновляться при изменении значений ID&lt;BR&gt;в таблице Lists, однако нам такой режим не&lt;BR&gt;требуется, поскольку поле ID имеет значение&lt;BR&gt;типа AutoNumber, которое не может изменяться&lt;BR&gt;после включения записи в таблицу.&lt;BR&gt;Теперь нам следует создать отношения между таблицами Lists— NewsHistory&lt;BR&gt;и subscribers—usersData аналогичным образом, определяя, между какими полями&lt;BR&gt;должны быть установлены связи с помощью вышеприведенного рисунка.&lt;BR&gt;Бизнес-классы, предназначенные&lt;BR&gt;для доступа в базе данных&lt;BR&gt;Код, который осуществляет работу с базами данных, логически и физически по-&lt;BR&gt;дразделяется на несколько различных классов. Все эти классы будут откомпилиро-&lt;BR&gt;ваны в библиотеку классов с именем NewsMaiierDB. Остальная часть кода —&lt;BR&gt;классы кода поддержки приложения — будет помещена в отдельный модуль. Это&lt;BR&gt;наилучший подход, ибо, если возникает необходимость внести какие-либо измене-&lt;BR&gt;ния в работу базы данных или требуется установить новую версию SQL Server, для&lt;BR&gt;этого будет нужно внести изменения и повторно откомпилировать только бизнес-&lt;BR&gt;модуль. Это лучше, чем компилировать все вместе (бизнес-классы и класс под-&lt;BR&gt;держки) в единый модуль, поскольку можно использовать бизнес-модуль само-&lt;BR&gt;стоятельно, например, в клиентской части приложения Windows.&lt;BR&gt;Для данного приложения такой подход не дает существенных преимуществ;&lt;BR&gt;структура приложения является довольно простой, компилировать приходится не&lt;BR&gt;такие уж большие файлы, и никакие другие клиенты эти бизнес-классы не исполь-&lt;BR&gt;зуют. Поэтому, даже если мы все откомпилируем в единую DLL, это не приведет&lt;BR&gt;к серьезным проблемам. Но мы будем использовать отдельные DLL-модули, для&lt;BR&gt;того чтобы продемонстрировать, насколько все это просто, и для того, чтобы при-&lt;BR&gt;учить вас к хорошим манерам&lt;BR&gt;802 Практический пример&lt;BR&gt;Если вы разрабатываете проект с нуля, вы должны посвятить все время, затра-&lt;BR&gt;ченное на создание проекта, объектно-ориентированной разработке, для чего&lt;BR&gt;обычно следует отделить бизнес-классы от кода пользовательского интерфейса&lt;BR&gt;и компилировать их в разные библиотеки. Разбиение кода на несколько отдельных&lt;BR&gt;модулей может быть осуществлено и позднее, поскольку это относится к процедуре&lt;BR&gt;компиляции. Однако при этом необходимо создавать такие классы, единственная&lt;BR&gt;задача которых — осуществлять взаимодействие с базой данных, размещая весь&lt;BR&gt;код, ответственный за пользовательский интерфейс, в других классах.&lt;BR&gt;Создание проекта&lt;BR&gt;Если для разработки используется Visual Studio.NET, то следует создать новый&lt;BR&gt;проект с типом С# | Class Library и назвать его NewsMaiierDB. Затем необходимо&lt;BR&gt;приступить к созданию файлов классов для данного модуля, что будет объясняться&lt;BR&gt;в следующих разделах. Необходимо создать новый файл для каждого класса с по-&lt;BR&gt;мощью команды Project | Add New Class, либо с помощью Project | Add Existing Item,&lt;BR&gt;если вы пожелаете импортировать готовые файлы с web-сайта издательства Wrox.&lt;BR&gt;Обратите внимание на то, что код этих бизнес-классов воспроизводится&lt;BR&gt;в тексте книги.&lt;BR&gt;Класс ListsDB&lt;BR&gt;Класс ListsDB предоставляет все функциональные возможности, необходимые&lt;BR&gt;как для выполнения манипуляций над уже существующими списками рассылки, так&lt;BR&gt;и для создания новых. Информация об этом классе сведена в следующую таблицу:&lt;BR&gt;Класс ListsDB&lt;BR&gt;Метод Описание&lt;BR&gt;public ListsDB (string ConnString)&lt;BR&gt;public DataSet GetListsO&lt;BR&gt;public DataRow GetDetails(int ListID)&lt;BR&gt;public bool Add (string ListName,&lt;BR&gt;string listDescr)&lt;BR&gt;public bool Delete (int ListID)&lt;BR&gt;bool Update (int ListID, string ListName,&lt;BR&gt;string listDescr)&lt;BR&gt;Конструктор класса, которому в качестве параметра&lt;BR&gt;передается строка соединения, описываемая в установках&lt;BR&gt;файла (к их обсуждению мы перейдем позже)&lt;BR&gt;Возвращает объект DataSet, в котором содержатся&lt;BR&gt;все доступные списки новостей&lt;BR&gt;Позволяет получать подробную информацию о списке&lt;BR&gt;по заданному идентификатору&lt;BR&gt;Добавляет новый список с заданным именем и описанием&lt;BR&gt;Удаляет указанный список&lt;BR&gt;Позволяет изменять свойства Name и Description&lt;BR&gt;указанного списка&lt;BR&gt;Метод GetListsO возвращает набор данных, в котором находится все содержи-&lt;BR&gt;мое таблицы Lists, то есть все доступные списки и их свойства. Этот метод воз-&lt;BR&gt;вращает единственный список, который задается идентификатором, передаваемым&lt;BR&gt;методу в качестве параметра.&lt;BR&gt;С помощью метода Delete о можно удалить запись с идентификатором, преда-&lt;BR&gt;ваемым этому методу в качестве параметра. Почти так же работают методы Add о&lt;BR&gt;и update о за исключением того, что параметры могут содержать еще и данные,&lt;BR&gt;которые должны быть модифицированы или добавлены.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 803&lt;BR&gt;Класс SiibscribersDB&lt;BR&gt;Класс SubscribersDB предназначается для доступа к таблицам subscribers&lt;BR&gt;и usersData. Он обладает структурой, аналогичной структуре класса ListsDB,&lt;BR&gt;и хранится в файле subscribers.cs. Все методы этого класса сведены в следую-&lt;BR&gt;щую таблицу: s&lt;BR&gt;Класс Subscribers&lt;BR&gt;ЭВМетод Описание&lt;BR&gt;public SubscribersDB (string ConnString)&lt;BR&gt;public DataSet GetSubscribers(int ListID)&lt;BR&gt;public DataRow GetDetails(int SubscrlD)&lt;BR&gt;public bool Add(int ListID, string FirstName,&lt;BR&gt;string LastName, string Email)&lt;BR&gt;public bool Delete (int SubscrlD)&lt;BR&gt;public bool Update (int SubscrlD, string FirstName,&lt;BR&gt;string LastName, string Email)&lt;BR&gt;public int GetUserID(int SubscrlD)&lt;BR&gt;public int GetUserID(string Email)&lt;BR&gt;public int GetSubscriberID(int ListID,&lt;BR&gt;string Email)&lt;BR&gt;Конструктор класса, которому в качестве&lt;BR&gt;параметра передается строка соединения,&lt;BR&gt;описываемая в установках файла&lt;BR&gt;Возвращает список подписчиков данного списка&lt;BR&gt;Позволяет получать подробную информацию&lt;BR&gt;о списке по заданному идентификатору&lt;BR&gt;Добавляет нового подписчика&lt;BR&gt;Удаляет подписчика&lt;BR&gt;Позволяет обновить подробную персональную&lt;BR&gt;информацию о подписчике&lt;BR&gt;Возвращает идентификатор пользователя&lt;BR&gt;по заданному идентификатору подписки&lt;BR&gt;Возвращает идентификатор пользователя&lt;BR&gt;по заданному адресу электронной почты&lt;BR&gt;Возвращает идентификатор подписчика&lt;BR&gt;для конкретного списка и конкретного&lt;BR&gt;пользователя, определяемый по уникальному&lt;BR&gt;адресу электронной почты&lt;BR&gt;Этот класс оказывается несколько более сложным, чем класс ListsDB, поскольку&lt;BR&gt;ему приходится иметь дело с двумя таблицами и управлять отношениями между&lt;BR&gt;ними. Функция GetSubscribers о возвращает всех подписчиков того списка, иден-&lt;BR&gt;тификатор которого передан ему в качестве параметра. В нем используется&lt;BR&gt;SQL-оператор, в котором содержится команда INNER JOIN, позволяющая получать&lt;BR&gt;информацию сразу ИЗ двух таблиц — UsersData И Subscribers!&lt;BR&gt;public DataSet GetSubsctibers (int ListID)&lt;BR&gt;string sqlCmd = &quot;SELECT FirstName, LastName, Email, &quot;;&lt;BR&gt;sqlCmd += &quot;ListID, UserlD, CreatedDate, Subsctibers.ID FROM UsersData &quot;;&lt;BR&gt;sqlCmd += &quot;INNER JOIN Subscribers ON UsersData.ID= Subsctibers.UserlD &quot;;&lt;BR&gt;sqlCmd += &quot;WHERE Subscribers.ListID = * + ListID;&lt;BR&gt;DataSet subsctibers = new DataSet();&lt;BR&gt;OleDbConnection myConn = new OleDbConnection(connString) ;&lt;BR&gt;OleDbDataAdapter myDAdp = new OleDbDataAdapter (sqlCmd, myConn) ;&lt;BR&gt;myDAdp.Fill(subscribers, &quot;Subscribers*);&lt;BR&gt;return subscribers;&lt;BR&gt;Метод GetDetaiisO практически полностью аналогичен соответствующему ме-&lt;BR&gt;тоду класса ListsDB; отличие заключается в SQL-строке, которая у него такая же,&lt;BR&gt;как приведенная выше.&lt;BR&gt;804 Практический пример&lt;BR&gt;МеТОДЫ Add(), D e l e t e () И Update () ПОЗВОЛЯЮТ ВСТаВЛЯТЬ, удаЛЯТЬ И МОДИфиЦИ-&lt;BR&gt;ровать подписку пользователей в новые списки. Они выполняют эту работу не-&lt;BR&gt;сколько по-другому, чем соответствующие методы класса ListsDB. Функция&lt;BR&gt;Delete о сначала удаляет подписчика из указанного списка, а затем производит&lt;BR&gt;проверку, включен ли данный пользователь в какие-либо другие списки. Если нет,&lt;BR&gt;то информация о пользователе удаляется из таблицы usersData. Функция Add о не&lt;BR&gt;только добавляет подписчика в указанный список, но и проверяет, не совпадает ли&lt;BR&gt;переданный ей адрес электронной почты с каким-либо адресом, уже имеющимся&lt;BR&gt;в таблице UsersData. Если нет, то делается предположение, что это новый пользо-&lt;BR&gt;ватель, и он добавляется в таблицу. Для создаваемого приложения мы будем исхо-&lt;BR&gt;дить из предположения, что каждое вхождение поля электронной почты представляет&lt;BR&gt;уникального пользователя.&lt;BR&gt;Далее приведены две перезагрузки метода GetuseriDO, которые предназнача-&lt;BR&gt;ются для внутреннего использования методами Delete о и Add(). Первый вариант&lt;BR&gt;принимает в качестве параметра идентификатор подписчика и возвращает иденти-&lt;BR&gt;фикатор пользователя, привязанный к данной подписке; этот метод используется&lt;BR&gt;внутри метода Delete (). Вторая перезагрузка принимает в качестве параметра&lt;BR&gt;строку адреса электронной почты и возвращает идентификатор пользователя, при-&lt;BR&gt;вязанный к данному адресу, если таковой существует; этот метод используется&lt;BR&gt;внутри метода Add ().&lt;BR&gt;Последняя функция данного класса — GetSubscriberiDO — возвращает иден-&lt;BR&gt;тификатор подписчика определенного списка по указанному адресу электронной&lt;BR&gt;почты. Эта функция используется методом Add(), чтобы определить, существует&lt;BR&gt;ли уже пользователь, который осуществляет подписку на данный список, в табли-&lt;BR&gt;це UsersData, ИЛИ нет.&lt;BR&gt;Класс NewsHistoryDB&lt;BR&gt;КлаСС NewsHistoryDB (который Хранится В файле NewsMailerDB.cs) ЯВЛЯеТСЯ&lt;BR&gt;самым простым из всех; он состоит всего лишь из четырех методов и параметризо-&lt;BR&gt;ванного конструктора метода, как показано в приведенной ниже таблице:&lt;BR&gt;Класс NewsHistoryDB&lt;BR&gt;Метод Описание&lt;BR&gt;public NewsHistoryDB (string ConnString) Конструктор класса, которому в качестве параметра&lt;BR&gt;передается строка соединения, которая описывается&lt;BR&gt;в установках файла&lt;BR&gt;public DataSet GetNews(int ListiD) Возвращает все наименования новостей&lt;BR&gt;для указанного списка&lt;BR&gt;public DataRow GetDetails (int NewslD) Позволяет получать строку, которая идентифицирует&lt;BR&gt;указанную запись News&lt;BR&gt;public bool Add (int List ID, string Subject, Добавляет подробную информацию о записи&lt;BR&gt;string Body/ bool isHTML) c новостями в заданный список&lt;BR&gt;public bool Delete (int NewslD) Удаляет указанную запись News&lt;BR&gt;Компиляция модуля&lt;BR&gt;Когда создание всех файлов завершено, можно откомпилировать модуль. Если&lt;BR&gt;вы выполняли все действия в Visual Studio.NET, то ваш Solution Explorer должен&lt;BR&gt;принять вид, изображенный на рисунке на стр. 805.&lt;BR&gt;Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 805&lt;BR&gt;Solution EKpforer ~ NewsMaifet&lt;BR&gt;&apos; э&lt;BR&gt;r*(I project)&lt;BR&gt;й-&lt;BR&gt;ЕЬ Й References&lt;BR&gt;§1) AssernblyInfoDB.es&lt;BR&gt;§g| ListsDB.cs&lt;BR&gt;«3] NewsHistoryDB.es&lt;BR&gt;|8] SubscribersDB.es&lt;BR&gt;soiu- 1 Class Vii&lt;BR&gt;Файл Assembiyinfo.es содержит множество всех атрибутов,&lt;BR&gt;которые транслируются в модуль наряду с исходными файлами.&lt;BR&gt;Этот файл создается Visual Studio.NET по умолчанию в момент&lt;BR&gt;создания проекта. Мы не будем вносить в него какие бы то ни&lt;BR&gt;было изменения. •&lt;BR&gt;При этом в режиме Class&lt;BR&gt;View должна выводиться&lt;BR&gt;картинка, представленная на&lt;BR&gt;рисунке справа.&lt;BR&gt;Компиляция модуля за-&lt;BR&gt;ключается в использовании&lt;BR&gt;команды Build в VS.NET.&lt;BR&gt;* 4 t &amp;gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/prakticheskij_primer_2_menedzher_rassylki_novostej_v_rezhime_onlajn/2010-02-11-408</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/prakticheskij_primer_2_menedzher_rassylki_novostej_v_rezhime_onlajn/2010-02-11-408</guid>
			<pubDate>Wed, 10 Feb 2010 21:59:12 GMT</pubDate>
		</item>
		<item>
			<title>Управление опросами</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Управление опросами&lt;BR&gt;&lt;/SPAN&gt;Одно из преимуществ .NET перед предшествующими технологиями заключает-&lt;BR&gt;ся в том, что возможность повторного использования создаваемого программного&lt;BR&gt;обеспечения несколько упрощается. В этом разделе мы собираемся создать пакет&lt;BR&gt;web-сайта для проведения опросов, с тем чтобы иметь возможность вставлять&lt;BR&gt;этот сайт в любую страницу ASP.NET при помощи всего лишь пары строк кода.&lt;BR&gt;На данном этапе необходимо выполнить довольно значительный объем работы,&lt;BR&gt;для того чтобы интегрировать процедуру проведения опроса в какую-либо другую&lt;BR&gt;web-страницу, поскольку для этого потребуется скопировать соответствующую ин-&lt;BR&gt;формацию как из файла с расширением .aspx, так и из файла &quot;с кодом поддерж-&lt;BR&gt;ки&quot;, который имеет расширение .aspx.cs. Мы будем создавать управляющий&lt;BR&gt;элемент таким образом, что в качестве дополнительной возможности он будет вы-&lt;BR&gt;водить страницу с опросом, и если данный пользователь уже проголосовал ранее,&lt;BR&gt;...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Управление опросами&lt;BR&gt;&lt;/SPAN&gt;Одно из преимуществ .NET перед предшествующими технологиями заключает-&lt;BR&gt;ся в том, что возможность повторного использования создаваемого программного&lt;BR&gt;обеспечения несколько упрощается. В этом разделе мы собираемся создать пакет&lt;BR&gt;web-сайта для проведения опросов, с тем чтобы иметь возможность вставлять&lt;BR&gt;этот сайт в любую страницу ASP.NET при помощи всего лишь пары строк кода.&lt;BR&gt;На данном этапе необходимо выполнить довольно значительный объем работы,&lt;BR&gt;для того чтобы интегрировать процедуру проведения опроса в какую-либо другую&lt;BR&gt;web-страницу, поскольку для этого потребуется скопировать соответствующую ин-&lt;BR&gt;формацию как из файла с расширением .aspx, так и из файла &quot;с кодом поддерж-&lt;BR&gt;ки&quot;, который имеет расширение .aspx.cs. Мы будем создавать управляющий&lt;BR&gt;элемент таким образом, что в качестве дополнительной возможности он будет вы-&lt;BR&gt;водить страницу с опросом, и если данный пользователь уже проголосовал ранее,&lt;BR&gt;он сможет только ознакомиться с результа-&lt;BR&gt;тами опроса — страница голосования выво-&lt;BR&gt;диться не будет.&lt;BR&gt;Для того чтобы создать пакет для прове-&lt;BR&gt;дения голосования, нужно разработать не-&lt;BR&gt;стандартный управляющий элемент, который&lt;BR&gt;будет реализован в классе, наследуемом от&lt;BR&gt;класса control, описанного в .NET Framework.&lt;BR&gt;Для начала в Visual Studio.NET следует&lt;BR&gt;щелкнуть правой кнопкой мыши на проекте&lt;BR&gt;web-приложения (poiiw), выбрать меню Add,&lt;BR&gt;а в нем пункт Add New Item. В появившемся&lt;BR&gt;диалоговом окне нужно выбрать иконку&lt;BR&gt;Web Custom Control и ввести в поле Name&lt;BR&gt;Poiicontroi.cs, как это проиллюстрировано&lt;BR&gt;на рисунке слева.&lt;BR&gt;Хотя Visual Studio.NET генерирует несколько строк кода, для того чтобы нам&lt;BR&gt;было с чего начинать (при этом реализуется свойство Text создаваемого управля-&lt;BR&gt;ющего элемента), однако нам все это не понадобится, поэтому для начала работы&lt;BR&gt;нужно привести класс к еще более простому виду:&lt;BR&gt;using System;&lt;BR&gt;using System,Web.UI;&lt;BR&gt;using System.Web.Ul.WebControls;&lt;BR&gt;using System.ComponentModel;&lt;BR&gt;namespace PollW&lt;BR&gt;III &lt;summary&amp;gt;&lt;BR&gt;/// Краткое описание класса PollControl.&lt;BR&gt;/// &lt;/summary&amp;gt; ,&lt;BR&gt;public class PollControl : WebGontrol&lt;BR&gt;{ &apos; .• . ... •• •• •• • •••. . • • • . • &apos; • - • • - • ; • . . .. • . , . • . , &apos;&lt;BR&gt;protected override void Render(KtmlTextWriter output)&lt;BR&gt;output.Write(&quot;This is my Poll Control&quot;);&lt;BR&gt;: / Это управляющий элемент для проведения опросов /&lt;BR&gt;»J&lt;BR&gt;Л ck*s :ot --testae, an ASP-KET server &lt;c*v/c*&lt;BR&gt;Cancel&lt;BR&gt;Практический пример 1 — юеЪ-сайт для проведения опросов 791&lt;BR&gt;Заметьте, что все, что на самом деле необходимо выполнить,— это создать&lt;BR&gt;класс, который наследуется от System.web.ui.webcontrois.webcontroi. Сделав&lt;BR&gt;это, мы реализуем переопределение метода Render о , в котором генерируем&lt;BR&gt;HTML, который мы планируем выводить. Существует также возможность напи-&lt;BR&gt;сать такой управляющий элемент, который будет создавать себя сам посредством&lt;BR&gt;объединения других управляющих элементов, но в настоящем примере мы будем&lt;BR&gt;генерировать HTML.&lt;BR&gt;IS&lt;BR&gt;H&lt;BR&gt;Web Service&lt;BR&gt;Component&lt;BR&gt;•MS&lt;BR&gt;Web User&lt;BR&gt;Control&lt;BR&gt;Data fotm&lt;BR&gt;Wizard&lt;BR&gt;Class&lt;BR&gt;Data Set&lt;BR&gt;HTML Рг$е&lt;BR&gt;zi&lt;BR&gt;•: j defaults. a$px&lt;BR&gt;Попытаемся вставить в страницу&lt;BR&gt;простой нестандартный управляющий&lt;BR&gt;элемент и посмотреть, что для этого&lt;BR&gt;придется сделать. Во-первых, добавим&lt;BR&gt;к нашему проекту новую страницу,&lt;BR&gt;КОТОруЮ назовем default2.aspx И КО-&lt;BR&gt;торую мы будем использовать в ка-&lt;BR&gt;честве контейнера нестандартного&lt;BR&gt;управляющего элемента. Это дости-&lt;BR&gt;гается за счет использования пункта&lt;BR&gt;Add Web Form из меню Project, как&lt;BR&gt;показано на рисунке слева.&lt;BR&gt;Мы приведем в порядок содержи-&lt;BR&gt;мое default2.aspx, чтобы ничего не&lt;BR&gt;усложнять и четко представлять себе,&lt;BR&gt;что происходит:&lt;BR&gt;&lt;%@ Page language=&quot;c#&quot; Codebehind= default2.aspx.es&quot; %&amp;gt;&lt;BR&gt;. •.-.; . &lt; h e a d &amp;gt; . . * . . : •: ;&lt;BR&gt;&lt; / h e a d &amp;gt; •,•••• . • • . : . • . ; . • • . &apos; : ; •/•• .:• . : • • • • . , . : • • : &apos; &apos; - &apos; : :-. .&apos; • ... . .&lt;BR&gt;• •&apos;• &apos; ; • / • : : &lt; b o d y &amp;gt; &apos;&apos; : &apos; :- • &apos; •&apos; •&apos;&apos; ; . &apos; . &apos; • ; - .•• . ••• • &apos;&apos; : ^ ••••;/ . . . .&lt;BR&gt;: : . ; . . &apos; &lt; / b o d y &amp;gt; . •&apos; &apos;&apos; •&apos; &apos;&apos;&apos;.•• • • &apos; . . • &apos; • • &apos; . • . , • • • • ; • • . . • • • • - • • • • • : . . •&lt;BR&gt;&lt;/html&amp;gt;&lt;BR&gt;Для того чтобы вставить управляющий элемент для проведения опросов в стра-&lt;BR&gt;ницу, следует добавить всего две строки:&lt;BR&gt;&lt;%@ Page language^1 с#&quot; Codebehind= default2.aspx.es1&apos; ......%&amp;gt;&lt;BR&gt;&lt;%@ Register TagPref ix=&quot;Wrox&quot; Namespace=&quot;PollWn Assembly:=tlPollW11 %&amp;gt;&lt;BR&gt;&lt;html&amp;gt;&lt;BR&gt;&lt;head&amp;gt;&lt;BR&gt;&lt;/head&amp;gt;&lt;BR&gt;&lt;body&amp;gt;&lt;BR&gt;&lt;Wrox:PollControll runat=&quot;server&quot;&amp;gt;&lt;/Wrox:PollControl&amp;gt;&lt;BR&gt;&lt;/body&amp;gt;&lt;BR&gt;&lt;/html&amp;gt;&lt;BR&gt;В первой из двух добавленных строк объявляется префикс тегов TagPrefix&lt;BR&gt;с именем Wrox. Это означает, что если ASP.NET встречает на странице любой&lt;BR&gt;серверный управляющий элемент, который начинается с &lt;wrox:, то система начи-&lt;BR&gt;нает осуществлять поиск в пространстве имен Poiiw в модуле Poiiw управляющего&lt;BR&gt;элемента с таким же именем. В данном случае мы указали &lt;wrox:Poiicontroi&amp;gt;,&lt;BR&gt;поэтому ASP.NET будет осуществлять поиск в пространстве имен Poiiw класса&lt;BR&gt;Poiicontroi. Вторая добавленная строка представляет собой серверный управляю-&lt;BR&gt;щий элемент, и именно в ней мы фактически вставляем опрос в страницу. Обратите&lt;BR&gt;792 Практический пример&lt;BR&gt;Fife Edit View Favorites Tools Help&lt;BR&gt;Г Personal Bat ^Search 3j Favorites&lt;BR&gt;-jhttp.7/localhost/poHw/defdulK2.aspx&lt;BR&gt;This is my Poll Control&lt;BR&gt;zl&lt;BR&gt;внимание на то, что мы включили&lt;BR&gt;в нее атрибут runat. Если же теперь&lt;BR&gt;ОТКрЫТЬ файл def a u l t2 . aspx В Своем&lt;BR&gt;браузере, то можно увидеть текст,&lt;BR&gt;выводящийся методом Poiicontroi&lt;BR&gt;Render () (см. рис. слева).&lt;BR&gt;Мы успешно вставили в стра-&lt;BR&gt;ницу нестандартный управляющий&lt;BR&gt;элемент; теперь добавим в метод&lt;BR&gt;Render о , находящийся в файле&lt;BR&gt;Poiicontroi.cs, код, который по-&lt;BR&gt;зволит выводить опрос на экран.&lt;BR&gt;Упомянутый код оказывается практически идентичным коду для &quot;файла поддерж-&lt;BR&gt;ки&quot; default.aspx.cs. He забудьте, что в начале файла необходимо поместить опе-&lt;BR&gt;ратор using Polling:&lt;BR&gt;protected override void Render(ЯtmlTextWriter output)&lt;BR&gt;s t r i n g H t m l = * w ; • •&apos;••;•••• . &apos; r ... .••••&apos; y : .&apos;.-.• • • • . &apos; • • : • • &apos;•&lt;BR&gt;Poll aPoll = Poll.Current();&lt;BR&gt;Html += aPoll,Question + *&lt;br /xbr /&amp;gt;&quot;&apos;,&lt;BR&gt;f or (int i=l&apos;•; i&lt;=aPoll. AnswerCount; i++}&lt;BR&gt;I l o c e infc»&lt;BR&gt;HtmlLink += *&lt;a href=&amp;#92;//vote.aspx?id=&quot;+i + ll&amp;#92;&lt;BR&gt;HtmlLink += &quot;Scnbsp; * + aPol 1 Answers [i] + &quot;&lt;br /&amp;gt;&quot;}&lt;BR&gt;}&lt;BR&gt;output.Write(Html);&lt;BR&gt;fife &amp;pound;dfc View Favorites&lt;BR&gt;Toosшl шHшeplшш&lt;BR&gt;:avorites&lt;BR&gt;.aspx jj 4^Sc i Links&lt;BR&gt;Если теперь построить проект заново и открыть файл defauit2. aspx, то можно&lt;BR&gt;увидеть то же самое, что и в случае default.aspx за исключением того, что эту&lt;BR&gt;версию гораздо проще использовать повторно. Все, что необходимо сделать для&lt;BR&gt;того чтобы использовать ее на некото-&lt;BR&gt;ром сайте, — это сначала убедиться&lt;BR&gt;в доступности файла vote.aspx, затем&lt;BR&gt;убедиться в доступности модулей, со-&lt;BR&gt;держащих классы Poll И PollControl,&lt;BR&gt;после чего просто добавить две строки&lt;BR&gt;кода к странице ASP.NET. В резуль-&lt;BR&gt;тате этих действий получилась некая&lt;BR&gt;оболочка, объемлющая отдельные&lt;BR&gt;функциональные возможности. Мы&lt;BR&gt;назвали ее управляющим web-элемен-&lt;BR&gt;том. Этот подход позволяет объеди-&lt;BR&gt;нять различные функциональные воз-&lt;BR&gt;можности и облегчает их повторное&lt;BR&gt;использование. Результат можно ви-&lt;BR&gt;деть на рисунке справа.&lt;BR&gt;What development language do you primarily use?&lt;BR&gt;Vote C#&lt;BR&gt;VoteC-H- . ,&lt;BR&gt;Vote Java&lt;BR&gt;Vote JavaScript&lt;BR&gt;Vote Visual Bask&lt;BR&gt;fe] Done trarjet A&lt;BR&gt;Практический пример 1 — weh-caum для проведения опросов 793&lt;BR&gt;Трехзвенность и приложение Poll&lt;BR&gt;Уровень&lt;BR&gt;представления&lt;BR&gt;Уровень&lt;BR&gt;бизнес-логики&lt;BR&gt;Уровень&lt;BR&gt;данных&lt;BR&gt;Консольное&lt;BR&gt;приложение&lt;BR&gt;Приложение&lt;BR&gt;Windows Forms&lt;BR&gt;Web-службы&lt;BR&gt;Класс Poll&lt;BR&gt;C:&amp;#92;Polls.xml&lt;BR&gt;Приложение&lt;BR&gt;WebForm&lt;BR&gt;Итоги&lt;BR&gt;Нами создано приложение, которое может функционировать и как консольное&lt;BR&gt;приложение, и как web-служба, и как приложение Windows Forms, и как Интернет-&lt;BR&gt;интерфейс ASP.NET. Для того чтобы наглядно представлять себе, как все эти&lt;BR&gt;отдельные части соотносятся друг с&lt;BR&gt;другом, слева приведена диаграмма,&lt;BR&gt;на которой изображены основные&lt;BR&gt;элементы приложения Poll и проил-&lt;BR&gt;люстрировано, каким образом это&lt;BR&gt;приложение вписывается в модель&lt;BR&gt;трехзвенной архитектуры, состоящую&lt;BR&gt;из уровня данных, уровня бизнес-&lt;BR&gt;логики и уровня представления.&lt;BR&gt;Заметьте, что несмотря на то,&lt;BR&gt;что приложение Windows Forms&lt;BR&gt;обычно взаимодействует с классом&lt;BR&gt;Poll посредством web-службы, ему не придется этого делать, если оно будет запу-&lt;BR&gt;щено на той же машине, что и класс Poll (другими словами, на web-сервере).&lt;BR&gt;Данный практический пример позволил продемонстрировать, каким образом&lt;BR&gt;можно применить теорию по С# и .NET, изучавшуюся нами на протяжении всей&lt;BR&gt;настоящей книги, в ситуации из реальной жизни, где перед нами возникла задача&lt;BR&gt;создать приложение, которое было бы доступно посредством различных пользова-&lt;BR&gt;тельских интерфейсов. В этом практическом примере воссоздается ситуация из&lt;BR&gt;реальной жизни в том смысле, что мы на первой итерации создаем первоначаль-&lt;BR&gt;ную версию приложения, а затем добавляем в него новые функциональные воз-&lt;BR&gt;можности. В мире коммерческих продуктов программное обеспечение не пишется —&lt;BR&gt;оно модифицируется, и именно это мы и попытались здесь продемонстрировать.&lt;BR&gt;В качестве краткого напоминания перечислим приемы и технологии, которые&lt;BR&gt;были использованы в этом практическом примере:&lt;BR&gt;• Бизнес-объекты (класс Poll)&lt;BR&gt;• Генерирование исключительных ситуаций&lt;BR&gt;Q Нестандартный управляющий элемент ASP.NET&lt;BR&gt;• Серверные управляющие элементы ASP.NET&lt;BR&gt;• Статически методы класса&lt;BR&gt;• Наборы данных XML и ADO.NET&lt;BR&gt;• Web-службы и web-методы&lt;BR&gt;• System.Timer (таймер)&lt;BR&gt;• НТТР-куки&lt;BR&gt;• Класс HttpContext&lt;BR&gt;794 Практический пример&lt;BR&gt;• Уровень представления, поддерживающий множество интерфейсов&lt;BR&gt;• Консольное приложение&lt;BR&gt;• Приложение Windows Forms&lt;BR&gt;• Трехзвенная архитектура&lt;BR&gt;• Объектно-ориентированная разработка&lt;BR&gt;• Тестирование программного обеспечения&lt;BR&gt;Надеемся, что вы получили удовольствие от чтения этой главы, а информация,&lt;BR&gt;которую вы из нее почерпнули, вдохновит вас на создание своего собственного&lt;BR&gt;приложения на С#. .NET в сочетании с такими методами, как трехзвенная архи-&lt;BR&gt;тектура и объектно-ориентированная разработка, оказывается чрезвычайно мощ-&lt;BR&gt;ной платформой для разработки программных приложений, а С# — наиболее&lt;BR&gt;эффективным из всех языков программирования, входящих в состав .NET.&lt;BR&gt;&lt;BR&gt;</content:encoded>
			<link>https://krutoto.ucoz.ru/news/upravlenie_oprosami/2010-02-11-407</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/upravlenie_oprosami/2010-02-11-407</guid>
			<pubDate>Wed, 10 Feb 2010 21:58:24 GMT</pubDate>
		</item>
		<item>
			<title>Пользовательский интерфейс (уровень представления)</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Пользовательский интерфейс (уровень представления)&lt;BR&gt;&lt;/SPAN&gt;Завершив создание уровня данных&lt;BR&gt;и уровня бизнес-логики и поэксперимен-&lt;BR&gt;тировав с консольным приложением на&lt;BR&gt;уровне представления, можно перейти&lt;BR&gt;к созданию web-интерфейса для опроса&lt;BR&gt;с использованием ASP.NET. Прежде все-&lt;BR&gt;го необходимо добавить проект ASP.NET&lt;BR&gt;в наше решение в Visual Studio.NET.&lt;BR&gt;Назовем его Poiiw (сокращение от Poll&lt;BR&gt;Web), как показано на рисунке слева.&lt;BR&gt;Заметьте, что при создании нового&lt;BR&gt;web-приложения Visual Studio.NET авто-&lt;BR&gt;матически генерирует несколько файлов,&lt;BR&gt;ВКЛЮЧая файл WebForml. aspx — началь-&lt;BR&gt;ную страницу ASP.NET. Переименуем ее&lt;BR&gt;В default.aspx С тем, чтобы МОЖНО было&lt;BR&gt;*&quot;^Л&apos; &quot; ~С***&apos;*&lt;BR&gt;Project Types:&lt;BR&gt;j l &apos; ----- С* Projects&lt;BR&gt;CJ Seiyp -and Deployment Prefects&lt;BR&gt;*&quot; LJ Other Projects window&lt;BR&gt;Application Windows&lt;BR&gt;:i Шш&lt;BR&gt;Щ&lt;BR&gt;МС library&lt;BR&gt;ASPJNE T Web w«b Ox*&lt;BR&gt;_rJ&lt;BR&gt;Location;&lt;BR&gt;Project vM be created at hltp://locdhost/...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Пользовательский интерфейс (уровень представления)&lt;BR&gt;&lt;/SPAN&gt;Завершив создание уровня данных&lt;BR&gt;и уровня бизнес-логики и поэксперимен-&lt;BR&gt;тировав с консольным приложением на&lt;BR&gt;уровне представления, можно перейти&lt;BR&gt;к созданию web-интерфейса для опроса&lt;BR&gt;с использованием ASP.NET. Прежде все-&lt;BR&gt;го необходимо добавить проект ASP.NET&lt;BR&gt;в наше решение в Visual Studio.NET.&lt;BR&gt;Назовем его Poiiw (сокращение от Poll&lt;BR&gt;Web), как показано на рисунке слева.&lt;BR&gt;Заметьте, что при создании нового&lt;BR&gt;web-приложения Visual Studio.NET авто-&lt;BR&gt;матически генерирует несколько файлов,&lt;BR&gt;ВКЛЮЧая файл WebForml. aspx — началь-&lt;BR&gt;ную страницу ASP.NET. Переименуем ее&lt;BR&gt;В default.aspx С тем, чтобы МОЖНО было&lt;BR&gt;*&quot;^Л&apos; &quot; ~С***&apos;*&lt;BR&gt;Project Types:&lt;BR&gt;j l &apos; ----- С* Projects&lt;BR&gt;CJ Seiyp -and Deployment Prefects&lt;BR&gt;*&quot; LJ Other Projects window&lt;BR&gt;Application Windows&lt;BR&gt;:i Шш&lt;BR&gt;Щ&lt;BR&gt;МС library&lt;BR&gt;ASPJNE T Web w«b Ox*&lt;BR&gt;_rJ&lt;BR&gt;Location;&lt;BR&gt;Project vM be created at hltp://locdhost/PofiW.&lt;BR&gt;ссылаться на приложение следующим образом: https/ziocalhost/Pollw. У файла&lt;BR&gt;default.aspx имеется привязанный к нему файл defauit.aspx.es с кодом под-&lt;BR&gt;держки. Мы скоро приступим к работе с ним. Совершенно очевидно, что если&lt;BR&gt;web-сервер выполняется не на вашей локальной машине, то необходимо указать&lt;BR&gt;имя вашего сервера, а не использовать слово locaihost.&lt;BR&gt;Но прежде необходимо подумать об одном важном моменте. Использование&lt;BR&gt;ASP.NET позволяет создать фантастическую систему для построения web-форм,&lt;BR&gt;которая во многом напоминает Visual Basic, поскольку в Visual Studio.NET можно&lt;BR&gt;переносить управляющие элементы с помощью мыши и использовать программи-&lt;BR&gt;рование, основанное на работе с событиями. Однако существует одна загвоздка —&lt;BR&gt;при использовании ASP.NET можно использовать только одну форму на стороне&lt;BR&gt;766 Практический пример&lt;BR&gt;Г http://iocafhost/pollw/ - Micro&lt;BR&gt;; File gdt View Favorites Tools Help&lt;BR&gt;./ро?И&lt;BR&gt;пользователя для каждой конкретной страницы. При создании web-сайта для про-&lt;BR&gt;ведения опросов представляется логичным воспользоваться на стороне сервера&lt;BR&gt;формой, которая будет обладать, например, одним переключателем для каждого&lt;BR&gt;ответа и кнопкой Vote для регистрации сделанного выбора. Если остановиться на&lt;BR&gt;таком подходе, то страница, на которой будет проводиться опрос, не сможет содер-&lt;BR&gt;жать никаких других форм на стороне сервера, а если включить опрос на несколь-&lt;BR&gt;ко страниц web-сайта, где впоследствии потребуется добавить еще какие-либо&lt;BR&gt;формы (например, второй опрос или управляющий элемент поиска), то этого сде-&lt;BR&gt;лать будет нельзя. Чтобы избежать проблем подобного рода, а заодно получить&lt;BR&gt;возможность познакомиться с некоторыми не столь широко известными методами&lt;BR&gt;.NET, нужно воспользоваться такой моделью web-сайта для проведения опросов,&lt;BR&gt;в которой не будет использовано никаких форм на стороне сервера, т. е. перейти&lt;BR&gt;не более низкий уровень возможностей ASP.NET, который может оказаться зна-&lt;BR&gt;комым тем, программирует на ASP 3.0. И хотя использование этих возможностей&lt;BR&gt;в ASP.NET является несколько необычным, все равно будет полезно познакомить-&lt;BR&gt;ся с тем, как они работают в подобных ситуациях — когда использование формы&lt;BR&gt;на стороне сервера оказывается неприемлемым.&lt;BR&gt;Обычно в простой, отсылаемой назад форме достаточно ограничиться одной&lt;BR&gt;страницей и воспользоваться событием Onclick для кнопки отправки (кнопки&lt;BR&gt;Vote), которая позволяет зарегистрировать выбор посетителя. Однако, чтобы&lt;BR&gt;избежать использования форм на стороне&lt;BR&gt;сервера, мы собираемся использовать две&lt;BR&gt;страницы. На первой из них будет выво-&lt;BR&gt;диться вопрос и перечень возможных отве-&lt;BR&gt;тов, а рядом с каждым ответом — ссылка&lt;BR&gt;Vote (Голосую за). Эта ссылка позволяет&lt;BR&gt;передать в качестве параметра номер вы-&lt;BR&gt;бранного ответа второй странице, которая&lt;BR&gt;использует переданное ей значение для ре-&lt;BR&gt;гистрации голоса, после чего выводит на&lt;BR&gt;экран текущие результаты голосования.&lt;BR&gt;Как должна выглядеть первая страни-&lt;BR&gt;ца—default.aspx, показано на рисунке&lt;BR&gt;слева.&lt;BR&gt;I [gPersonatBar ^Search&lt;BR&gt;Какой язык программирования вы, в основном, используете?&lt;BR&gt;Голосую за С#&lt;BR&gt;Голосую за C++&lt;BR&gt;Голосую за Java&lt;BR&gt;Голосую за JavaScript&lt;BR&gt;Голосую за Visual Basic&lt;BR&gt;&quot;ГГТ&lt;BR&gt;А вот как должна выглядеть вторая стра-&lt;BR&gt;ница — vote.aspx, представлено на рисунке&lt;BR&gt;справа.&lt;BR&gt;Первая страница — default.aspx — пред-&lt;BR&gt;ставляет опрос, и когда мы выбираем первый&lt;BR&gt;из возможных ответов с помощью ссылки&lt;BR&gt;Vote, то видим, что странице vote.aspx&lt;BR&gt;в строке URL передается единица. Данный&lt;BR&gt;параметр используется для регистрации го-&lt;BR&gt;лоса. После этого vote.aspx выводит все ва-&lt;BR&gt;рианты ответов со счетчиками голосов для&lt;BR&gt;каждого из них.&lt;BR&gt;? :1&amp;pound;&amp;pound;&amp;#92;&apos;&lt;&lt;BR&gt;Fib E&lt;&amp;amp; Vim&lt;BR&gt;Address {:&lt;BR&gt;т„•: - :• ^&lt;BR&gt;У •$Search Qj&lt;BR&gt;Голосование oo вопросу &quot;Какой язык программировании&lt;BR&gt;вы, в основном, используете?&quot;&lt;BR&gt;С# 15 голосов&lt;BR&gt;О+ 2 голоса&lt;BR&gt;Java 35 голосов&lt;BR&gt;JavaScript 12 голосов&lt;BR&gt;Visual Basic 42 голоса&lt;BR&gt;&amp;pound;|~ Local intiane* /X&lt;BR&gt;Практический пример 1 — юеЪ-сайт для проведения опросов 767&lt;BR&gt;Начнем с файла ASP.NET default.aspx, созданного Visual Studio.NET. Эта&lt;BR&gt;страница является стандартной и в ней содержится несколько тегов, в частности,&lt;BR&gt;внешние HTML-теги, а также теги &lt;head&amp;gt; и &lt;body&amp;gt;:&lt;BR&gt;&lt;%@ Page Ianguuge=&quot;c#&quot; Codebehind=&quot;Default.aspx.cs&quot; AutoEventWireup=&quot;false&quot;&lt;BR&gt;Inherits=PollW.WebForml&quot; %&amp;gt;&lt;BR&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN&quot; &amp;gt;&lt;BR&gt;&lt;HTML&amp;gt;&lt;BR&gt;&lt;HEAD&amp;gt;&lt;BR&gt;. ; &amp;gt; ; / : &lt;meta name = &quot;GENERATOR&quot; Content=&quot;Microsoft Visual Studio 7.0&quot;&amp;gt;&lt;BR&gt;&lt;/HEAD&amp;gt;&lt;BR&gt;&lt;BODY&amp;gt; • .&lt;BR&gt;&lt;form id=&quot;Default&quot; method-&quot;post&quot; runat=nserver&quot;&amp;gt;&lt;BR&gt;•• , .::. ••• .&apos; V •&apos; :• . j &apos;• :&apos; v&apos; . &lt; / f o r m &amp;gt; . &apos; &quot; : , • . &apos; &apos; &apos; , .&apos; • . • &quot; &apos; &apos; &apos; • &apos; &apos; : •&apos; : •• . &quot; .. • • &apos;&lt;BR&gt;&lt;/BODY&amp;gt;&lt;BR&gt;&lt;/HTML&amp;gt;&lt;BR&gt;Обратите внимание на то, что в код также включен тег серверной формы&lt;BR&gt;(&lt;form runat=&quot;server•&amp;gt;). Первое, что нужно сделать,— удалить его; это послужит&lt;BR&gt;напоминанием того, что нами не используются формы на стороне сервера. В то же&lt;BR&gt;время мы включим пару управляющих элементов Label на стороне сервера; это&lt;BR&gt;будет сделано в том месте, где происходит вывод вопроса для опроса и перечня&lt;BR&gt;возможных ответов:&lt;BR&gt;&lt;%@ Page 1апдиаде=ис#&quot; Codebehind=&quot;Default.aspx.сs&quot; AutoEventWireup=&quot;false&quot;&lt;BR&gt;Inherits=PollW.WebForml&quot; %&amp;gt;&lt;BR&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 T r a n s i t i o n a l / / E N &quot; &amp;gt;&lt;BR&gt;&lt;HTML&amp;gt; /&lt;BR&gt;&lt;HEAD&amp;gt;&lt;BR&gt;&lt;meta name =&quot;GENERATOR&quot; Content=&quot;Microsoft Visual Studio 7.0&quot;&amp;gt;&lt;BR&gt;&lt;/HEAD&amp;gt;&lt;BR&gt;&lt;BODY&amp;gt;&lt;BR&gt;&lt;asp:Label id=&quot;QuestionLabel&quot; runat=&quot;server&quot;&amp;gt;&lt;/asp:Label&amp;gt;&lt;BR&gt;&lt;asp:Label id=&quot;AnswerLabel&quot; runat=&quot;server&quot;&amp;gt;&lt;/asp:Label&amp;gt;&lt;BR&gt;&lt;/BODY&amp;gt;&lt;BR&gt;&lt;/HTML&amp;gt;&lt;BR&gt;Теперь есть чистая страница ASP.NET с управляющим элементом Label, куда&lt;BR&gt;мы можем вывести наш вопрос. Под вопросом мы выведем возможные ответы, од-&lt;BR&gt;нако вместо того, чтобы делать это непосредственно в .aspx-файле, мы использу-&lt;BR&gt;ем ДЛЯ ЭТИХ целей файл С КОДОМ ПОДДерЖКИ — default, aspx. cs.&lt;BR&gt;Здесь используется стандартный код, передаваемый Visual Studio.NET в файл&lt;BR&gt;default.aspx.cs, который осуществляет основную обработку событий, а также&lt;BR&gt;содержит стандартные методы для инициализации и загрузки страницы. Обратите&lt;BR&gt;внимание на то, как Visual Studio.NET генерирует обработчик событий для метода&lt;BR&gt;Page_init(); именно так объект Page вызывает метод Page_init{) после его со-&lt;BR&gt;здания:&lt;BR&gt;using Polling;&lt;BR&gt;using System;&lt;BR&gt;using System.Collections;&lt;BR&gt;using System.ComponentModel; . :&lt;BR&gt;: using System.Data; : : :&lt;BR&gt;using System.Drawing; . : .&lt;BR&gt;using Syset.Web;&lt;BR&gt;using System.Web,SeesionState;&lt;BR&gt;using System.Web.UI;&lt;BR&gt;using System.Web.Ul.WebControls;&lt;BR&gt;using SYstem.Web.UI.HtmlControls;&lt;BR&gt;768 Практический пример&lt;BR&gt;Namespace Pol1W ,&lt;BR&gt;/// &lt;summary&amp;gt; :&lt;BR&gt;///Общее описание для WebForml.&lt;BR&gt;///&lt;/summary &amp;gt;&lt;BR&gt;public class webFormi : System.Web.UI.Page&lt;BR&gt;{&lt;BR&gt;public WebForm ()&lt;BR&gt;§0A-:: . { ;&apos;• •&lt;BR&gt;Page Init += new System.EventHandler (Page_Init);&lt;BR&gt;}&lt;BR&gt;private void Page_Load (object sender, System.EventArgs e)&lt;BR&gt;// Ввод кода пользователя для инициализации страницы&lt;BR&gt;&amp;gt; &apos; &apos; :•• : •&lt;BR&gt;private void Page_Init (object sender, EventArgs e)&lt;BR&gt;{&lt;BR&gt;• •&apos;• &apos; : • • . • • : • . . . • • • : • : . • • • / / &apos;... •&apos;.[,&apos; • &quot; ; ; ^ ;•:. ; • ; V • , &apos; x : &amp;#92; - •.&apos; •. • - . : . ^ . ; &apos;:•• , &apos; • : . .: ; &apos; &quot; &apos; : ; ; : : &apos; - - :&lt;BR&gt;// Генерация кода: Этот запрос требуется ASP.NET&lt;BR&gt;//&lt;BR&gt;InitializeComponent ();&lt;BR&gt;•illlll Ь У : - ;. ;&lt;BR&gt;#region Web Form Designer geenrated code&lt;BR&gt;/// &lt;summary&amp;gt;&lt;BR&gt;/// Необходимый метод для поддержки Design - не модифицировать&lt;BR&gt;/// содержание этого метода с помощью редактора кода.&lt;BR&gt;/ ,:. ••&apos;,:&quot;: • .&apos; . /// &lt; / s u m m a r y &amp;gt; .&apos;, ;.;•••&apos;&apos; /_; .&apos;.&apos;:&apos;: .&apos;&apos;.,:-..&apos; :&apos;• &apos;-:: / : .&apos;:&apos;•• &apos;•&apos;•:-V-:;&apos;-&apos; :&quot;: &apos; У •&lt;BR&gt;private void InitializeComponent ();&lt;BR&gt;{&lt;BR&gt;: .. . this load += new System.EventHandler (this.Page_Load) ;&lt;BR&gt;Первое изменение, которое необходимо внести, заключается в добавлении объ-&lt;BR&gt;явлений ДОЯ QuestionLabel И AnswerLabel, ЧТО ПОЗВОЛИТ ИСПОЛЬЗОВаТЬ ИХ ИЗ КОДа&lt;BR&gt;поддержки страницы. Если вы используете Visual Studio.NET и переносили управ-&lt;BR&gt;ляющие элементы Label мышью, а не добавляли их вручную, то все уже сделано&lt;BR&gt;за вас. В самом верху класса WebForml, непосредственно перед конструктором&lt;BR&gt;должны появиться следующие строки:&lt;BR&gt;public class WebForml : System.Web.UI.Page :&lt;BR&gt;{ , : . ^&lt;BR&gt;protected System.Web.Ul.WebControls.Label QuestionLabel;&lt;BR&gt;protected System.Web.Ul.WebControls.Label AnswerLabel;&lt;BR&gt;Основное внимание мы уделим методу Page__Load (), который вызывается в тот&lt;BR&gt;момент, когда страница запрашивается браузером. Внутрь этого метода мы помес-&lt;BR&gt;тим код, отвечающий за вывод текста вопроса, и добавим управляющие элементы&lt;BR&gt;HTML для каждого из возможных ответов. Давайте пройдем по данному методу&lt;BR&gt;шаг за шагом и разберем новый код. Сначала мы создаем объект класса poll&lt;BR&gt;и инициализируем его используя статический метод Current ():&lt;BR&gt;private void Page__Load(object sender, System.EventArgs e)&lt;BR&gt;{ :;• •&lt;BR&gt;Poll aPoll = Poll.Current();&lt;BR&gt;Практический пример 1 — web-caum для проведения опросов 769&lt;BR&gt;Использование объекта Poll начинается в следующей строке; он используется&lt;BR&gt;для выполнения присваивания значения свойству Text управляющего элемента&lt;BR&gt;Label (QuestionLabel):&lt;BR&gt;QuestionLabel.Text = aPoll.Question;&lt;BR&gt;Несколько последующих строк предназначаются для организации цикла, кото-&lt;BR&gt;рый проходит по всем возможным ответам и выводит для каждого из них некото-&lt;BR&gt;рый HTML. Обратите внимание на то, что для задания числа повторений цикла&lt;BR&gt;for используется свойство Poii.AnswerCount. Мы также создаем строковую пере-&lt;BR&gt;менную, в которой будет храниться создаваемый нами HTML, и вставляем в нее&lt;BR&gt;два тега, ответственных за переход на новую строку:&lt;BR&gt;string HtmlLink = &quot;&lt;br /xbr /&amp;gt;*&apos;•;&lt;BR&gt;for(int i=l;i&lt;=aPoll.AnswerCount;i&lt;BR&gt;Для каждого из ответов требуется вывести текстовую ссылку с текстом &quot;Vote&quot;&lt;BR&gt;(&quot;Голосую за&quot;), а также текст самого ответа. Нужно внимательно следить за тем,&lt;BR&gt;чтобы ссылка действительно указывала на vote.aspx, а в значение URL включа-&lt;BR&gt;лось число, которое соответствует номеру выбранного ответа (например, при вы-&lt;BR&gt;боре ответа &quot;С#&quot; — это 1). HTML-код будет выглядеть следующим образом:&lt;BR&gt;&lt;а href=&quot;vote.aspx?id=l&quot;&amp;gt;Vote&lt;/a&amp;gt;&amp;amp;nbsp;C#&lt;br /&amp;gt;&lt;BR&gt;Обратите также внимание на использование в конце строки тега &lt;br /&amp;gt;, кото-&lt;BR&gt;рый отвечает за то, чтобы каждый ответ на экране располагался на отдельной&lt;BR&gt;строке. Для того чтобы более аккуратно отформатировать вывод, можно бы вос-&lt;BR&gt;пользоваться таблицей, но пока мы не будем ничего усложнять.&lt;BR&gt;Запись *&amp;amp;nbsp; * расшифровывается как non-breaking space (неудаляемый про-&lt;BR&gt;бел). Она заставляет браузер вставить пробел между текстом &quot;Vote&quot; и текстом&lt;BR&gt;самого ответа (например, С#), т. е. эти две записи при выводе будут разделены&lt;BR&gt;строго одним пробелом. Для создания соответствующего HTML-кода нужно исполь-&lt;BR&gt;зовать некоторую строку (с именем HtmlLink), а также переменную i и свойство&lt;BR&gt;с массивом Answers объекта Poll, для того чтобы вставить значение id и текст&lt;BR&gt;ответа. Код разбивается на две строки, поэтому он умещается на экране (обычно,&lt;BR&gt;если создаваемая текстовая строка занимает несколько строк на экране, следует&lt;BR&gt;воспользоваться классом StringBuilder):&lt;BR&gt;HtmlLink += *&lt;а href=&amp;#92;*vote.aspx?id=h +i +l! &amp;#92; &quot;&amp;gt;Vote&lt;/a&amp;gt;&quot; ;&lt;BR&gt;HtmlLink += &quot;&amp;amp;nbsp;&quot; + aPollAnswers [i] + *&lt;br /&amp;gt;&quot;-,&lt;BR&gt;Теперь есть строковая переменная — HtmlLink, которая содержит HTML-код&lt;BR&gt;для одного из ответов. Далее следует перейти к очередной итерации цикла и доба-&lt;BR&gt;вить HTML-текст для следующего ответа, а потом присвоить текст второму управ-&lt;BR&gt;ляющему элементу Label с помощью HTML-кода:&lt;BR&gt;• } &apos;&lt;BR&gt;AnswerLabel.Text = HtmlLink; I&lt;BR&gt;}&lt;BR&gt;Если теперь загрузить default.aspx в браузер, то можно увидеть созданный&lt;BR&gt;нами опрос, с выведенным в самом верху вопросом, под которым располагается&lt;BR&gt;перечень ответов (но не забудьте, что ссылки Vote пока не работают).&lt;BR&gt;Теперь нужно перейти к странице vote.aspx. Для ее создания VS следует вос-&lt;BR&gt;пользоваться пунктом Add Web Form меню Project в Visual Studio.NET. Убедившись,&lt;BR&gt;770 Практический пример&lt;BR&gt;Web Service Class&lt;BR&gt;Component Ddta Form Data Set&lt;BR&gt;Class Wizard&lt;BR&gt;Web User HTML Page Ftemeset&lt;BR&gt;&amp;pound;«•«#»&lt;BR&gt;Open Help&lt;BR&gt;что в окне диалога выбран пункт Web&lt;BR&gt;Form, введем vote.aspx в поле Name&lt;BR&gt;(см. рис. слева).&lt;BR&gt;Visual Studio.NET сгенерирует оба&lt;BR&gt;файла—vote.aspx И vote.aspx.cs&lt;BR&gt;(файл с кодом поддержки), а также&lt;BR&gt;откроет файл vote.aspx для редакти-&lt;BR&gt;рования. Файл vote.aspx практически&lt;BR&gt;идентичен default.aspx; он представ-&lt;BR&gt;ляет собой чистую страницу, содер-&lt;BR&gt;жащую управляющий элемент Label,&lt;BR&gt;в который будет помещен текст,&lt;BR&gt;представляющий данную страницу.&lt;BR&gt;Обратите внимание на то, что теги&lt;BR&gt;форм серверной стороны были удале-&lt;BR&gt;ны вручную за ненадобностью:&lt;BR&gt;&lt;%@ Page language&quot;&quot;c#&quot; Codebehind=&quot;vote.aspx.cs&quot; AutoEventWireup=&quot;false&quot;&lt;BR&gt;Inherits=PollW.vote&quot; %&amp;gt;&lt;BR&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0 Transitional//EN» &amp;gt;&lt;BR&gt;&lt;HTML&amp;gt;&lt;BR&gt;&lt;HEAD&amp;gt;&lt;BR&gt;&lt;meta name =иGENERATOR&quot; Content^&quot;Microsoft Visual Studio 7.0&quot;&amp;gt;&lt;BR&gt;&lt;meta name = &quot;CODELJJANGUAGE&quot; Content=&quot;C#!l&amp;gt;&lt;BR&gt;&lt;meta name = &quot;vs__defaultClientScript&quot; content=&quot;JavaScript (ECMAScript)&quot;&amp;gt;&lt;BR&gt;&lt;meta name =&quot;vs_targetSchema11&lt;BR&gt;content=&quot;http://schemas.microsoft.com/intellisense/ie5- •&amp;gt;•&lt;BR&gt;&lt;/KSAD&amp;gt; • • &apos;:: ••• : &apos;&lt;BR&gt;&lt;BODY&amp;gt;&lt;BR&gt;&lt;asp:Label id=lltitleLabelH runat=&quot;server&quot;&amp;gt;&lt;/asp:Label&amp;gt;&lt;BR&gt;&lt;br /&amp;gt;&lt;BR&gt;&lt;br /&amp;gt;&lt;BR&gt;&lt;asp: Panel id=Hresul.tsPaneln runat=&quot; server &quot;&amp;gt;&lt;/asp:Panel&amp;gt;&lt;BR&gt;&lt;/BODY&amp;gt;&lt;BR&gt;&lt;/HTML&amp;gt;&lt;BR&gt;Точно так же, как и для default.aspx, необходимо добавить для управляющих&lt;BR&gt;элементов следующие объявления:&lt;BR&gt;public class vote : Systern.Web,UI.Page&lt;BR&gt;{ &apos;&apos;&lt;BR&gt;protected System,Web.Ul.WebControls.Label titleLabel;&lt;BR&gt;protected System.Web.UI.WebControls.Panel resultsPanel;&lt;BR&gt;Теперь следует приступить к рассмотрению метода Page_Load(). Он должен&lt;BR&gt;вставить название страницы, которая будет выполнять повторный просмотр вопро-&lt;BR&gt;са текущего опроса, а затем выводить все ответы с указанием числа голосов, кото-&lt;BR&gt;рые удалось собрать каждому из них. Сначала мы создаем экземпляр объекта Poll&lt;BR&gt;посредством метода Current о , в результате чего получается объект, в котором со-&lt;BR&gt;держатся данные, касающиеся активного в настоящий момент опроса, взятые из&lt;BR&gt;XML-файла:&lt;BR&gt;private void Page__Load (object sender, System. E vent Args e)&lt;BR&gt;Poll aPoll = Poll.Current(};&lt;BR&gt;Практический пример 1 — web-сайт для проведения опросов 771&lt;BR&gt;В следующей строке мы используем объект Request класса Page (от которого&lt;BR&gt;наследуется данная страница) и с помощью семейства Querystring получаем до-&lt;BR&gt;ступ к параметрам, хранящимся в 4URL в строке запроса:&lt;BR&gt;string parameter = Request.QueryString[&quot;id&quot;];&lt;BR&gt;Далее нужно произвести проверку того, не равно ли значение id нулю. Если&lt;BR&gt;это значение не нуль, то следует делать попытку зарегистрировать поданный голос;&lt;BR&gt;после чего в любом случае перейти к выводу на экран текущих результатов опро-&lt;BR&gt;са. Обратите внимание на то, как мы опять используем метод Parse о класса int&lt;BR&gt;для преобразования строки в целое значение. Этот метод завершится неудачей,&lt;BR&gt;если ему будет передана строка, которая не может быть преобразована в целое&lt;BR&gt;значение, однако в данном случае уровень контроля за тем, что именно передается&lt;BR&gt;странице, очень высок, поэтому едва ли имеет смысл пытаться перехватывать та-&lt;BR&gt;кую ошибку:&lt;BR&gt;; if (parameter != null)&lt;BR&gt;{&lt;BR&gt;aPoll.Vote(int.Parse(parameter));&lt;BR&gt;} &apos; •&lt;BR&gt;В следующей строке программы осуществляется присваивание свойства Text&lt;BR&gt;управляющему элементу Label для осуществления перехода к странице, где содер-&lt;BR&gt;жится вводный текст данной страницы, в котором вопрос задается повторно. Об-&lt;BR&gt;ратите внимание на то, как в строке используются обратные слэши (*V)&amp;gt; чтобы&lt;BR&gt;включить в состав текста символы &quot;кавычки&quot; &quot;&quot;:&lt;BR&gt;titleLabel.Text = &quot;Votes for &amp;#92;&quot;n + aPoll.Question + &quot;&amp;#92;n&quot;;&lt;BR&gt;Оставшаяся в методе Page_Load() часть кода предназначается для вывода на&lt;BR&gt;экран результатов опроса, при этом каждый из вариантов ответа выводится на&lt;BR&gt;своем обычном месте, а рядом с ним выводится число голосов, которое он собрал.&lt;BR&gt;Сначала в нем создается экземпляр объекта Table (который представляет собой&lt;BR&gt;HTML-таблицу с результатами голосования), затем используется цикл for, в кото-&lt;BR&gt;ром просматриваются все ответы, а в качестве ограничителя используется значе-&lt;BR&gt;ние свойства AnswerCount:&lt;BR&gt;Table myTable = new Table О ;&lt;BR&gt;for(int i=l;i&lt;=aPoll.AnswerCount;i++)&lt;BR&gt;{ •-:•:.- • •&lt;BR&gt;После этого следует свести воедино HTML-таблицу (с помощью myTable) и ин-&lt;BR&gt;формацию, хранящуюся в объекта aPoll. Мы создаем новую строку и добавляем&lt;BR&gt;ее в таблицу:&lt;BR&gt;TableRow myTableRow = new TableRowO ;&lt;BR&gt;myTable«Controls.Add(myRow);&lt;BR&gt;Затем нужно создать новую ячейку таблицы, в которой свойство Text будет со-&lt;BR&gt;держать результат опроса, и добавить эту ячейку в таблицу:&lt;BR&gt;TableCell iayAnswer-Cell - new TableCell()?&lt;BR&gt;myAnswerCell.Text = aPoll.Answers[i]; ,:&lt;BR&gt;V myRow.Controls.Add(myAnswerCell);&lt;BR&gt;После следует осуществить те же действия для счетчика голосов, для чего со-&lt;BR&gt;здать новую ячейку таблицы, присвоить ее свойству Text значение счетчика голо-&lt;BR&gt;сов (присоединяя в конец строки текст -votes*), и добавляя эту ячейку в строку&lt;BR&gt;таблицы:&lt;BR&gt;772 Практический пример&lt;BR&gt;TableCell myVotesCell = new TableCelK) ;&lt;BR&gt;myVotesCell.Text = aPoll.Votes [i] .ToStringO + H votes&quot;&lt;BR&gt;myRow.Controls.Add(myVotesCell);&lt;BR&gt;Голосование по вопросу &quot;Какой язык программирования&lt;BR&gt;вы, в основном, используете?&apos;*&lt;BR&gt;С# 15 голосов&lt;BR&gt;О+ 2 голоса&lt;BR&gt;Java 35 голосов&lt;BR&gt;JavaScript 12 голосов&lt;BR&gt;Visual Basic 42 полоса&lt;BR&gt;После завершения цикла таблица добавля-&lt;BR&gt;ется в семейство управляющих элементов, хра-&lt;BR&gt;нящихся в серверном управляющем элементе&lt;BR&gt;resuitsPanei, следующим образом:&lt;BR&gt;resultsPanel.Controls.Add(myTable);&lt;BR&gt;В результат этой операции проиллюстриро-&lt;BR&gt;ван на рисунке слева.&lt;BR&gt;Оценка версии 1&lt;BR&gt;На настоящий момент мы являемся обладателями небольшого трехзвенного&lt;BR&gt;приложения, которое собирает ответы, полученные при проведении опроса, при&lt;BR&gt;этом мьГимеем возможность обращаться к бизнес-объекту как из приложения&lt;BR&gt;ASP.NET, так и из консольного приложения. Наше приложение реализовано толь-&lt;BR&gt;ко в самых общих чертах, и поэтому представляется важным понимать присущие&lt;BR&gt;ему ограничения:&lt;BR&gt;• Многократное голосование. Это, вероятно, является одним из самых&lt;BR&gt;существенных недостатков; каждый может зайти на сайт и многократно&lt;BR&gt;голосовать, отвечая на один и тот же вопрос опроса. Если результаты&lt;BR&gt;опроса являются значимыми для какой-либо третьей стороны, то вряд ли&lt;BR&gt;ее представители смогут устоять перед искушением добавить пару-тройку&lt;BR&gt;лишних голосов к тому или иному ответу.&lt;BR&gt;• Возможность повторного использования. Хотя разработанная программа&lt;BR&gt;является самодостаточной, и при попытке ее повторного использования&lt;BR&gt;не должно возникать никаких трудностей, ее интерфейс оказывается&lt;BR&gt;распределенным между двумя файлами — с расширениями .aspx и ,cs&lt;BR&gt;(файл с кодом поддержки). Каждый раз, когда возникает необходимость&lt;BR&gt;включить новый опрос, приходится объединять эти два файла&lt;BR&gt;с .aspx-файлом и .cs-файлом страницы, на которой предполагается&lt;BR&gt;проведение этого опроса. Было бы желательно иметь более простой&lt;BR&gt;способ включения опроса в страницу, и в ASP.NET такая возможность&lt;BR&gt;предусмотрена.&lt;BR&gt;• Редактирование опроса. Несмотря на то, что XML-файл обладает весьма&lt;BR&gt;простой структурой, всегда существует определенная вероятность того,&lt;BR&gt;что в какой-то момент человек, занимающийся его редактированием,&lt;BR&gt;забудет какой-либо жизненно важный символ, и в выводе web-сайта&lt;BR&gt;начнут появляться ошибки. Справиться с такой ситуацией можно&lt;BR&gt;несколькими способами. Можно изящно обойти такую проблему и вывести&lt;BR&gt;сообщение типа &quot;Извините, данный опрос в настоящий момент недоступен&quot;.&lt;BR&gt;Но более правильным решением будет предоставление менеджеру&lt;BR&gt;сайта интерфейса, с помощью которого он сможет выполнять&lt;BR&gt;редактирование опроса. Такой интерфейс мог бы быть реализован&lt;BR&gt;Практический пример 1 — web-caum для проведения опросов 773&lt;BR&gt;с помощью целого ряда технологий, однако наиболее подходящими&lt;BR&gt;представляются либо ASP.NET (web-интерфейс, предназначенный&lt;BR&gt;для редактирования опроса), либо интерфейс Windows Forms.&lt;BR&gt;• Слежение за ходом опроса. В том виде приложения, в котором оно&lt;BR&gt;существует на данный момент, не предусмотрено никакого простого&lt;BR&gt;способа, с помощью которого менеджер сайта мог бы ознакомиться&lt;BR&gt;с текущим состоянием опроса. Если собираемые данные представляют&lt;BR&gt;определенную важность, то было бы полезно иметь возможность&lt;BR&gt;наблюдать за распределением голосов в режиме реального времени.&lt;BR&gt;Для решения этой проблемы целесообразно создать дополнительный&lt;BR&gt;управляющий интерфейс. Такой интерфейс можно построить&lt;BR&gt;с использованием ASP.NET или — в качестве варианта — расширить&lt;BR&gt;уровень представления и создать интерфейс Windows Forms.&lt;BR&gt;• Управление данными. Поскольку все данные хранятся в XML-файле,&lt;BR&gt;необходимо иметь возможность контролировать состояние этого файла.&lt;BR&gt;Поэтому при дублировании web-сервера XML-файл также должен&lt;BR&gt;дублироваться. Хотя выполнить это совсем несложно, дублирование&lt;BR&gt;требует дополнительных административных усилий, направленных&lt;BR&gt;на сопровождение web-сайта, особенно если часть данных хранится&lt;BR&gt;в других местах (например, в БД или в каких-либо других файлах).&lt;BR&gt;Серьезные проблемы возникают также, если когда-либо в будущем&lt;BR&gt;встанет задача расширить web-сайт, с тем чтобы он мог выполняться&lt;BR&gt;более, чем на одном сервере; в этом случае можно было бы хранить&lt;BR&gt;файл с данными на одном сервере, к которому имеют доступ оба&lt;BR&gt;web-сервера, однако это простая проблема быстро становится сложнее,&lt;BR&gt;чем в идеальном случае. Поэтому, если принимать во внимание&lt;BR&gt;все проблемы, связанные с сопровождением, может оказаться&lt;BR&gt;целесообразным сложить все яйца в одну корзину и воспользоваться&lt;BR&gt;централизованным хранением всех данных в одной базе данных,&lt;BR&gt;вместо того чтобы хранить их в XML-файле.&lt;BR&gt;• Повторяющийся код. В методе Current () есть участок кода, отвечающий&lt;BR&gt;за загрузку XML-файла в объект DataSet; это код затем дублируется&lt;BR&gt;в методе vote (). В реальной программе такой участок кода должен быть&lt;BR&gt;оформлен в виде отдельного частного метода, которым смогут пользоваться&lt;BR&gt;И метод Current (), И метод Vote () ДЛЯ получения объекта DataSet&lt;BR&gt;из XML-файла. Избегайте повторяющихся участков кода любой ценой —&lt;BR&gt;и ваша жизнь как программиста станет существенно проще.&lt;BR&gt;• Множественные опросы. Данная модель предназначена для проведения&lt;BR&gt;только одного опроса. В реальной ситуации можно предположить, что&lt;BR&gt;каждый из опросов со временем будет заменяться на некоторый новый,&lt;BR&gt;т. е. менеджеру сайта потребуется редактировать XML-файл для замены&lt;BR&gt;опроса. При необходимости может быть поставлена задача сохранения&lt;BR&gt;копии предыдущего опроса в архиве опросов. Объем ручного труда,&lt;BR&gt;который потребуется для решения всех этих задач, оказывается&lt;BR&gt;достаточно большим, и в реальной жизни потребуется усовершенствовать&lt;BR&gt;модель, чтобы все опросы автоматически заносились в архив&lt;BR&gt;в используемом хранилище данных, а у менеджера web-сайта имелся&lt;BR&gt;в распоряжении интерфейс, позволяющий ему добавлять новые опросы.&lt;BR&gt;При наличии нескольких опросов возникает также необходимость&lt;BR&gt;устанавливать, какой из них является в настоящий момент активным.&lt;BR&gt;774 Практический пример&lt;BR&gt;• Одновременное обращение. Для хранения данных опроса используется&lt;BR&gt;единственный XML-файл, и в этом случае возникает возможность того,&lt;BR&gt;что определенная часть голосов не будет зарегистрирована, поскольку&lt;BR&gt;некоторые попытки осуществить доступ к файлу могут производиться&lt;BR&gt;в момент регистрации другого голоса. Маловероятно, что такая проблема&lt;BR&gt;возникнет для сайта с низкой интенсивностью посещений, но, если&lt;BR&gt;придется регистрировать большое количество голосов, может потребоваться&lt;BR&gt;внести соответствующие изменения, которые позволят справляться&lt;BR&gt;&apos; с высокой интенсивностью голосования. Наиболее логичным способом&lt;BR&gt;решения этой проблемы является переход на использование сервера БД,&lt;BR&gt;например SQL Server или Oracle, устойчивых к одновременным&lt;BR&gt;обращениям такого рода.&lt;BR&gt;• Внешний вид. Для обеих страниц опроса — default.aspx&lt;BR&gt;и vote.aspx — не разработано никакого внешнего представления.&lt;BR&gt;Для любого web-сайта необходимо прорабатывать внешний вид.&lt;BR&gt;В данном примере первостепенное внимание уделяется процессу&lt;BR&gt;разработки и используемым для этого технологиям, поэтому придание&lt;BR&gt;web-сайту надлежащего внешнего вида мы оставляем полностью&lt;BR&gt;на ваше усмотрение!&lt;BR&gt;• Обработка ошибок. В существующем на настоящий момент виде данное&lt;BR&gt;приложение обладает определенными функциональными возможностями,&lt;BR&gt;однако в нем предусмотрены только самые основные возможности&lt;BR&gt;обработки ошибок. Проблема заключается в том, что если происходит&lt;BR&gt;что-либо непредвиденное, то приложение генерирует сообщения&lt;BR&gt;об ошибках, которые совершенно не следует выводить пользователям.&lt;BR&gt;Например, если XML-файл оказывается недоступен, то возникает&lt;BR&gt;исключительная ситуация. Прежде чем приложение может быть&lt;BR&gt;передано для коммерческого использования, оно должно быть расширено,&lt;BR&gt;чтобы защищать себя и пользователей от возможных проблем.&lt;BR&gt;Теперь, когда у нас имеется представление о некоторых из тех областей, в ко-&lt;BR&gt;торых мы можем усовершенствовать и улучшить приложение для проведения&lt;BR&gt;опросов, давайте приступим к созданию второй версии, в которую будут включены&lt;BR&gt;некоторые дополнительные функциональные возможности и преодолены два из&lt;BR&gt;перечисленных выше ограничений. Мы рассмотрим только две проблемы из пере-&lt;BR&gt;. численных, однако и об остальных проблемах не следует забывать, если вы когда-&lt;BR&gt;либо соберетесь создавать аналогичную систему проведения опросов.&lt;BR&gt;Версия 2&lt;BR&gt;Программы не создаются, они вырастают. По мере того как ведется работа&lt;BR&gt;с некоторой версией какого-либо ПО, постоянно возникают планы по расширению&lt;BR&gt;и изменению этого программного обеспечения. Существует целый ряд усовершен-&lt;BR&gt;ствований, которые могут быть внесены в наше приложение. Во второй версии мы&lt;BR&gt;собираемся решить проблему двух ограничений и продолжить совершенствование&lt;BR&gt;уже созданного кода, уделяя пристальное внимание тому, куда вносятся изменения,&lt;BR&gt;в частности, касается ли это уровня представления, уровня бизнес-логики или&lt;BR&gt;уровня данных.&lt;BR&gt;Практический пример 1 - юеЪ-сайт для проведения опросов&lt;BR&gt;Дополнительные требования&lt;BR&gt;Ниже представлены требования ко второй версии web-сайта для проведения&lt;BR&gt;опросов, которыми мы будем руководствоваться:&lt;BR&gt;• Инструмент для просмотра результатов опроса. Менеджеру сайта&lt;BR&gt;необходима некоторая утилита, которую он мог бы запускать на своей&lt;BR&gt;рабочей машине и которая позволяла бы непрерывно выводить текущее&lt;BR&gt;состояние счетчиков голосов. Это приложение должно быть приложением&lt;BR&gt;Windows и устанавливать соединение с web-сайтом посредством TCP/IP.&lt;BR&gt;Этот инструмент должен выводить вопрос, все ответы, счетчик голосов&lt;BR&gt;для каждого из ответов и его долю в процентном отношении, а также&lt;BR&gt;суммарное количество голосов.&lt;BR&gt;• Один человек — один голос. Посетители сайта должны иметь&lt;BR&gt;возможность проголосовать только один раз по каждому опросу.&lt;BR&gt;• Управляющий элемент для проведения опросов. Должна быть&lt;BR&gt;предусмотрена возможность несложного добавления опроса на любую&lt;BR&gt;страницу ASP.NET просто за счет обеспечения доступа к бизнес-объекту&lt;BR&gt;и добавления в .aspx-файл нескольких простых операторов.&lt;BR&gt;Инструнент для просмотра результатов опроса&lt;BR&gt;Интерфейс&lt;BR&gt;Из трех новых требований к приложению для начала выбираем самое большое.&lt;BR&gt;Оно предполагает создание настольного приложения Windows, построенного с ис-&lt;BR&gt;пользованием Windows Forms. К нему не предъявляется никаких особых требова-&lt;BR&gt;ний в смысле вывода информации об опросе, хотя представляется разумным&lt;BR&gt;предположить, что это будет происходить в рамках одной формы.&lt;BR&gt;Модель, которой мы собираемся воспользоваться, состоит из нескольких над-&lt;BR&gt;писей, располагающихся вверху, в которых содержится вопрос и суммарное коли-&lt;BR&gt;чество проголосовавших. Под указанными надписями располагается группа строк,&lt;BR&gt;в каждой из которых содержится текст ответа и количество набранных голосов&lt;BR&gt;(вместе с процентным отношением),&lt;BR&gt;а также линейка, представляющая&lt;BR&gt;счетчик количества голосов в графиче-&lt;BR&gt;ском режиме (см. рис. слева).&lt;BR&gt;Все очень просто, за исключением&lt;BR&gt;одной маленькой загвоздки, которая&lt;BR&gt;заключается в том, что на момент раз-&lt;BR&gt;работки формы нам не известно общее&lt;BR&gt;Doyouthmk&amp;amp;iciosoffc.NET will succeedhtheт&amp;amp;Ы?&lt;BR&gt;Y e s 1040 (52^j&lt;BR&gt;No 398 (2G^j 1&lt;BR&gt;Not sure • E i i i i&lt;BR&gt;Poll Results Too!&lt;BR&gt;бы воспользоваться окном со списком&lt;BR&gt;либо каким-либо другим управляющим&lt;BR&gt;элементом, который в состоянии дина-&lt;BR&gt;мически изменять свои размеры, однако&lt;BR&gt;для того чтобы наш инструмент выгля-&lt;BR&gt;дел красиво, а также для того, чтобы&lt;BR&gt;продемонстрировать некоторые воз-&lt;BR&gt;можности Windows Forms, мы будем&lt;BR&gt;формировать каждую строку данных в&lt;BR&gt;динамическом режиме (см. рис. справа).&lt;BR&gt;количество голосующих. Можно было&lt;BR&gt;What development language do you primarily use&lt;BR&gt;Total vote*: 108&lt;BR&gt;JavaScnpt&lt;BR&gt;Visual Bbuz&lt;BR&gt;776 Практический пример&lt;BR&gt;&lt; &amp;amp;Ш&lt;BR&gt;Это означает, что если в опросе оказывается большее количество ответов, то&lt;BR&gt;будет выведено большее количество строк и для их вывода форма изменит свои&lt;BR&gt;размеры.&lt;BR&gt;Web-служба для проведения опроса&lt;BR&gt;Для реального сценария использования данного приложения представляется&lt;BR&gt;маловероятным, чтобы инструмент для просмотра результатов использовался на&lt;BR&gt;той же машине, на которой находится web-сайт. Напротив, с уверенностью можно&lt;BR&gt;утверждать, что он будет располагаться на другой машине, однако мы предполага-&lt;BR&gt;ем, что соединение между этими двумя машинами поддерживает TCP/IP. Для того&lt;BR&gt;чтобы объекты могли взаимодействовать по каналу TCP/IP с использованием&lt;BR&gt;HTTP (что обычно предполагает работу в Интернете, поскольку интранет-прило-&lt;BR&gt;жения обычно используют работу с удаленными объектами), следует воспользо-&lt;BR&gt;ваться web-службами. Web-службы — это способ производить удаленные вызовы&lt;BR&gt;по различным сетям, включая Интернет, а также использовать SOAP- и XML-&lt;BR&gt;стандарты для управления соединением. При использовании .NET, в особенности&lt;BR&gt;Visual Studio.NET, реализовать web-службу не составляет никакого труда. При&lt;BR&gt;этом многое из происходящего будет скрыто от наших глаз, но само построение&lt;BR&gt;web-службы оказывается относительно простым.&lt;BR&gt;Первое, что мы собираемся сделать,— это создать web-службу для проведения&lt;BR&gt;опросов; она будет создана в приложении ASP.NET PollW, поскольку обращения&lt;BR&gt;к этой web-службе будут происходить из страниц нашего web-сайта. В web-службе&lt;BR&gt;будут предусмотрены три web-метода, доступ к которым может осуществляться&lt;BR&gt;через Интернет:&lt;BR&gt;• Answers (). Возвращает массив строк, в котором содержится&lt;BR&gt;текст всех ответов.&lt;BR&gt;• votes (). Возвращает массив целых, в котором содержатся&lt;BR&gt;счетчики голосов для каждого из ответов.&lt;BR&gt;• QuestionO. Возвращает строку, содержащую вопрос текущего опроса.&lt;BR&gt;Теоретически можно сделать эти методы доступными через web, описав их&lt;BR&gt;в классе Poll, однако, чтобы не смешивать методы, доступ к которым осуществля-&lt;BR&gt;ется через Интернет, с нашим бизнес-объектом, мы создадим новый класс, где бу-&lt;BR&gt;дут находиться эти web-методы, которые, в свою очередь, используют методы,&lt;BR&gt;описанные в уже существующем классе Poll. В подходе, обеспечивающем полный&lt;BR&gt;контроль над интерфейсом web-служб, ко-&lt;BR&gt;торый не зависит от бизнес-логики класса&lt;BR&gt;более низкого уровня, имеются определен-&lt;BR&gt;ные преимущества.&lt;BR&gt;Все, что требуется для создания Web-&lt;BR&gt;службы в Visual Studio.NET,— это восполь-&lt;BR&gt;зоваться пунктом Add Web Service меню&lt;BR&gt;Project, позволяющим добавить web-службу&lt;BR&gt;в проект Poiiw (web-приложение). Далее&lt;BR&gt;следует ввести имя файла web-службы; это&lt;BR&gt;та страница, которая будет предоставлять&lt;BR&gt;наши методы. Web-службами используются&lt;BR&gt;файлы с расширением .asmx, хотя их струк-&lt;BR&gt;тура и содержание почти не отличаются от&lt;BR&gt;файлов с расширением .aspx (см. рис. слева).&lt;BR&gt;•&lt;*t&lt;BR&gt;&apos;HI&lt;BR&gt;Web Fern&lt;BR&gt;Class&lt;BR&gt;Практический пример 1 — web-сайт для проведения опросов 777&lt;BR&gt;После того создания файла с расширением .asmx можно обнаружить, что кро-&lt;BR&gt;ме него создан еще один файл results.asmx.cs с кодом поддержки. Именно&lt;BR&gt;в нем будет храниться код, реализующий web-методы. Если вы прокрутите файл&lt;BR&gt;results.asmx.cs вниз, то ближе к его концу вы обнаружите образец web-метода&lt;BR&gt;с комментариями:&lt;BR&gt;// ОБРАЗЕЦ WEB-СЛУЖБЫ&lt;BR&gt;// Образец службы HelloWorldO осуществляет возврат строки Hello World&lt;BR&gt;// Для создания web-службы уберите знаки комментария из следующих строк,&lt;BR&gt;// затем сохраните проект и постройте его&lt;BR&gt;//Для тестирования web-службы нажмите F5 :&lt;BR&gt;. ; - • , . . • &apos; : ;. / / .• ; •••:• . . &apos; • • •. ••• . • . • • &apos;• . . - : • • • • • • : • . ; &apos; . ;. &apos; &apos; . &apos;&lt;BR&gt;// [Webmethod]&lt;BR&gt;// public string HelloWorldO&lt;BR&gt;// {&lt;BR&gt;// return &quot;Hello World&quot;;&lt;BR&gt;// }&lt;BR&gt;Из приведенного выше примера видно, что все, что требуется для создания&lt;BR&gt;web-метода,— это включить атрибут &quot;[webmethod]&quot; непосредственно перед описа-&lt;BR&gt;нием самого метода. Далее приводится код web-метода Question*):&lt;BR&gt;[Webmethod {Description^11 Return the poll question&quot;)]&lt;BR&gt;/ описание: возвращает вопрос опроса /&lt;BR&gt;public string Question{)&lt;BR&gt;{&lt;BR&gt;Poll aPoll = Poll.Current () ;&lt;BR&gt;return aPoll.Question;&lt;BR&gt;}&lt;BR&gt;Обратите внимание на то, что атрибуту [webmethod] передается некоторый па-&lt;BR&gt;раметр, в котором содержится краткое описание web-метода. В теле самого метода&lt;BR&gt;используется класс Poll точно таким же образом, каким он использовался в на-&lt;BR&gt;шем консольном приложении и в web-приложении. Он создает экземпляр объекта&lt;BR&gt;Класса Poll С ПОМОЩЬЮ метода Current () И возвращает Значение СВОЙСТВа Question.&lt;BR&gt;Весь код, необходимый для реализации возможности обращения к этому методу&lt;BR&gt;через Интернет, скрыт от нас.&lt;BR&gt;Web-методы для счетчиков голосов и для ответов абсолютно аналогичны:&lt;BR&gt;[Webmethod&lt;Description=JIReturn the results for the poll&quot;)]&lt;BR&gt;. , .. . / описание: возвращает результаты проведения опроса /&lt;BR&gt;public int[] VotesO&lt;BR&gt;{ •&lt;BR&gt;Poll aPoll = Poll.Current();&lt;BR&gt;return aPoll.Votes;&lt;BR&gt;• : : [ y [ : - У : ; У : ; : &apos; • Г У &apos; : . , : . - • - &apos; : • ; . ; &apos; . ; / • . • Y • &apos; ; . • . • : : • • • • : • . • • . • . • • • , ; , • • • . . . • • • ; : • : • . . • , , . • . • . . • . • • . • . • • ; • • • • . • . : . ; • . . : • ; • • . . у Ш &amp;#92;;.-. • .. • . : - , • • • . . , ; . . . • . ; . . &apos; • . • • • •&lt;BR&gt;[Webmethod(Description^1 Return the answers in the poll&quot;) ]&lt;BR&gt;• / описание: возвращает возможные ответы опроса /&lt;BR&gt;public string[] Answers() :&lt;BR&gt;v Poll aPoll = Poll.Current();&lt;BR&gt;return aPoll.Answers;&lt;BR&gt;&amp;gt; . Ш Н Ш 1 ш ш Ш • : • I • &apos; W-&lt;BR&gt;Для каждого из методов мы включили краткое описание; все эти методы исполь-&lt;BR&gt;зуют класс Poll для предоставления требуемых данных. Именно в этом заключает-&lt;BR&gt;ся все изящество централизованных бизнес-объектов; создав объекты, обладающие&lt;BR&gt;основными функциональными возможностями, мы затем можем легко использо-&lt;BR&gt;вать их в различных местах.&lt;BR&gt;778 Практический пример&lt;BR&gt;&apos; - ... &apos; . . . . . Г . : .4 :&lt;BR&gt;- - • •&lt;BR&gt;m p » ( H t » &lt; &amp;gt; . f m « f o&lt;BR&gt;T h i s w e f e s e r v i c e H M s i o Q W t p : / / t e t « m w H . o f 4 3 / a s I t s d e f a u l t n&lt;BR&gt;Recommendation: Chinee the default памтрайв b«jfftrt* the e b s e r v i c e I s m a d e p u b l i c .&lt;BR&gt;Остальная часть страницы содержит&lt;BR&gt;рекомендации, каким образом следует&lt;BR&gt;сконфигурировать web-службу, перед&lt;BR&gt;тем, как передать ее для коммерческого&lt;BR&gt;использования. Если выбрать web-метод&lt;BR&gt;Question, то можно увидеть страницу&lt;BR&gt;(см. рис. справа) с информацией о вы-&lt;BR&gt;бранном web-методе и о том, как его&lt;BR&gt;следует использовать.&lt;BR&gt;На странице web-метода Question&lt;BR&gt;расположена кнопка с текстом invoke&lt;BR&gt;(вызов), которая может быть использо-&lt;BR&gt;вана для тестирования web-службы.&lt;BR&gt;Если щелкнуть на кнопке, то можно бу-&lt;BR&gt;дет увидеть выходной поток web-метода&lt;BR&gt;QuestionO, представленный на рисунке&lt;BR&gt;в виде SOAP/XML:&lt;BR&gt;ЕСЛИ теперь Открыть файл results.asmx&lt;BR&gt;в браузере через HTTP, то можно увидеть&lt;BR&gt;то, что изображено на рисунке слева. Обра-&lt;BR&gt;тите внимание на то, что при перечислении&lt;BR&gt;всех методов указывается не только его&lt;BR&gt;имя, но и краткое описание. Эта информа-&lt;BR&gt;ция существенно облегчает понимание того,&lt;BR&gt;какие действия выполняет каждый из web-&lt;BR&gt;методов.&lt;BR&gt;Эта страница в удобном для чтения виде&lt;BR&gt;автоматически генерируется системой .NET&lt;BR&gt;и позволяет проверить работу web-службы.&lt;BR&gt;На ней отображаются все три web-метода.&lt;BR&gt;**8*Л ^ ^ . ,0 2} $ Q-PCM^S* 4**en _IjF.v.^«&lt;BR&gt;Results&lt;BR&gt;Click fcecE fo^1» complete l«t of о^еслйол*.&lt;BR&gt;! Question&lt;BR&gt;Reiwm the poll question&lt;BR&gt;Test&lt;BR&gt;To lest, dick the &apos;InvakQ&apos; button.&lt;BR&gt;SOAP&lt;BR&gt;With actual values.&lt;BR&gt;POST / S № l l v / c e : s u i r , 3 . i i : ; } - 7w H T T P / l . i&lt;BR&gt;H o s t : l c c c » i h O 3 t &apos; .. • ,. &apos; &apos; . . . • :&lt;BR&gt;C6»tr?riv- &apos;Гу|:.:_: ic.y.r,/y.i.«l; tnftS»et&quot;4CJ-0&lt;BR&gt;OrL-ri. -I.-/rr.j&quot;;ht Icnrjth&lt;BR&gt;older* *KUV&lt;BR&gt;. в&lt;BR&gt;i&lt;BR&gt;•f-iSS&apos;loci^rW* ^&lt;BR&gt;3 й lwlies -.ii&lt;BR&gt;&lt;?xml version=M1.0* encoding=3 lutf-81 3 ?&gt;&lt;BR&gt;&lt;string K m l n s ^ S ! h t t p : / / t e i n p u n &amp;#92; o r g / l&apos;&amp;gt;What d e v e l o p m e n t l a n g u a g e do y o u p r i m a r i l y use?&lt;/stnng&amp;gt;&lt;BR&gt;;:Г&lt;BR&gt;Заметьте, насколько проста строка URL, позволяющая обратиться к этому ме-&lt;BR&gt;тоду, а также на то, что результат работы метода — вопрос нашего опроса — воз-&lt;BR&gt;вращается в виде простого XML-документа.&lt;BR&gt;В выходном потоке web-метода votes о мы увидим нечто похожее (см. рис. на&lt;BR&gt;стр. 779, верхний), но здесь стоит обратить внимание на то, как просто .NET&lt;BR&gt;и web-служба работают с массивом целых значений. Объем работы, выполняемый&lt;BR&gt;.NET за кулисами, огромен, однако нам нет никакой необходимости знать о нем&lt;BR&gt;что-либо, что позволяет нам выполнять свою работу намного более эффективно.&lt;BR&gt;Практический пример 1 — web-сайт, для проведения опросов 779&lt;BR&gt;: : •&amp;gt; - . •&lt;BR&gt;51* &amp;amp;Й v;«w rgvctRes Tods :1*?? ; Address J&lt;BR&gt;id Й&lt;BR&gt;&lt;?xml version-&lt;BR&gt;- &lt;ArrayOftnt&lt;BR&gt;&lt; in t &gt; 0 &lt;/in t &gt;&lt;BR&gt;&lt;№t&gt;16&lt;/&amp;#92;nt&gt;&lt;BR&gt;encoding»*utf-8&quot; ?&gt;&lt;BR&gt;p://vvwvv-vv3&lt;BR&gt;.w3.org/2001/XMLSchema&quot; K&lt;BR&gt;&lt;int&amp;gt;34&lt;/int&amp;gt;&lt;BR&gt;&lt;int&amp;gt;12&lt;/int&amp;gt;&lt;BR&gt;&lt;int&amp;gt;44&lt;/int&amp;gt;&lt;BR&gt;&lt;/ArrayOflnt&amp;gt;&lt;BR&gt;] Done&lt;BR&gt;zl&lt;BR&gt;• J ;- л * is!&lt;BR&gt;Project T&lt;BR&gt;*LJl Visual C^&quot; Proj.-jc^-&lt;BR&gt;LJ Setup and Deptoyment Projects&lt;BR&gt;• ;.„_Л Other Projects&lt;BR&gt;Приложение Windows&lt;BR&gt;Создать web-методы и организовать доступ к ним посредством HTTP оказыва-&lt;BR&gt;ется очень легко, но возникает вопрос: каким образом web-методы могут быть ис-&lt;BR&gt;пользованы? Как можно преобразовать получаемый XML во что-либо полезное?&lt;BR&gt;Нам не придется этим заниматься, за нас это все также сделает система .NET.&lt;BR&gt;Мы обладаем функционирующей&lt;BR&gt;web-службой, у которой имеются&lt;BR&gt;web-методы, обеспечивающие до-&lt;BR&gt;ступ к данным опроса. Теперь пере-&lt;BR&gt;ключим&apos; внимание на приложение&lt;BR&gt;Windows Forms. Мы воспользуемся&lt;BR&gt;пунктом Add Project меню File, за-&lt;BR&gt;тем выберем Windows Application&lt;BR&gt;и введем имя PoiiD (сокращение от&lt;BR&gt;названия приложения Poll Desktop),&lt;BR&gt;как показано на рисунке справа.&lt;BR&gt;В результате Visual Studio.NET&lt;BR&gt;СОЗДаСТ ОДИН файл Forml.cs С ОПИ-&lt;BR&gt;санием класса и откроет форму в&lt;BR&gt;окне разработки, в котором можно&lt;BR&gt;непосредственно производить ре-&lt;BR&gt;дактирование. Хотя мы планируем&lt;BR&gt;ASP.MET Web ASP.NET Web Web Cootf&lt;&lt;BR&gt;Service library&lt;BR&gt;vah a V &apos;i&lt;BR&gt;zl&lt;BR&gt;ШжС^х&lt;BR&gt;I OK I Cancoi J Help&lt;BR&gt;J Total votes: •• DO&lt;BR&gt;L ;&lt;BR&gt;• о&lt;BR&gt;создавать большую часть управляющих&lt;BR&gt;элементов формы посредством исполь-&lt;BR&gt;зования кода, три расположенных в са-&lt;BR&gt;мом верху управляющих элемента можно&lt;BR&gt;включить, воспользовавшись окн</content:encoded>
			<link>https://krutoto.ucoz.ru/news/polzovatelskij_interfejs_uroven_predstavlenija/2010-02-11-406</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/polzovatelskij_interfejs_uroven_predstavlenija/2010-02-11-406</guid>
			<pubDate>Wed, 10 Feb 2010 21:58:07 GMT</pubDate>
		</item>
		<item>
			<title>Практический пример 1 - web-сайт для проведения опросов</title>
			<description>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Практический пример 1 -&lt;BR&gt;&lt;/SPAN&gt;web-сайт для проведения опросов&lt;BR&gt;На протяжении книги вы знакомились со всем спектром технологий .NET, ко-&lt;BR&gt;торые можно использовать, программируя на С#. В этом разделе мы собираемся&lt;BR&gt;отойти от теории и заняться в качестве практического упражнения приложением,&lt;BR&gt;в котором будут использоваться самые разнообразные технологии из имеющихся&lt;BR&gt;в .NET.&lt;BR&gt;Сначала мы создадим базовое приложение, а затем расширим его и создадим&lt;BR&gt;вторую версию, в которую будут включены дополнительные возможности. В реаль-&lt;BR&gt;ной жизни от любого приложения всегда требуется постоянно соответствовать из-&lt;BR&gt;меняющимся требованиям, и совершенно очевидно, что познакомиться с процессом&lt;BR&gt;изменения приложения в практическом примере такой книги, как эта, оказывается&lt;BR&gt;очень полезным. Использование двух различных версий также предоставит воз-&lt;BR&gt;можность узнать, каким образом .NET позволяет упростить процедуру расширения&lt;BR&gt;приложений, это означае...</description>
			<content:encoded>&lt;SPAN style=&quot;font-size: 12pt&quot;&gt;Практический пример 1 -&lt;BR&gt;&lt;/SPAN&gt;web-сайт для проведения опросов&lt;BR&gt;На протяжении книги вы знакомились со всем спектром технологий .NET, ко-&lt;BR&gt;торые можно использовать, программируя на С#. В этом разделе мы собираемся&lt;BR&gt;отойти от теории и заняться в качестве практического упражнения приложением,&lt;BR&gt;в котором будут использоваться самые разнообразные технологии из имеющихся&lt;BR&gt;в .NET.&lt;BR&gt;Сначала мы создадим базовое приложение, а затем расширим его и создадим&lt;BR&gt;вторую версию, в которую будут включены дополнительные возможности. В реаль-&lt;BR&gt;ной жизни от любого приложения всегда требуется постоянно соответствовать из-&lt;BR&gt;меняющимся требованиям, и совершенно очевидно, что познакомиться с процессом&lt;BR&gt;изменения приложения в практическом примере такой книги, как эта, оказывается&lt;BR&gt;очень полезным. Использование двух различных версий также предоставит воз-&lt;BR&gt;можность узнать, каким образом .NET позволяет упростить процедуру расширения&lt;BR&gt;приложений, это означает что можно акцентировать внимание на меньших частях&lt;BR&gt;приложения в процессе его разработки и создания.&lt;BR&gt;Приложение, в первую очередь, предназначается для работы с web-сайтом. Од-&lt;BR&gt;нако, как вы сможете увидеть по мере изучения этого примера, оно будет работать&lt;BR&gt;с любым типом интерфейсов. Важно помнить, что, хотя мы будем заниматься со-&lt;BR&gt;зданием приложения как функциональной возможности web-сайта, лежащая в его&lt;BR&gt;основе объектная модель будет работать не менее эффективно и для консольного&lt;BR&gt;приложения, и для desktop-приложения, и даже для web-службы. Мы также узнаем,&lt;BR&gt;каким образом трехзвенная модель приложения (в которой уровни данных, бизнес-&lt;BR&gt;логики и представления отделены друг от друга) позволяет упрощать процесс мо-&lt;BR&gt;дернизации программного обеспечения на всем протяжении его жизненного цикла.&lt;BR&gt;Web-сайт для проведения опросов&lt;BR&gt;Многие web-сайты предусматривают вывод на экран вопроса с возможными&lt;BR&gt;вариантами ответов. Посетителям web-сайтов таким образом дается подсказка для&lt;BR&gt;ответа в соответствии с их точкой зрения, после чего они получают возможность&lt;BR&gt;просмотреть общие результаты текущего опроса. Рассмотрим пример:&lt;BR&gt;Какой язык программирования вы, в основном, используете?&lt;BR&gt;С#&lt;BR&gt;с++&lt;BR&gt;. • &apos;• • • . &apos; J a v a &apos; • •&apos; . • . • . &apos; ...-..•• • • ••• . :• •• &apos;• .*.&apos;.&apos;&lt;BR&gt;J a v a S c r i p t •• •. • • . . ... • • . : • - : . : • • • • :•••••• :••••••:•••• :••:•••;: . А : . - . у , - • ; . , .,.:•••&lt;BR&gt;748 Практический пример&lt;BR&gt;Результат, который увидит посетитель, может быть представлен примерно сле-&lt;BR&gt;дующим образом:&lt;BR&gt;10% С#&lt;BR&gt;2% C++&lt;BR&gt;34% Java&lt;BR&gt;12% JavaScript&lt;BR&gt;42% Visual Basic&lt;BR&gt;Практическим примером, которому посвящен этот раздел, будет реализация&lt;BR&gt;системы проведения опросов, подобных приведенному выше, и после того, как мы&lt;BR&gt;создадим две версии системы, мы включим в них новые возможности. Основным&lt;BR&gt;будет интерфейс, использующий web и построенный с помощью ASP.NET. Мы&lt;BR&gt;также создадим уровни представления для консольного приложения, desktop-при-&lt;BR&gt;ложения Windows и web-службы.&lt;BR&gt;Версия 1&lt;BR&gt;В первой версии web-сайта для проведения опросов будет реализован простой&lt;BR&gt;вывод вопроса на web-страницу и сбор ответов. Прежде чем двигаться дальше,&lt;BR&gt;ясно и четко сформулируем требования к этому web-сайту.&lt;BR&gt;Требования&lt;BR&gt;Наш не очень интенсивно посещаемый web-сайт должен включать в себя&lt;BR&gt;опрос, который состоит из вопроса и нескольких возможных вариантов ответа&lt;BR&gt;(обычно не более десяти). При проведении опроса посетитель выбирает один из&lt;BR&gt;предложенных ответов. После того как&lt;BR&gt;посетитель проголосовал, он получает воз-&lt;BR&gt;можность увидеть число голосов, отданных&lt;BR&gt;за каждый из вариантов.&lt;BR&gt;Все детали, касающиеся вопроса, отве-&lt;BR&gt;тов и подсчета голосов, хранятся в XML-&lt;BR&gt;файле на web-сервере, поскольку бюджет&lt;BR&gt;на БД не выделен, а возможность должна&lt;BR&gt;быть реализована в срочном порядке. Ког-&lt;BR&gt;да администратору требуется внести какие-&lt;BR&gt;либо изменения в проведение опроса, он&lt;BR&gt;вручную редактирует XML-файл. Прило-&lt;BR&gt;жение должно выводить простой HTML&lt;BR&gt;так, чтобы он был корректно представлен&lt;BR&gt;в двух основных типах браузеров (Netscape&lt;BR&gt;и Internet Explorer).&lt;BR&gt;Разработка объектной подели (Business Logig Tier)&lt;BR&gt;Для данного примера будет использоваться трехзвенная модель — мы собира-&lt;BR&gt;емся провести четкую границу между всеми тремя уровнями приложения:&lt;BR&gt;• Уровень представления. Этот уровень представляет собой&lt;BR&gt;пользовательский интерфейс и для .NET может состоять&lt;BR&gt;из приложения ASP.NET (Интернет, интранет, цифровое телевидение,&lt;BR&gt;мобильный телефон, электронная записная книжка и т. д.),&lt;BR&gt;консольного приложения, приложения Windows Forms или web-службы.&lt;BR&gt;1 File М View F&amp;amp;vorites&lt;BR&gt;v^Back * =&amp;gt; • -Ц l&amp;pound;j f j j&lt;BR&gt;Address J4Q http;//lQCelhosfc/polto&lt;BR&gt;Tools Help&lt;BR&gt;&amp;#92; Ш Personal Bar ^J&lt;BR&gt;l Какой язык программирования вы, в основном»&lt;BR&gt;i Голосую за С#&lt;BR&gt;Голосую за О+&lt;BR&gt;Голосую за Java&lt;BR&gt;Голосую за JavaScript&lt;BR&gt;1 Голосую за Visual Basic&lt;BR&gt;i&lt;BR&gt;/Search&lt;BR&gt;~ 3 *&amp;gt;&lt;*&lt;BR&gt;используете?&lt;BR&gt;: Local intranet&lt;BR&gt;О&lt;BR&gt;1&lt;BR&gt;:| Links-&amp;gt;?|i&lt;BR&gt;-!&lt;BR&gt;Практический пример 1 — web-caum для проведения опросов 749&lt;BR&gt;В данном примере мы планируем рассмотреть создание уровня представления&lt;BR&gt;с использованием приложения ASP.NET, приложения Windows Forms,&lt;BR&gt;web-службы и консольного приложения с командной строки.&lt;BR&gt;Уровень бизнес-логики. Это сердцевина приложения. Именно здесь&lt;BR&gt;мы будем применять принципы объектно-ориентированной разработки&lt;BR&gt;в чистом виде, и именно здесь будет располагаться большая часть&lt;BR&gt;создаваемого кода.&lt;BR&gt;Уровень представления&lt;BR&gt;Windows Forms, ASP.NET,&lt;BR&gt;консольное приложение,&lt;BR&gt;web-службы и т. д.&lt;BR&gt;Уровень бизнес-логики&lt;BR&gt;Класс(ы)&lt;BR&gt;Уровень данных&lt;BR&gt;XML, SQL Server, Oracle,&lt;BR&gt;Microsoft Access, классы и т. д.&lt;BR&gt;• Уровень данных. Это уровень, на котором&lt;BR&gt;будут храниться данные, будь это XML-файл,&lt;BR&gt;обычный файл на диске либо БД SQL Server,&lt;BR&gt;Microsoft Access, MSDE или Oracle, либо&lt;BR&gt;какое-либо другое средство хранения данных.&lt;BR&gt;Во многих приложениях — кроме собственно&lt;BR&gt;среды хранения данных — на этом же уровне&lt;BR&gt;располагаются и классы, которые позволяют&lt;BR&gt;осуществлять доступ к данным (см. рис. справа).&lt;BR&gt;Необходимо помнить о том, что в .NET имеется&lt;BR&gt;целый спектр мощных и гибких инструментов, однако&lt;BR&gt;для создания высококачественного продукта прежде&lt;BR&gt;всего играют роль методы, которые используются при разработке приложений,&lt;BR&gt;а не инструменты сами по себе. Вполне возможно создать такой сайт для проведе-&lt;BR&gt;ния опросов, используя только .aspx-файлы, которые непосредственно привязаны&lt;BR&gt;к хранилищу данных. Однако в данном примере используется более структуриро-&lt;BR&gt;ванный подход, который приводит&quot; к созданию приложения, разбитого на три логи-&lt;BR&gt;ческие составные части; такое приложение гораздо проще совершенствовать&lt;BR&gt;и расширять. Время, затрачиваемое на создание программного обеспечения, на-&lt;BR&gt;много меньше времени на сопровождение этого программного обеспечения; имен-&lt;BR&gt;но поэтому структурированный подход представляет особую ценность.&lt;BR&gt;Для трехзвенной структуры приложения представляется благоразумным учи-&lt;BR&gt;тывать предъявляемые к нему требования с самого начала разработки объектной&lt;BR&gt;модели. Это означает сначала построение связной умозрительной модели того, из&lt;BR&gt;каких &quot;вещей&quot; должно состоять приложение, а затем создание на основании этой&lt;BR&gt;модели уровня бизнес-логики приложения. Именно на этом этапе создаются объ-&lt;BR&gt;екты, моделирующие отдельные составные части проблемы из той области знаний,&lt;BR&gt;в которой мы работаем, и мы строим эти объекты так, чтобы соответствовать тре-&lt;BR&gt;бованиям уровня представления и разумно использовать уровень данных. Зачастую&lt;BR&gt;возникают ситуации, когда по мере разработки объектов, находящихся в среднем&lt;BR&gt;звене, нам приходится принимать во внимание особенности физической среды&lt;BR&gt;выполнения (например, быстродействие), однако в данном конкретном случае мы&lt;BR&gt;разрабатываем очень простую систему, поэтому физические особенности среды не&lt;BR&gt;играют существенной роли, и можно сосредоточить основное внимание на разра-&lt;BR&gt;ботке объектов уровня бизнес-логики. Это дает возможность создать умозритель-&lt;BR&gt;ную модель в чистом виде и впоследствии расширять ее по мере изменения&lt;BR&gt;требований.&lt;BR&gt;Возможные классы&lt;BR&gt;При создании объектной модели зачастую используется смесь интуиции и прак-&lt;BR&gt;тического опыта, хотя для этого обычно существует теоретическое обоснование,&lt;BR&gt;которое вырабатывается с течением времени. Начнем с того, что еще раз просмотрим&lt;BR&gt;750 Практический пример&lt;BR&gt;все требования и перечислим все имена существительные, которые мы обнаружим&lt;BR&gt;в описании классов/объектов нашего приложения.&lt;BR&gt;• Web-сайт&lt;BR&gt;• Опрос&lt;BR&gt;• Вопрос&lt;BR&gt;• Ответ&lt;BR&gt;• Посетитель сайта&lt;BR&gt;• Голосование&lt;BR&gt;В этом списке наиболее заслуживающими внимания представляются следующие&lt;BR&gt;пункты: опрос, вопрос, ответ, голосование. Оставшиеся два (web-сайт и посети-&lt;BR&gt;тель сайта) не являются специфичными именно для сайта, предназначенного для&lt;BR&gt;сбора голосов, хотя они могут понадобиться позднее.&lt;BR&gt;Класс Poll (опрос)&lt;BR&gt;Когда мы обсуждаем понятие опроса, мы говорим о весьма специфическом на-&lt;BR&gt;боре данных:&lt;BR&gt;• Единственный вопрос&lt;BR&gt;• Множество ответов&lt;BR&gt;• Подсчет голосов для каждого из возможных ответов&lt;BR&gt;Не следует забывать, что в XML-файле может находиться несколько различных&lt;BR&gt;вариантов опроса, и нужно быть в состоянии создавать объект Poll для каждого из&lt;BR&gt;вариантов.&lt;BR&gt;Когда мы представляем себе, какие данные придется хранить в объектах Poll,&lt;BR&gt;рассмотрим какие функциональные возможности потребуются от такого объекта:&lt;BR&gt;• Голосование — кажется логичным предусмотреть метод vote ()&lt;BR&gt;(голосование), который будет регистрировать выбор одного из ответов&lt;BR&gt;при проведении опроса.&lt;BR&gt;• Получение вопроса — необходимо предусмотреть возможность&lt;BR&gt;доступа к вопросу, чтобы вывести его на web-странице.&lt;BR&gt;• Получение ответа — необходимо считывать список возможных&lt;BR&gt;при проведении опроса ответов, которые будут выводиться на странице&lt;BR&gt;для выбора посетителями сайта.&lt;BR&gt;• Получение числа голосов для данного варианта ответа — необходимо&lt;BR&gt;предусмотреть способ выявления проголосовавших за данный вариант.&lt;BR&gt;Это будет использоваться для вывода количества голосов по каждому&lt;BR&gt;варианту после голосования очередного посетителя.&lt;BR&gt;В классе Poll содержится большая часть необходимых возможностей, однако&lt;BR&gt;следует рассмотреть и другие классы, чтобы выяснить, какие возможности они&lt;BR&gt;могут предложить.&lt;BR&gt;Класс Question (вопрос)&lt;BR&gt;Что представляет из себя вопрос? Насколько известно из наших требований,&lt;BR&gt;это просто строка типа &quot;Какую платформу вы используете?&quot;. Поскольку это так&lt;BR&gt;просто, то можно не утруждать себя реализацией вопроса в качестве объекта,&lt;BR&gt;Практический пример 1 — юеЪ-сайт для проведения опросов 751&lt;BR&gt;а вместо этого представить его в качестве поля какого-либо другого класса. Окон-&lt;BR&gt;чательное решение мы примем, когда будем рассматривать отношения между&lt;BR&gt;классами.&lt;BR&gt;Класс Answer (ответ)&lt;BR&gt;Как и вопрос, ответ представляет из себя просто строку; однако не забывайте,&lt;BR&gt;что, хотя для каждого опроса существует только один вопрос, для него — и для&lt;BR&gt;каждого опроса— имеется несколько вариантов ответа. Следует также принять во&lt;BR&gt;внимание то, что каждый вариант ответа предполагает сохранение числа поданных&lt;BR&gt;за него голосов. Если бы мы пришли к выводу о необходимости реализации ответа&lt;BR&gt;в качестве класса, то нам следовало бы предусмотреть свойства для текста самого&lt;BR&gt;вопроса и для хранения числа поданных голосов, а также включить метод vote ().&lt;BR&gt;Окончательно решение будет принято нами в следующем разделе.&lt;BR&gt;Класс Vote (голосование)&lt;BR&gt;Что такое голос? Это либо да, либо нет. Существует другой вариант, при кото-&lt;BR&gt;ром можно говорить о голосовании как о классе &quot;Votes&quot;; в этом случае он мог бы&lt;BR&gt;содержать счетчики числа голосов для каждого из имеющихся ответов. При таком&lt;BR&gt;варианте сценария класс votes представлял бы собой нечто большее, чем просто&lt;BR&gt;некий массив. В этом случае представляется бессмысленным создавать класс, ко-&lt;BR&gt;торый будет представлять из себя всего лишь простой массив.&lt;BR&gt;Отношения между классами&lt;BR&gt;Представляется совершенно очевидным, что в качестве центрального компо-&lt;BR&gt;нента приложения используется класс Poll. В нем будут содержаться собственно&lt;BR&gt;вопрос, набор возможных ответов и счетчики числа голосов. Кроме того, в нем&lt;BR&gt;предусмотрен метод vote о , который будет регистрировать голоса, отдаваемые по-&lt;BR&gt;сетителями.&lt;BR&gt;Едва ли имеет смысл создавать для вопроса отдельный класс, поскольку вопрос&lt;BR&gt;представляет собой простую строку, поэтому мы разместим его в поле, имеющем&lt;BR&gt;тип строки, внутри какого-либо другого класса. Поскольку у каждого объекта Poll&lt;BR&gt;имеется только один вопрос, то кажется логичным прийти к заключению, что поле,&lt;BR&gt;в котором содержится вопрос, должно находится внутри класса Poll.&lt;BR&gt;Возникает вопрос, каким образом следует реализовать ответы и подсчет голо-&lt;BR&gt;сов, поскольку в данном случае есть выбор — создавать ли нам специальный&lt;BR&gt;класс &quot;Answer&quot; (ответ), в котором будут содержаться строка (с текстом ответа)&lt;BR&gt;и счетчик голосов, или просто включить соответствующую функциональную воз-&lt;BR&gt;можность в класс Poll, предусмотрев поле, где будет храниться семейство ответов,&lt;BR&gt;и параллельно еще одно поле, в котором будет храниться число голосов для каж-&lt;BR&gt;дого ответа (другими словами, второй элемент семейства поля, где находится счет-&lt;BR&gt;чик голосов, будет содержать количество голосов, которое было подано за вариант&lt;BR&gt;ответа, описываемый вторым элементом в семействе ответов). В результате такого&lt;BR&gt;подхода с точки зрения объектной модели необходимо регистрировать голоса сле-&lt;BR&gt;дующим образом:&lt;BR&gt;myAnswerText = myPoll.Answrers[3];&lt;BR&gt;myPoll.Vote(3);&lt;BR&gt;В данном случае для регистрации голоса используется метод vote о на объекте&lt;BR&gt;poll. Также имеется свойство с именем Answers (ответы), которое обеспечивает&lt;BR&gt;доступ к семейству строк (возможно, хранящемуся в виде некоторого массива).&lt;BR&gt;752 Практический пример&lt;BR&gt;Если бы мы приняли решение создать класс Answer внутри класса Poll, то код,&lt;BR&gt;позволяющий выполнять те же самые действия, принял бы приблизительно следу-&lt;BR&gt;ющий вид:&lt;BR&gt;myAnswerText•••= myPoll. Answrers [3] .Text; : I&lt;BR&gt;myPoll.Answrers[3].Vote();&lt;BR&gt;При желании можно записать его следующим образом:&lt;BR&gt;myAnswer -myPoll.Answrers[3];&lt;BR&gt;myAnswerText=myAnswer,Text;&lt;BR&gt;myAnswer.Vote();&lt;BR&gt;Отличие между двумя последними примерами заключается в том, что теперь&lt;BR&gt;семейство представляет собой семейство объектов Answer, каждый из которых&lt;BR&gt;обладает свойством Text (в котором содержится текст ответа) и методом vote().&lt;BR&gt;С практической точки зрения совершено очевидно, что первый вариант является&lt;BR&gt;более аккуратным; он позволит не тратить силы и время на создание класса Answer.&lt;BR&gt;Дополнительным преимуществом является то, что позднее, когда встанет задача&lt;BR&gt;расширения приложения, нам придется работать с меньшим количеством классов,&lt;BR&gt;и в такой редакции приложение, скорее всего, окажется более просто сопровож-&lt;BR&gt;дать. В силу этих причин мы реализуем ответы и счетчики голосов в виде се-&lt;BR&gt;мейств, являющихся полями класса Poll, а не в виде отдельного класса Answer. На&lt;BR&gt;самом деле, если впоследствии возникнет необходимость в таком длассе, то нам&lt;BR&gt;ничего не сможет помешать создать его, но на данном этапе мы оставим все про-&lt;BR&gt;стым и понятным.&lt;BR&gt;Объектная модель&lt;BR&gt;Объектная модель приложения для проведения опросов пока состоит из един-&lt;BR&gt;ственного класса — Poll, который может быть представлен следующим образом:&lt;BR&gt;Q Метод — vote ()&lt;BR&gt;/ &apos;&lt;BR&gt;• СВОЙСТВО — Question&lt;BR&gt;• Свойство — Answers [] (семейство)&lt;BR&gt;• Свойство — votes [] (семейство)&lt;BR&gt;Примем, что ответы для данного опроса будут храниться в свойстве, возвраща-&lt;BR&gt;ющем семейство строк, которое может просматриваться в цикле. Со счетчиками&lt;BR&gt;голосов работа будет вестись аналогичным образом, и они будут возвращать зна-&lt;BR&gt;чения целого типа.&lt;BR&gt;На данный момент имеется объект, который позволяет с успехом хранить сайт&lt;BR&gt;для проведения опросов, однако каким образом можно такие объекты создавать?&lt;BR&gt;Необходимо предусмотреть метод, позволяющий создавать объект Poll, который&lt;BR&gt;соответствовал бы активному в настоящий момент опросу. Воспользуемся для этой&lt;BR&gt;цели статическим методом, например, таким:&lt;BR&gt;CurrentlyActivePoll = Poll.Current();&lt;BR&gt;Это приведет нас к объектной модели, которая может быть представлена следую-&lt;BR&gt;щим образом:&lt;BR&gt;• Метод — vote о&lt;BR&gt;• Метод — Current о (статический)&lt;BR&gt;Практический пример 1 — и&amp;gt;еЪ-сайт для проведения опросов 753&lt;BR&gt;• СВОЙСТВО — Question&lt;BR&gt;О Свойство — Answers [] (семейство)&lt;BR&gt;• Свойство — votes [] (семейство)&lt;BR&gt;Свойства и методы класса Poll&lt;BR&gt;Рассмотрим сигнатуры каждого из методов и свойств более внимательно, чтобы&lt;BR&gt;четко представлять, как они должны быть реализованы. В следующем разделе мы&lt;BR&gt;рассмотрим, каким образом класс может быть использован в типичной ситуации.&lt;BR&gt;Метод Vote()&lt;BR&gt;Метод vote о может получать целое значение в диапазоне от 1 до п, где п —&lt;BR&gt;это число ответов в данном опросе. Этот метод не возвращает значение:&lt;BR&gt;public void Vote(int answer)&lt;BR&gt;Статический метод CurrentQ&lt;BR&gt;Метод Current о является статическим, поэтому доступ к нему осуществляется&lt;BR&gt;в помощью ссылки на имя класса, а не на имя экземпляра данного класса. Пара-&lt;BR&gt;метры у него отсутствуют, и он возвращает значение типа Poll, которое представ-&lt;BR&gt;ляет опрос, активный в настоящий момент:&lt;BR&gt;public static Poll Current ()&lt;BR&gt;Свойство Question&lt;BR&gt;Свойство Question возвращает строку, которая может быть использована для&lt;BR&gt;вывода вопроса посетителям web-сайта, например: &quot;Какую платформу вы исполь-&lt;BR&gt;зуете в работе?&quot;.&lt;BR&gt;public string Question&lt;BR&gt;В первой версии мы редактируем вопрос через XML-файл. Это означает, что&lt;BR&gt;данное свойство может использоваться в режиме &quot;только чтение&quot;, поэтому необ-&lt;BR&gt;ходимо реализовать предложение get, а не set.&lt;BR&gt;Свойство Answers&lt;BR&gt;Свойство Answers обеспечивает доступ к объекту, в котором содержится семей-&lt;BR&gt;ство ответов для опроса; при опросе по использованию операционных систем это&lt;BR&gt;могут быть ответы типа &quot;Windows 2000&quot;, &quot;Linux&quot;, &quot;M&amp;amp;cOS&quot; и т. д. Поскольку нам&lt;BR&gt;известен размер семейства, а все входящие в него элементы имеют один и тот же&lt;BR&gt;тип, то представляется логичным воспользоваться типом стандартного массива&lt;BR&gt;и хранить ответы в виде массива строк:&lt;BR&gt;public string [] Answers&lt;BR&gt;Как и для свойства Question, все изменения в данные вносятся вручную по-&lt;BR&gt;средством редактирования XML-файла, поэтому требуется реализовать только&lt;BR&gt;предложение get — это свойство также будет использоваться в режиме &quot;только&lt;BR&gt;чтение&quot;.&lt;BR&gt;Свойство Votes&lt;BR&gt;Свойство votes содержит в себе единственное целое значение для каждого из&lt;BR&gt;ответов проводимого опроса. Названное свойство возвращает массив целого типа,&lt;BR&gt;существующий параллельно с массивом Answers; между этими двумя массивами&lt;BR&gt;754 _ - Практический пример&lt;BR&gt;устанавливается взаимно однозначное соответствие, которое должно поддерживать-&lt;BR&gt;ся нашей реализацией:&lt;BR&gt;public int[] Votes&lt;BR&gt;Значения, хранящиеся в свойстве votes, могут изменяться только с помощью&lt;BR&gt;метода Vote (), ПОЭТОМУ данное СВОЙСТВО, так же как И СВОЙСТВа Question И Answers,&lt;BR&gt;будет использоваться в режиме &quot;только чтение&quot;, и для него необходимо реализо-&lt;BR&gt;вать только предложение get.&lt;BR&gt;В классах, подобных данному, использование одного массива должно быть&lt;BR&gt;синхронизировано с использованием другого. Возможно, в приложении, предпо-&lt;BR&gt;лагающем коммерческое использование, будет более предпочтительным создать&lt;BR&gt;отдельный класс Answer, в котором текст ответа и счетчик голосов будут более&lt;BR&gt;тесно привязаны друг к другу; не исключено также, что вы сможете отыскать какое-&lt;BR&gt;либо иное решение. Чтобы не усложнять пример, мы продолжим использовать два&lt;BR&gt;параллельных массива, что в данном случае нас вполне устраивает, поскольку мы&lt;BR&gt;очень аккуратно будем относиться к тому коду, который производит изменения&lt;BR&gt;в семействах.&lt;BR&gt;Типичное использование&lt;BR&gt;Будем считать, что теперь есть объектная модель, но как ее можно использо-&lt;BR&gt;вать? Достаточно часто мы будем обнаруживать пробелы в нашей разработке при&lt;BR&gt;рассмотрении вопроса о том, каким образом используются методы и свойства, по-&lt;BR&gt;скольку это может приводить к возникновению очевидных проблем, в частности,&lt;BR&gt;к концептуальной путанице относительно того, каким образом работает сама мо-&lt;BR&gt;дель (возможно, вам приходилось слышать о таких проблемах, как варианты ис-&lt;BR&gt;пользования, которые являются важным элементом объектно-ориентированного&lt;BR&gt;программирования). Рассмотрим простое консольное приложение, которое берет&lt;BR&gt;текущий опрос, выводит его и регистрирует голосование. Это позволит понять,&lt;BR&gt;работает ли модель с концептуальной точки зрения:&lt;BR&gt;Poll myPo]I = Poll.Current {) ;&lt;BR&gt;Console.WriteLine (myPoll.Question);&lt;BR&gt;for(int i=l; i&lt;myPoll.Answers.Length; i++)&lt;BR&gt;i&lt;BR&gt;Console.Write {myPoll.Answers [i] + *: &quot;);&lt;BR&gt;Console,WriteLine (myPoll.Votes [i] + &quot; voted&quot;);&lt;BR&gt;} :- ; •&lt;BR&gt;MyPoll.Vote (2);&lt;BR&gt;Console.WriteLine (&quot;Vote registered against &quot; + myPoll.Answers [2]);&lt;BR&gt;Console.WriteLine (Poll.Votes [2] ) ;&lt;BR&gt;Все выглядит просто замечательно; у нас есть простой и ясный путь, позволяю-&lt;BR&gt;щий считывать текущий опрос, выводить его и регистрировать процедуру голосо-&lt;BR&gt;вания. Здесь используется туРО 11. Awnswers. Length для определения количества&lt;BR&gt;ответов. Это выглядит довольно запутанным, поскольку совершенно неясно, исполь-&lt;BR&gt;зуется ЛИ В данном Случае СВОЙСТВО Length, принадлежащее Votes ИЛИ Answers,&lt;BR&gt;поэтому следует избавиться от этой путаницы и ввести свойство AnswerCount,&lt;BR&gt;которое будет возвращать число ответов для данного варианта опроса:&lt;BR&gt;public int AnswerCount // Общее свойство класса Poll&lt;BR&gt;Это приводит к некоторым изменениям в использовании класса Poll и позволяет&lt;BR&gt;сделать интерфейс более аккуратным:&lt;BR&gt;Практический пример 1 — web-сайт для проведения опросов 755&lt;BR&gt;Poll inyPoll = Poll.Current ();&lt;BR&gt;Console.WriteLine (myPoll.Question) ;&lt;BR&gt;for (int i=l; i&lt;myPoll.AnswersCount; ++i;&lt;BR&gt;{&lt;BR&gt;Console.Write (myPoll.Answers [i] + •:&lt;BR&gt;Console.WriteLine (myPoll.Votes [i] +&lt;BR&gt;&apos;);&lt;BR&gt;votes&quot;);&lt;BR&gt;MyPoll.Vote (2)&lt;BR&gt;Console.WriteLine (*Vote registered against • = myPoll.Answer [2]);&lt;BR&gt;ConsoleWriteLine (poll.Votes [2]);&lt;BR&gt;Тестирование&lt;BR&gt;Прежде чем двигаться дальше, создадим небольшое консольное приложение,&lt;BR&gt;которое будет тестировать класс Poll. У такого подхода есть два существенных&lt;BR&gt;преимущества. Во-первых, в процессе создания класса Poll всегда можно убедить-&lt;BR&gt;ся в том, что он работает. Во-вторых, можно понять, каким образом класс Poll&lt;BR&gt;допускает свое использование из консольного&lt;BR&gt;приложения с учетом того, что оно создается&lt;BR&gt;прежде всего для использования в приложе-&lt;BR&gt;нии ASP.NET.&lt;BR&gt;Сначала мы создаем новое консольное&lt;BR&gt;приложение С# в Visual Studio.NET с именем&lt;BR&gt;Poiic (сокращение от Poll Command Line)&lt;BR&gt;(см. рис. слева).&lt;BR&gt;Visual Studio.NET создаст проект консоль-&lt;BR&gt;ного приложения и сгенерирует файл с име-&lt;BR&gt;нем ciassi.cs, где находится статический&lt;BR&gt;метод MainO, который начнет выполняться&lt;BR&gt;в момент запуска файла данного консольного&lt;BR&gt;приложения с расширением .ехе.&lt;BR&gt;using System;&lt;BR&gt;namespace PollC&lt;BR&gt;- •/•// &lt;summary&amp;gt; . . • • &apos;. .. ;&lt;BR&gt;/// Общее описание для класса!&lt;BR&gt;..///• &lt;/summary&amp;gt;.&lt;BR&gt;class Classl&lt;BR&gt;static void Main (string [] (args) •&lt;BR&gt;//Действие: добавить код для запуска приложения&lt;BR&gt;}&lt;BR&gt;Теперь добавим в консольное приложение требуемый код, который позволит&lt;BR&gt;считывать активный в настоящий момент опрос, выводить его вместе со счетчика-&lt;BR&gt;ми голосов, регистрировать процесс голосования и выводить всю информацию&lt;BR&gt;снова. Для этого потребуется внести в метод Main о следующие изменения:&lt;BR&gt;static void Main (string) [] args)&lt;BR&gt;Poll myPoll = P011.Current ();&lt;BR&gt;756 Практический пример&lt;BR&gt;••DisplayPoll (myPoll);&lt;BR&gt;myPoll.Vote (2);&lt;BR&gt;Console.WriteLine {&quot;Vote registered against&lt;BR&gt;•DisplayPoll (myPoll);&lt;BR&gt;myPoll.Answers [2] j&lt;BR&gt;Приведенный код очень напоминает тот код, который нам встретился в тот мо-&lt;BR&gt;мент, когда мы рассматривали типичное использование класса Poll. В первую оче-&lt;BR&gt;редь мы создаем объект с именем myPoll, затем используем метод DispiayPoiio&lt;BR&gt;для вывода опроса на экран (мы будем рассматривать этот метод немного позже),&lt;BR&gt;затем регистрируем поданный голос посредством метода vote о класса Poll и, на-&lt;BR&gt;конец, повторно обращаемся к методу DispiayPoiio для вывода состояния опро-&lt;BR&gt;са. Если мы все сделали правильно, то счетчик голосов для второго ответа после&lt;BR&gt;этого должен увеличиться.&lt;BR&gt;DispiayPoiio —это простой частный метод, который получает объект Poll&lt;BR&gt;и выводит его в выходной поток консоли. Он показывает собственно вопрос, а так-&lt;BR&gt;же все возможные ответы вместе с числом голосов, которые были поданы за каж-&lt;BR&gt;дый из них:&lt;BR&gt;: private static viodOisplayPoll (Poll aPoll) : v;&lt;BR&gt;Console.WriteLine (Л==Ро11++&lt;!г) ;&lt;BR&gt;Console.WriteLine (aPoll.Question);&lt;BR&gt;for (int i-=l; i&lt;= (aPoll. AnswerCount) ; i++)&lt;BR&gt;Console.Write (aPoll.Answers [i] + * : &quot; ) ;&lt;BR&gt;Console.WriteLine (aPoll.Votes [i] + &quot;votes])&lt;BR&gt;}&lt;BR&gt;Console.WriteLine (*==========»);&lt;BR&gt;Метод DispiayPoiio использует свойство&lt;BR&gt;Question для вывода текста вопроса, после&lt;BR&gt;чего он проходит по всем элементам в свой-&lt;BR&gt;ствах Answers и votes и выводит текст ответа&lt;BR&gt;и число голосов для всех возможных вариан-&lt;BR&gt;тов ответа на данный вопрос.&lt;BR&gt;Создав класс Poll, мы вправе ожидать,&lt;BR&gt;что выходной поток консольного приложения&lt;BR&gt;будет иметь вид, представленный на рисунке&lt;BR&gt;слева.&lt;BR&gt;Структуры данных (уровень данных)&lt;BR&gt;У нас имеется тестирующая программа, с помощью которой можно убедиться&lt;BR&gt;в правильности работы нашего кода. Теперь рассмотрим вопрос о том, каким об-&lt;BR&gt;разом мы собираемся хранить данные в XML-файле. Следует иметь в виду, что по-&lt;BR&gt;скольку между классом Poll и данными опроса существует взаимно однозначное&lt;BR&gt;соответствие, то, в зависимости от используемого для взаимодействия с классом&lt;BR&gt;Poll интерфейса (будь то консольное приложение, Web Forms или Windows&lt;BR&gt;Forms), есть возможность ддя перехода впоследствии к другой архитектуре хране-&lt;BR&gt;ния данных. При таком использовании XML существует целый ряд ограничений,&lt;BR&gt;о которых мы поговорим несколько позже.&lt;BR&gt;Каждый опрос состоит из нескольких видов данных:&lt;BR&gt;• Question (строка)&lt;BR&gt;Практический пример 1 — web-сайт для проведения опросов 757&lt;BR&gt;• Множество Answers (строки)&lt;BR&gt;• Множество счетчиков Votes (целые)&lt;BR&gt;Отсюда следует возможность создать простой XML-файл (polls.xml) в корне-&lt;BR&gt;вой директории диска С:&amp;#92;. Файл будет выглядеть следующим образом:&lt;BR&gt;&lt;?xml version5 5 &quot; ! . О&quot; encoding-&quot;utf-8м ?&gt;&lt;BR&gt;&lt;Poll Question=&quot;What. development language do you primarily use?&quot;&amp;gt;&lt;BR&gt;&lt;Answer Text=-C#&quot; Votes=&quot;10&quot; /&amp;gt;&lt;BR&gt;&lt;Answer Text=&quot;C++&quot; Votes-&quot;2If /&amp;gt; • . •&lt;BR&gt;&lt;Answer Text=&quot;Java&quot; Votes=&quot;34&quot; •/&amp;gt;&lt;BR&gt;&lt;Answer Text55&quot;JavaScript&quot; Votes=&quot;1211 /&amp;gt;&lt;BR&gt;&lt;Answer Text55&quot;Visual Basic&quot; Votes=&quot;42&quot; /&amp;gt;&lt;BR&gt;Обратите внимание на то, каким образом используется тег Poll, в котором со-&lt;BR&gt;держится вся информация об опросе и хранится атрибут, представляющий вопрос&lt;BR&gt;данного опроса. В тег Poll вложена последовательность, состоящая из нескольких&lt;BR&gt;тегов Answer, в каждом из которых содержится текст ответа и счетчик голосов.&lt;BR&gt;XML-формат обладает достаточно простой структурой, позволяющей выпол-&lt;BR&gt;нять редактирование вручную, но еще более ценным оказывается тот факт, что,&lt;BR&gt;сохранение данных в XML-формате предоставляет целый ряд возможностей для&lt;BR&gt;считывания данных и выполнения над ними манипуляций. Теги в XML-файле, где&lt;BR&gt;хранятся ответы на опрос, обладают точно такой же структурой, как если бы они&lt;BR&gt;хранились в базе данных — по одной строке на каждый ответ со столбцами Text&lt;BR&gt;и votes. Как вы сможете увидеть впоследствии, мы будем осуществлять доступ&lt;BR&gt;к XML посредством набора данных точно таким же образом, как если бы мы осу-&lt;BR&gt;ществляли доступ к таблице, хранящейся в базе данных.&lt;BR&gt;Реализация объекта&lt;BR&gt;На уровне бизнес-логики используется единственный класс — класс Poll.&lt;BR&gt;Ниже перечислены методы и свойства, которые необходимо написать.&lt;BR&gt;Методы&lt;BR&gt;Q public static Poll Current()&lt;BR&gt;• public void Vote(int answer)&lt;BR&gt;Ш *l5i Local Project Ке.&apos;л&lt;BR&gt;User Confcrd Data Form&lt;BR&gt;Wizard&lt;BR&gt;i Щ Й&lt;BR&gt;% F f e XML Schema Cede Fto&lt;BR&gt;i l :&lt;BR&gt;I An empty cbr.^ ded»--at*3fk&lt;BR&gt;Свойства&lt;BR&gt;• public int AnswerCount&lt;BR&gt;• public string Question&lt;BR&gt;• public string[] Answers&lt;BR&gt;• public int13 Votes&lt;BR&gt;Приступим к созданию класса. Преж-&lt;BR&gt;де всего создадим пустой файл для клас-&lt;BR&gt;са Poll. Для этого в Visual Studio.NET&lt;BR&gt;нужно выбрать пункт Add Class меню&lt;BR&gt;Project и ввести имя файла Poii.cs, как&lt;BR&gt;показано на рисунке слева.&lt;BR&gt;758 Практический пример&lt;BR&gt;Visual Studio.NET создаст файл Poii.cs и сгенерирует обитую схему класса, ко-&lt;BR&gt;торая выглядит следующим образом:&lt;BR&gt;namespace Poll&lt;BR&gt;••/// &lt;sumraary&amp;gt;&lt;BR&gt;/// Общее описание для Poll.&lt;BR&gt;///&lt;/summary&amp;gt;&lt;BR&gt;public class Poll .&lt;BR&gt;с • • • • •&lt;BR&gt;public Poll {)&lt;BR&gt;.,// Действие: добавить здесь логически конструктор&lt;BR&gt;Обратите внимание на то, как используется пустой конструктор (метод Poll о );&lt;BR&gt;его использование отличается от файла Pollc.cs, в котором вместо конструктора&lt;BR&gt;использовался метод Maino. Теперь следует пройти по всем методам и посмот-&lt;BR&gt;реть, каким образом их можно реализовать.&lt;BR&gt;Прежде чем переходить к рассмотрению методов и свойств класса Poll, необ-&lt;BR&gt;ходимо определить некоторые поля. Более подробно эти поля будет рассматривать-&lt;BR&gt;ся для каждого конкретного метода. В полях будут храниться число голосов, ответы,&lt;BR&gt;вопрос, количество ответов (myAnswer-count) и полное имя XML-файла с данными&lt;BR&gt;об опросе:&lt;BR&gt;namespace Polling&lt;BR&gt;{&lt;BR&gt;public class Poll&lt;BR&gt;{.&lt;BR&gt;private int [] my Votes;&lt;BR&gt;private string [[] myAnswers;&lt;BR&gt;private string myQuestions;&lt;BR&gt;private int myAnswerCount;&lt;BR&gt;private string myFilename;&lt;BR&gt;Заметьте также, что мы изменили пространство имен на Polling.&lt;BR&gt;Метод public static Poll CurrentQ&lt;BR&gt;Этот метод — единственный статический метод, он используется для получения&lt;BR&gt;экземпляра класса Poll с данными активного опроса, которые этот класс должен&lt;BR&gt;извлечь из XML-файла. Данный метод извлекает текст вопроса из тега &lt;Question&amp;gt;&lt;BR&gt;в XML-файле и записывает его в свойство myQuestion. После этого он проходит&lt;BR&gt;В ЦИКЛе ПО всем тегам &lt;Answer&amp;gt; И переписывает значение Text В массив myAnswers,&lt;BR&gt;а Значения Votes — В массив myVotes.&lt;BR&gt;Поскольку метод предназначается для создания нового экземпляра класса Poll,&lt;BR&gt;то автор предпочел использовать для создания объекта Poll на основе XML-файла&lt;BR&gt;частный конструктор, в результате чего метод Current о становится очень про-&lt;BR&gt;стым — выполнение всей работы берет на себя конструктор:&lt;BR&gt;public static Poll Current ()&lt;BR&gt;: (&lt;BR&gt;Poll myPoll = new Poll(@ИС:&amp;#92;polls.xml&quot;);&lt;BR&gt;, :••••• • . •&apos;• . r e t U C T l М Ш&lt;BR&gt;Практический пример 1 — web-caum для проведения опросов 759&lt;BR&gt;Здесь происходит только создание нового экземпляра Poll при помощи ключевого&lt;BR&gt;слова new и передача конструктору строки с именем файла. Обратите внимание на&lt;BR&gt;то, что мы добавляем символ &apos;@&apos; в начало строки, что позволяет использовать&lt;BR&gt;в названии файла символ обратного слэша (в противном случае пришлось бы ис-&lt;BR&gt;пользовать следующую запись &quot;crWpoiis.xml&quot;; применение двойного обратного&lt;BR&gt;слэша может оказаться очень громоздким). После создания нового объекта мы&lt;BR&gt;просто возвращаем его из метода. Теперь приступим к рассмотрению нового кон-&lt;BR&gt;структора.&lt;BR&gt;Метод private Poll(string filename)&lt;BR&gt;Конструктор, который принимает имя файла-в качестве своего единственного&lt;BR&gt;параметра, используется при создании объекта Poll и конфигурировании его по-&lt;BR&gt;средством данных в XML-файле. Есть несколько возможностей извлечению дан-&lt;BR&gt;ных из XML-файла. Можно либо последовательно каждый узел и извлекать&lt;BR&gt;необходимые данные, либо считывать только определенные участки данных, кото-&lt;BR&gt;рые требуЮТСЯ (например, Сначала Строку Question, Затем все СТрОКИ Answer И Т. Д.).&lt;BR&gt;Есть и другая возможность — сериализовать объект Poll на диск, а затем десе-&lt;BR&gt;риализовать его и тем самым воссоздать объект в памяти. Существует и четвертая&lt;BR&gt;возможность: считать XML-файл в объект DataSet, что позволит обращаться с ним&lt;BR&gt;так же, как и с любым другим источником данных. Для нашего примера мы вы-&lt;BR&gt;бираем последний путь — считываем XML-файл в объект DataSet с помощью&lt;BR&gt;ADO.NET.&lt;BR&gt;На приведенной ниже диаграмме видно, что при загрузке XML-файла в набор&lt;BR&gt;данных ADO.NET создаются две таблицы (что в объектах DataSet может хранить-&lt;BR&gt;ся сразу несколько связанных таблиц). Таблица с номером ноль представляет тег&lt;BR&gt;&lt;Poii&amp;gt; и содержит всего одну строку и один столбец; в клетке этой таблицы содер-&lt;BR&gt;жится вопрос текущего опроса. Таблица с номером один содержит в себе данные&lt;BR&gt;тега &lt;Answer&amp;gt;; в ней хранятся все ответы опроса в виде двух столбцов, по одной&lt;BR&gt;строке на каждый ответ:&lt;BR&gt;&lt;?xml version &quot;=&quot;encoding=&quot;utf-8&quot;?&lt;BR&gt;Строка О&lt;BR&gt;Таблица О&lt;BR&gt;Вопрос&lt;BR&gt;&quot;What development...?&quot; Строка 0&lt;BR&gt;Строка 1&lt;BR&gt;Строка 2&lt;BR&gt;Строка 3&lt;BR&gt;Строка 4&lt;BR&gt;Таблица 1&lt;BR&gt;Текст&lt;BR&gt;С#&lt;BR&gt;C++&lt;BR&gt;Java&lt;BR&gt;JavaScript&lt;BR&gt;VisualBasic&lt;BR&gt;Votes&lt;BR&gt;10&lt;BR&gt;2&lt;BR&gt;34&lt;BR&gt;12&lt;BR&gt;42&lt;BR&gt;&lt;Poll Quest ion= &quot;What development . . . ? &quot;&amp;gt; k ЫШ/ТОец U&lt;BR&gt;&lt;Answer Text=&quot;C#&quot; Votes=&quot;10&quot;/&amp;gt;&lt;BR&gt;&lt;Answer Text=&quot;O+&quot; Votes=&quot;2&quot;/&amp;gt;&lt;BR&gt;&lt;Answer Text=&quot;Java&quot; Votes=&quot;34&quot;/&amp;gt;&lt;BR&gt;&lt;Answer Text=&quot;JavaScript&quot; Votes=&quot;12&quot;/&amp;gt;&lt;BR&gt;&lt;Answer Text=&quot;Visual Basic&quot; Votes=&quot;42&quot;/&amp;gt; Столбец О Столбец 1&lt;BR&gt;Пройдем последовательно по всему методу шаг за шагом, создавая код для за-&lt;BR&gt;грузки XML-файла в набор данных. Нам придется написать здесь еще несколько&lt;BR&gt;строе кода по сравнению с тем, что написали до сих пор. Сначала мы определяем&lt;BR&gt;сигнатуру конструктора, в которую входит строка с именем XML-файла с данными&lt;BR&gt;опроса:&lt;BR&gt;private Poll(string filename)&lt;BR&gt;{&lt;BR&gt;inyFilename = filename;&lt;BR&gt;Затем создаем объект DataSet, в котором будут храниться считываемые дан-&lt;BR&gt;ные. Объекты DataSet обсуждались в главе 19. Мы создаем экземпляр объекта&lt;BR&gt;Filestream с помощью конструктора, которому передается как имя файла, так&lt;BR&gt;760 Практический пример&lt;BR&gt;и значение перечислимого типа FileMode.open, следовательно, требуется открыть&lt;BR&gt;данный файл для чтения:&lt;BR&gt;DataSet myDataSet = new DataSet{);&lt;BR&gt;FileStream fsReadXml = newFileStream(filename, FileMode.Open);&lt;BR&gt;Чтобы оба этих объекта могли быть использованы, следует убедиться в том,&lt;BR&gt;/ что в самом начале файла присутствуют ссылки на соответствующие пространства&lt;BR&gt;имен:&lt;BR&gt;using System.Data; // Требуется для объекта DataSet&lt;BR&gt;using System.10; // Требуется для объекта FileStream&lt;BR&gt;Теперь переходим к созданию объекта xmiTextReader, который будем использо-&lt;BR&gt;вать для считывания данных из XML-файла. Для этого просто передаем созданный&lt;BR&gt;нами объект типа FileStream — fsReadXml:&lt;BR&gt;XmlTextReader myXmlReader = new System.Xml.XmlTextReader (fsReadXml) ;&lt;BR&gt;He забудьте сослаться на следующее пространство имен:&lt;BR&gt;using System.Xml; // Для объекта XmlTextReader&lt;BR&gt;Следующая строка кода выполняет за нас очень большой объем работы —&lt;BR&gt;в ней осуществляется вызов метода Readxmio на объект DataSet. Этот метод счи-&lt;BR&gt;тывает весь XML-файл в объект DataSet, а также создает таблицы и строки, не-&lt;BR&gt;обходимые для точного отображения не только самих данных, но и их структуры.&lt;BR&gt;ADO.NET формирует две таблицы; первая из них (таблица 0) состоит всего из&lt;BR&gt;одной строки и из одного столбца и содержит вопрос для опроса. Вторая таблица&lt;BR&gt;содержит по одной строке на каждый возможный ответ и два столбца — один для&lt;BR&gt;текста ответа, а второй для числа голосов, которые этот ответ получил:&lt;BR&gt;.myDataSet.ReadXml(myXmlReader);&lt;BR&gt;Следующая строка выполняет закрытие файла:&lt;BR&gt;m y X m l R e a d e r . C l o s e ( ) ;&lt;BR&gt;Остальная часть метода используется для извлечения данных, находящихся&lt;BR&gt;внутри набора данных, и переноса их в частные поля класса Poll. Прежде всего&lt;BR&gt;необходимо определить количество строк в таблице 1 (помните, что таблицы&lt;BR&gt;в наборах данных индексируются с нуля), чтобы узнать, какое количество ответов&lt;BR&gt;допускается при данном опросе, а затем сохранить это значение в поле my Answercount&lt;BR&gt;класса Poll:&lt;BR&gt;myAnswerCount = myDataSet.Tables[1].Rows - Count;&lt;BR&gt;Чтобы присвоить значение полю myQuestion (доступ к которому осуществляет-&lt;BR&gt;ся через свойство Question класса Poll), мы обращаемся к нулевой таблице и вы-&lt;BR&gt;бираем первый элемент в первой и единственной содержащейся в ней строке.&lt;BR&gt;Свойство itemArray возвращает объект типа object, поэтому необходимо восполь-&lt;BR&gt;зоваться методом TostringO (который предусмотрен в типе object), чтобы преоб-&lt;BR&gt;разовать объект в строку перед присваиванием полю myQuestion:&lt;BR&gt;myQuestion = myDataSet.Tables[0].Rows[0].ItemArray[1].ToStringO;&lt;BR&gt;В следующем блоке кода инициализируется массив my Answers, предназначен-&lt;BR&gt;ный для хранения возможных ответов, а он наполняется проходом в цикле по всем&lt;BR&gt;строкам таблицы 1, в которой содержатся эти ответы. Поскольку мы используем&lt;BR&gt;массив с индексом, отсчет которого начинается с единицы (а не с нуля), то при&lt;BR&gt;Практический пример 1 — web-caum для проведения опросов 761&lt;BR&gt;указании размера массива используется выражение myAnswerCount+i. Свойства&lt;BR&gt;votes и Answers, описанные в классе Poll, также индексируются, начиная с едини-&lt;BR&gt;цы, поскольку такой интерфейс оказывается более понятным для уровня представ-&lt;BR&gt;ления, ибо позволяет называть &quot;вопросом 1&quot; первый вопрос, а не второй (как это&lt;BR&gt;было бы при отсчете индекса с нуля). Это субъективное решение автора — вы&lt;BR&gt;можете внести изменения в код и сделать индекс массива, изменяющимся с нуля.&lt;BR&gt;Обратите внимание на то, как мы осуществляем доступ к каждому ответу в таб-&lt;BR&gt;лице 1 с перечнем возможных ответов, с помощью прохода в цикле по всем стро-&lt;BR&gt;кам и извлечения каждый раз текста в нулевом столбце:&lt;BR&gt;.v••••;•./.,• myAnswers = new string[myAnswerCount+1 ];&lt;BR&gt;s t r i n g a n s w e r ; ••• .• •• • • • &amp;#92; • : ; :&apos;-^7^k&apos;&apos;T^y-&amp;#92;&apos;,^&apos; &apos; &apos;&lt;BR&gt;for(int i=0;i&lt;myAnswerCount;i&lt;BR&gt;answer = myDataSet.Tables[1].Rows[i].ItemArray[0].ToStringO;&lt;BR&gt;myAnswers[i+1] = answer;&lt;BR&gt;Следующий блок кода практически идентичен предшествующему за исключени-&lt;BR&gt;ем того, что на этот раз мы наполняем массив myvotes и используем для этого пер-&lt;BR&gt;вый столбец таблицы. Поскольку данный массив содержит в себе значения целого&lt;BR&gt;типа, то приходится для объекта типа int использовать метод ParseO, который&lt;BR&gt;преобразует строку XML-файла в значение целого типа, прежде чем присвоить ее&lt;BR&gt;элементу массива myvotes:&lt;BR&gt;myVotes •= new int[myAnswerCount+1];&lt;BR&gt;// прибавляем 1, поскольку индекс отсчитывается с 1&lt;BR&gt;•••• S t Г i n g V O t e S ; • • • : • • &apos;• • : •••••• • • • . • , . • ; . . . / • . • • • . . • • • • • : • : : • . • , . • • . . : : , . , . . • • . • • • • . : • • . . • . ^ у&lt;BR&gt;for(int i=0;i&lt; myAnswerCount;i&lt;BR&gt;votes = myDataSet.Tables[1].Rows[iJ.ItemArray[1].ToStringO;&lt;BR&gt;myVotes[i+l] = int.Parse(votes);&lt;BR&gt;}&lt;BR&gt;В ЭТОМ КОНСТруКТОре Объект Инициализирован таким обраЗОМ, ЧТО ПОЛЯМ myQuestion,&lt;BR&gt;myAnswerCount, myAnswers и myvotes присвоены соответствующие значения, и до-&lt;BR&gt;ступ к этим значениям может быть осуществлен использованием следующих&lt;BR&gt;СВОЙСТВ Объекта: Question, Count, Answers И Votes. После СОЗДанИЯ объект Poll&lt;BR&gt;остается единственная (на данный момент) возможность вносить изменения в хра-&lt;BR&gt;нящиеся в нем данные, и она заключается в методе vote о , к рассмотрению кото-&lt;BR&gt;рого мы переходим.&lt;BR&gt;Очень важно понимать, что при использовании свойства класса Poll мы, на&lt;BR&gt;самом деле, считываем данные не непосредственно из XML-файла, а из полей,&lt;BR&gt;находящихся внутри класса. Причина, по которой программа устроена и</content:encoded>
			<link>https://krutoto.ucoz.ru/news/prakticheskij_primer_1_web_sajt_dlja_provedenija_oprosov/2010-02-11-405</link>
			<category>информатика</category>
			<dc:creator>basic</dc:creator>
			<guid>https://krutoto.ucoz.ru/news/prakticheskij_primer_1_web_sajt_dlja_provedenija_oprosov/2010-02-11-405</guid>
			<pubDate>Wed, 10 Feb 2010 21:56:37 GMT</pubDate>
		</item>
	</channel>
</rss>