Четверг, 25.04.2024, 06:57
Приветствую Вас Гость | RSS

Лекции

Меню сайта
Форма входа
Категории раздела
ТАУ (Теория автоматического управления) [31]
лекции по ТАУ
Экология [151]
учебник
Бухгалтерский учет и налогообложение в строительстве [56]
Дементьев А.Ю. - Практическое пособие
Психология [104]
Пип
информатика [80]
с# Карли Ватсон
современные стулья [0]
новинки
Поиск

Главная » 2010 » Февраль » 11 » Редактирование и обновление списков
01:00
Редактирование и обновление списков
Редактирование и обновление списков
М ы переходим к реализации методов, которые осуществляют редактирование
и обновление списков:
protected void ListsGrid_Edit (object sender, DataGridCoiranandEventArgs e)
{
ShowAddNewControls(false);
//начать редактирование
ListsGrid.Editltemlndex = (int)e.Item.Itemlndex;
BindGridO;
•• • i i i > i ушшшшш ш •••:
:- • •' : " v ••.-•• ш
protected void ListsGrid_CancelEdit (object sender", DataGridCornmandEyentArgs
ListsGrid.Editltemlndex = -I;
. • • • • . , • • . . - . • , • . . . • . B i n d G r i d O ; •••• . • ' • ' • : • ••'••' '' : " : ; ; • : V ' \ . : , - - : • , . • • • ; . . . .. : •
: protected void ListsGrid_Update(object sender, DataGridCoiranandEventArgs e)
: : • < •'•' . •.''/. - : : ' : -
if (Page.IsValid)
{ ' Щ. •• - ; :
:
.;. //получить новые данные из диалоговых окон
string ListName = ((TextBox)e.Item.FindControl("EditListName")).Text;
string ListDescr = ((TextBox)e.Item.FindControl("EditListDescr")).Text;
int ListID = (int)ListsGrid.DataKeys[e.Item.Itemlndex]; Ш
NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString()};
//обновить значения
lists.Update(ListID, ListName, ListDescr);
ListsGrid.Editltemlndex = -1; •
BindGridO;
Первая процедура ListGrid_Edit(), вызываемая при наступления события,
прячет управляющие элементы для включения новой строки и присваивает свойст-
ву Editltemlndex в качестве значения индекс редактируемой строки; это значение
извлекается из объекта item, который представляется в качестве свойства объек-
та е, передаваемого функции в качестве параметра. Наконец, опять вызывается
метод BindGridO для привязки данных текущей строки к двум текстовым окнам.
Когда нажимается иконка X, свойству Editltemlndex присваивается -1 и таблица
обновляется.
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 821
Наибольший интерес представляет то, каким образом происходит обновление
строки, осуществляемое процедурой ListGrid_update (). Выполнение кода проис-
ходит, только если страница является допустимой, т. е. когда соблюдены все пра-
вила проверки допустимости управляющих элементов. В этом случае текстовое
окно Name должно содержать допустимое имя. При успешной проверке выполнение
функции продолжается, в результате чего извлекаются текущие значения из обоих
текстовых окон. Ссылка на каждое из окон возвращается методом Findcontroi о
объекта item, после чего их содержимое считывается посредством свойства Text.
Для считывания текста из управляющего элемента TextBox необходимо текстовое
окно, которое не возвращается методом Findcontroi () в явном виде, поэтому при-
ходится вручную приводить возвращаемый объект к типу TextBox. Последний не-
обходимый параметр — это идентификатор обновляемой строки, получить который
не составляет никакого труда, поскольку данная колонка была объявлена в качест-
ве первичного ключа таблицы данных, поэтому вся работа сводится к считыванию
значения свойства. В заключение создается объект ListsDB и вызывается метод
updateO, которому передается идентификатор списка, а также новые имя и описа-
ние; в результате этого изменения вносятся в базу данных, и остается только об-
новить таблицу, чтобы эти изменения нашли в ней свое отражение.
Удаление списка
Процедура обработки события ListGrid_Deiete() обладает в точности такой же
структурой, что и только что рассмотренные события, хотя она несколько проще;
единственный параметр, который необходимо передавать методу Delete () объекта
ListsDB,— это идентификатор списка, возвращаемый перечислимым свойством
DataKey:
• protected void ListsGrid_Delete{object sender, DataGridCommandEventArgs e)
ShowAddControls(false);
ListsGrid.Editltemlndex = -1;
NewsMailer»ListsDB lists = new NewsMailer.ListsDB(GetConnString());
// получить идентификатор списка и удалить его
Lists.Delete( (int)ListsGrid.DataKeys[e.Item.Itemlndex] );
BindGridO;
} . •
Создание списка
Последнее, с чем нам осталось познакомиться,— это добавление новой строки.
При нажатии кнопки Create на экран выводятся два текстовых окна и соответству-
ющие иконки для подтверждения или отказа от выполнения операции, в то время
как сама кнопка Create становится невидимой. Кроме того, свойству таблицы дан-
ных Edititemindex присваивается значение - 1 , что предотвращает выполнение ка-
ких бы то ни было операций редактирования. Ниже приводится код для обработки
этого события, а также код функции, которая выводит или прячет управляющие
элементы в зависимости от значения передаваемого ей логического параметра:
protected void: Create_Click(object sender, EventArgs e)
{ .
// показать диалоговые окна и кнопки для добавления новой записи
ShowAddNewControls(true);
ListsGrid.Editltemlndex = -1;
BindGridO ; '
822 Практический пример
protected void ShowAddNewControls(bool ShowControls)
РШРР . • {
// показать / спрятать управляющие элементы для добавления новой записи
NewListNarne.Text^" •; ' . .
.::;•:.:•••;: NewListDescr.Text=" •; .
AddNewControlsRow.Visible = JShowControls; :
CreateNewRow.Visible=IShowControls;
PPPPi• ' •'•: '" PPPP'i-. :;"':Ф:Щ!1:;::л!:::;:'• •..';;::Р:ЙРPy-:?1^Ш1:;?.1К?Э" :лШ>::Ш
Иконка, добавляющая новый список, представляет собой не что иное, как
кнопку, для которой обработка события "щелчок мышью" имеет следующий вид:
protected void AddNew_Click(object sender, EventArgs e)
{
if (Page.IsValid)
Ш-ЙР. {
NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString() );
//добавить новую запись
lists.Add(NewListName.Text, NewListDescr.Text);
. ShowAddNewControls (false) ; :: " :
BindGridO ;
Если страница является допустимой, как в случае события update о , то про-
грамма получает содержимое двух текстовых окон и передает эти строки методу
Add о объекта ListsDB. В данном случае код оказывается несколько проще, посколь-
ку можно непосредственно ссылаться на оба окна, так как других управляющих
элементов с такими именами не существует.
Иконка, отменяющая операцию добавления, представляет собой управляющий
элемент ButtonLink, который, будучи нажатым, прячет все управляющие элементы
для имени и описания нового списка и восстанавливает все в том виде, в каком это
выводилось по умолчанию. Ниже, приводится код для обработки события click:
protected void CancelAddNew_Click(object sender, EventArgs e)
Щ i '' . • ' • / : ; ; : - Й ^ р ^ Ш ^ Ш ^ ^ ^ . ^ •. •'.',,:-;-^ ••:•' '•:•/; v.:.'
ShowAddNewControls(false);
\P::Wi::^;:::)ЖР Ж v;-: ШШ'£W¥:C;W:>::-ШР?ЖiPBwP:(Ш-:кШШШР;:;P •.i.:::;: •:•:••••. :• •' •: •:: Ш
9 • •
Здесь следует обратить внимание на один очень важный момент. Нажатие
кнопки приводит к тому, что страница отправляется обратно. В этот момент произ-
водится проверка допустимости управляющих элементов с именем и описанием, и,
если имя нового списка отсутствует, отправка страницы будет прекращена. Чтобы
избавиться от этой проблемы, можно установить режим, при котором нажатие
этой кнопки не приводит к проверке допустимости формы, присвоив ее свойству
CuasesValidtion значение false.
На этом код для данной страницы завершен. Для создания страницы потребо-
валось не такое уж большое количество кода, особенно по сравнению с кодом, ко-
торый был бы необходим при использовании традиционного ASP — даже простое
создание многофункционального табличного представления данных потребовало
бы несколько сотен (если не тысяч) строк сложного кода на ASP.
Управление подписчиками
Страница для управления подписчиками списков очень похожа на только что
проанализированную страницу, поэтому в данном разделе мы остановимся только
на ее отличиях. На рисунке (см. стр. 823) страница изображена в том виде, в каком
Практический пример 2 — Менеджер рассылки новостей в уежиме
она выводится в процессе добавления
нового подписчика. Пользователь про-
извел попытку подписаться, не указав
своего адреса электронной почты, поэ-
тому программа проверки допустимости
сообщает ему, что поле Emaii должно
быть заполнено обязательно.
Страница
Subscribers, aspx
Как видно на рисунке, эта страница
отличается от предыдущей. Одно из от-
личий заключается в том, что в таблице
присутствует другое количество столб-
цов и, кроме того, имеется раскрываю-
щееся окно, в где можно осуществлять выбор списка рассылки и просматривать
подписчиков этого списка. Помимо этого есть кнопка, которая переносит пользо-
вателя на страницу, позволяющую отправить новое сообщение по данному списку
рассылки.
Что касается столбцов, то все отличия сводятся к добавлению нескольких
новых столбцов с шаблонами, к изменению имени столбца при вызове метода
DataBinder.Evaio, а также к изменению определенных свойств некоторых столб-
цов без шаблонов. Код, относящийся к этой странице, оказывается довольно длин-
ным. Ниже приводится его первая часть, в которой описывается комбинированное
окно и кнопка Send Email (отправка электронной почты):
<asp:table id="TableLists" runat="server"• CssClass="Grid_General>
<asp:TableRow>
<asp:TableCell width="5Opx"
HorizontalAlign= "Center "><b>List :</bx/asp:TableCell>
<asp:TableCelI width=n280px"
<asp:DropDownList runat = "server" ID="ListDropDownf' ;
DataTextField="Name" DataValueField="ID" width=»280pxn '
Class="TextBoxrl AutoPostBaGk.= l!True"
OnSelectedIndexChanger-"ListsDropDown_IndexChanged" />
</asp;TableCell> >
<asp:TableCell>
<asp:Button runat="server" Text="Send Email"
ID="SendEmail" CssClass="Button11
OnClick="SendEmail_Click" Width="100px" />
</asp:TableCell>
<asp:TableRow> :
:
<asp:table>
Необходимо обратить внимание на то, что свойству раскрывающегося окна
AutoPostBack присвоено значение true. Это приводит к тому, что страница будет
отправляться обратно каждый раз, когда пользователь изменяет выбранный эле-
мент. В свою очередь, это влечет за собой наступление события OnSeiectedmdex-
Changed И, Соответственно, ВЫЗОВ процедуры LiStsDropDown_IndexChanged() .
Остальная часть страницы аналогична тому, что мы видели раньше. Рассмотрим
дополнительные строки, которые были добавлены к объявлению таблицы данных:
<asp:DataGrid id="SubscrGrid" runat-'1 server"
AllowPaging="True" :.{..•
PageSize="20"
824 Практический пример
PagerStyle-HorizontalAlign=nRight"
PagerStyle-PageButtonCount=H20"
PagerStyle-Mode=IINumericPages"
OnPageIndexChanged="SubscrGrid_J?ageChanged11
В этих строках соответственно определяется, что данные будут выводиться
в виде страниц по 20 строк и что пользователь будет иметь возможность осущест-
влять поиск и перемещение по номерам страниц, расположенных внизу справа,
а также задается процедура, которая будет обрабатывать события, связанные с из-
менением страницы.
Код поддержки для Subscribers.aspx
Что касается кода на ASP.NET, то код поддержки для subscribers.aspx не
очень отличается от страницы Lists. В нем появилось несколько строк для работы
с вновь добавленными управляющими элементами. Этот код выполняется, когда
происходит загрузка страницы:
protected void Page_Load(object sender, EveiitArgs e)
{ . •
// получить ListID из QueryString
string ListID -Request.Params[*ListID"];
SubscrGrid.Attributes[••ListlD*]. = ListID;
.If (iPage, IsPostBack)
'{
// загрузить все доступные списки в управляющий элемент DropDown
NewsMailer.ListsDB lists.= new NewsMaiier.ListsDBCGetConnStringO);
DataView myDV = lists.GetListsO .Tables [0] .DefaultView;
ListsDropDown.DataSource ^ myDV;
ListsDropDown.DataBindO ;
If (ListID!=null)
{ ' . • ' . . ' : . : . • .. ^ .:• • ' - • . / • - " ; ' • , . ; ./• •
// выбрать элемент DropDown в соответствии с ListID
forearch (ListItem item in ListsDropDown.Items)
if (item.Value==ListID) s
ListsDropDown.Selectedlndex =
ListsDropDown.Items.IndexOF(item);
- ' • ••• " ••••••• • ' • • • " > • • • •••• ••• •'•• '• •" •: ; k Щ / Ж Ч './:•.•"•'•• v \ - ' : . . ' ; ; . Л : ; :" ;• :
V/ упорядочить управляющие элементы на странице
BindGridO ;
• > Ш-ШМ ^
> I ••":"-: Ш Ш ш
С правой стороны каждой строки таблицы на страннице Lists.aspx располага-
лась иконка, которая, при щелчке на ней мышью, переносила пользователя на
страницу subscribers.aspx, чтобы он мог просмотреть всех подписчиков данного
списка. Для этого использовалась ссылка на страницу subscribers.aspx, а в стро-
ку запроса в качестве параметра добавлялся идентификатор списка. Далее это
значение извлекается из строки запроса и сохраняется в качестве атрибута эле-
мента, управляющего табличным представлением данных, так как оно будет исполь-
зоваться в тот момент, когда в этом коде будет вызываться метод GetsubscribersO
для данного списка.
Двигаясь далее, мы обнаружим, что в дополнение к обычному вызову метода
BindGrid () на этот раз используется раскрывающийся список, который наполняется
имеющимися в наличии списками рассылки. Это осуществляется непосредственно
Практический пример 2 — Менеджер рассылки новостей в -режиме онлайн 825
внутри данной процедуры посредством обращения к методу GetListsO класса
ListsDB и привязки получаемой в результате таблицы в качестве источника данных
для управляющего элемента. Вновь добавленные элементы считываются один за
другим и выбирается элемент, идентификатор которого совпадает с идентификато-
ром, хранящимся в строке запроса.
В метод BindGrido ДДЯ этой страницы включен некоторый дополнительный код,
считывающий идентификатор списка, для которого требуется извлечь подписчиков,
и, кроме того, в ней ддя получения требуемого набора данных (то есть таблицы)
ИСПОЛЬЗуетСЯ класс SubscribersDB:
protected void BindGridO
- . _ {
int ListID;
// получить значение ListID из атрибутов Grid
if { SubscrGrid.Attributes[«ListID'1 1= null )
ListID = int. Parse(SubscrGrid.Attributes!"List-ID']);
else
ListID = int.Parse (ListsDropDown.SelectedI.tem.Value);
// получить всех подписчиков данного листа
NewsMailer.SubscribersDB subscribers =
new NewsMailer.SubscribersDB(GetConnString());
DataView myDV = subscribers.GetSubscribers (
ListID).Tables[OJ.DefaultView;
// отсортировать все записи в соответствии с
// атрибутом SortExpression DataGris
if ( SubscrGrid.Attributes['SortExpression*]! = " ';
myDV.Sort = SubscrGrid.Attributes["SortExpression"];
SubscrGrid.DataSource = myDV;
SubscrGrid.DataBindO ;
}
Эта функция отвечает за выбор элемента в раскрывающемся списке:
protected void ListsDropDown_IndexChanged(object sender. EventArgs e)
{
// загрузить страницу, чтобы показать записи выбранного листа
Response.Redirect ('Subscribers.aspx?ListID='r +
ListsDropDown.Selectedltem.Value);
•; -: : .•••:•-v' :: ""•: wu • :• ш . :'&ш&шшш^. шшшш. шшiiii .' '
В результате появляется возможность повторно направить браузер на ту же са-
мую страницу, но на этот раз с идентификатором выбранного элемента, что позво-
лит произвести загрузку соответствующих подписчиков при очередном обращении
К методу BindGrid ().
Когда пользователь двигается по другим страницам таблицы данных, необходи-
мо запретить переход в режим редактирования. Это означает, что, пока не будет
произведена повторная привязка таблицы данных, необходимо спрятать элементы,
управляющие добавлением новой строки, а также не выводить сообщение об
ошибке, которая возникает, если мы пытаемся добавить уже существующего
в списке подписчика. Необходимо присвоить свойству currentPageindex фактиче-
ское значение, для того чтобы внести изменения в текущую страницу:
protected void SubscrGrid_PageChanged(object sender,
DataGridPageChangedEventArgs e)
{
SubscrGrid.EditItemlndex = -1
AddError.Visible = false;
826 Практический пример
ShowAddNewControls(false);
// изменить текущую страницу для чтения данных
SubscrGrid.CurrentPagelndex = e.NewPagelndex;
BindGridO ?
В заключение процедура, которая обрабатывает событие, наступающее при на-
жатии кнопки Send Email, передает управление на страницу sendEmaii.aspx
с идентификатором текущего списка в качестве параметра — точно так же, как
это делалось для раскрывающихся списков:
protected void SendHmail_jClick(object sender, EventArgs e)
{
// вернуться к странице, чтобы отослать Email, •
// добавить значение ListID к QueryString
Response.Redirect("SerKiErna.il.aspx?ListID-" +
ListDropDovm.Selectedltem.Value) ;
Отправка электронной почты подписчикам
\
•:.:::|.S*-:J./iC«i5.Se;K«
ъ
v>ou(<sao
• • • - : -
использующейся по умолчанию SMTP-
службы, которая инсталлируется вместе
с Windows 2000 Server, поэтому не по-
требуется ни каких-либо дополнительных
средств, ни каких-либо серверов сторон-
них производителей для отправки сообще-
ний. Кроме того, можно предварительно
просмотреть сообщение, хотя при этом
строки, ограниченные символами " # " , не
транслируются, поскольку предваритель-
ный просмотр не является специфическим
для какого-либо конкретного подписчика.
На рисунке справа изображено предва-
рительное представление тела сообще-
ния с предыдущего рисунка.
Мы достигли критической точки в реализации при-
ложения — теперь требуется разработать и написать
код для страницы, которая позволяла бы администра-
тору составлять сообщение, рассылать его всем под-
писчикам из списка и заносить его в архив в БД для
последующего просмотра. Рисунок слева дает представ-
ление о том, как это все должно функционировать.
С помощью этой страницы администратор получает
возможность создать само сообщение, отправляемое по
электронной почте, и задать практически все опции,
касающиеся отправки сообщений, которые являются
общими для большинства клиентов: СС, ВСС, формат
электронного сообщения (простой текст или HTML),
приоритет, предмет сообщения и его тело. Кроме того,
можно использовать несколько отформатированных
специальным образом строк (располагающихся с правой
стороны), которые будут автоматически заменяться на
соответствующие им значения для каждого сообщения,
отправляемого по электронной почте посредством
-;'оч: -о' > -".- 1" :i2O«"5">*UstOosc.'ip
B-a&r tfSubscri ^ I - I . ^ L . >t-# tfSubscriberLa
is seme nsv?s about C#:
- you con use •" • ••-' A: v.-T y-: •»i dows ap
C i
racia^ o u r big « f f g r t t o p r o v i d e .you .wish frepi nov,'.-, -J.-<••
(ч# code sunipk%s, news, articles: Issue u, .1.2
1?ШЩщ^и '• . -
:гтт '." ;<rr.T r:r.v; .э,Ьо'.;1 См
• ; t j , ^ v « . u ^ ^ ":: ;;;.•: ••;-;:;:;:^:'y •'-" "••:,•:•::;:•;;:::.:'
- ycu v.jj иге :: fa Ab°?,N£T .c.u W::...k-v.-? г^ргг <ii vvc'i •
• Of' r ,J :v;?- г..-jrt* *
','.> nor;1 you .;:•;>:•:<::;::= oyr b:^ tS't-rt Ю pow.:; yen r.'.th fresh ncv.-; v/l'i«
;ri;-J th;yi/'v у ом. j.,-!-r.».sn SMV^UJ lots of chocolate ,•*
: •;:.". Ш sparr lime If ус-иЧткс ^о
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 827
Страница SendEmaiLaspx
Страница ASP.NET содержит код, аналогичный коду, встречавшемуся ранее,
здесь он не будем воспроизводиться. Управляющие элементы в виде текстовых
окон, уникальные для данной страницы, используются для вывода значений
свойств NewsSubject и signature, которые хранятся в XML-файле с установками
и которые извлекаются кодом поддержки и передаются, странице.
Код поддержки для SendEamaiLaspx
Табличная сетка для вывода данных не используется на этой странице, поэтому
данный файл с кодом поддержки существенно отличается от тех двух файлов с ко-
торыми мы сталкивались перед этим. Рассмотрим код метода Page_Load(), в кото-
ром части программы, отличающиеся от предшествующих файлов, выделены
серым цветом:
// Используются две переменные для хранения конфигурационных установок
public string Signature_Value;
public string Subject_Value;
protected void Page_Load(object sender, EventArgs e)
{
string ListID = Request.Params["ListlD"]
if (IPage.IsPostBack)
// загрузить все списки, перечисленные в управляющем элементе DropDown
NewsMailer.ListsDB lists = new NewsMailer.ListsDB(GetConnString(});
DataView myDV = lists.GetLists().Tables[0].DefaultView;
ListsDropDown.DataSource = myDV;
// загрузить подписи и новые объекты из базы данных
NewsMaiier.Appsettings settings -
NewsMailer. AppConf ig.GetSettings (Server.MapPatMGetSettingsFile () ) ) ;
Signature_Value = settings.Signature;
Subject_Value = settings.NewsSubject;
Page.DataBind();
if (ListID!=null)
{
foreach (Listltem item in ListsDropDown.Items)
if (item.Value==ListID)
ListsDropDown.Selectedlndex =
ListsDropDown.Items.IndexOf(item) ;
Модуль NewsMailerConf ig используется для получения всех установок из XML-
файла, а сигнатура и предмет новостей сохраняются в общих переменных.
Заметьте, что имя файла, в котором хранятся установки, извлекается либо из
файла web.config, либо ИЗ КЭШ-памяти посредством функции GetSettingsFileO
класса Baseciass, а возвращенное значение преобразуется в реальный путь с по-
мощью вызова метода server.Mappathо, который позволяет получить полный путь
к файлу.
Когда выполняется метод DataBind о,осуществляющий привязку всех дочерних
управляющих элементов текущей формы к данным, то происходит привязка к зна-
чениям двух переменных — Signature_Value И Subject_Value — И ИХ ВЫВОД В тек-
стовых окнах.
828 Практический пример
Ниже приводится код для кнопки Preview:
protected void Preview__Click(object sender, EventArgs e)
V - , . V - : : ' \ •:; -; { " ;/:';- :.. •;.,••'•.,';:-: ••.'.•;•', : " t ' : - " . •"' : ' ! l ' - : : J y - • • ' ; ; : v . ...
string MsgText = . Body.Text;
: int ListID = int.Parse(ListsDropDown.Selectedltem.Value);
// заменить теги по спискам и установкам на их новые значения
MsgText = NewsMailer.Utilities.ProcessListTags(MsgText,
GetCoimS.tring () , List-ID) ;
MsgText = NewsMailer.Utilities.ProcessListTags(MsgText, GetConnString());
//осуществить кодировкутела, если это не формат HTML
if (FormatDropDown.SelectedIndex==0)
MsgText = HttpUtility.KtmlEncode(MsgText);
// заменить новые линии символами <br>
MsgText- MsgText.Replace("\пя, "<Ъх>");
// убрать символы возврата каретки
MsgText=...MsgText. Replace (• \r •",.•••);
MsgPreview.Text = MsgText;
MsgPreview.Visible = true;
В этом коде происходит вызов некоторых функций из класса u t i l i t i e s , кото-
рые осуществляют замены определенных тегов на соответствующие им значения,
кодирование текста в том случае, если в качестве формата выбран обыкновенный
текст (например, тег <ь> заменяется на &it;b&gt;), заменяют все переходы к но-
вой строке на тег <br> и удаляют символы "возврат каретки", поскольку символы
#\п' и '\г' не распознаются в HTML. В завершение тело сообщения выводится
в управляющем элементе предварительного просмотра.
Перейдем к коду для кнопки Send Email:
protected void Send_Click (object sender, EventArgs e)
{ '
Server.ScriptTimeout = 3 600,-
Strins MsgBady = Body.Text;
Int ListID= int.Parse(ListDropDown.Selectedltem.Value);:
String MsgSubject = NewsMailer.Utilties.ProcessListTags(
Subject.Text, GetConnString(), List-ID) ;
NewsMailer.AppSettings =
NewsMailer.AppConfig.GetSettings(Server.MapPath(GetSettingsFile()));
NewsMailer.NewsHistoryDB news = new NewsMailer. NewsHistoryDB(
GetConnString());
// заменить теги по спискам и установкам на их новые значения
MsgBody = NewsMailer.Utilities.ProcessListTags(MsgBody,
GetConnString('), ListlDOf-
MsgBody - NewsMailer. Utilities. ProcessSettingsTags (MsgBody,
GetConnString());
// добавить новую запись в архив новостей
news .Add(ListID, MsgSubject,MsgBody, (FormatDropDown.SeleC:tedIndexs==l)'.) ;•
//создать новое почтовое сообщение
MaiMessage MailMsg = new MaiM^ssage () ;
MailMsg.From•= settings.SenderName•+ * <* + settings.SenderEmail. + ">";
MailMsg.Cc = CC.Text;
MailMsg.Bcc = BCC.Text;
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 829
MailMsg. Priority•.- (Mail-Priority) PriorityDropDown. Selectedlndex;
MailMsg.BodyFormat = (MailFormat)FormatDropDown.Selectedlndex;
MailMsg.Subject = MsgSubject;
NewsMailer.SubscribersDB subscribers = new NewsMailer.SubscribersDB{
. CetCormStringO ) ;
//получить всех подписчиков данного листа..:.-.
DataTabledt = subscribers.GetSubscribers(ListDB).Tables[0];
foreach (DataRow dr in dt.Rows)
•; и - Ш { • . ШшШ- ; Щ. •••'••' •
//заменить теги подписчика на их новые значения
MailMsg.То = (srting)dr["Email"];
MailMsg.Body = NewsMailer.Utilities.ProcessSubscriberTags(MsgBody,
' GetConnStringO , (int)dr["ID"]) ;
У/ послать это сообщение данному подписчику
SmtpMai 1. Send (MailMsg');'
;!:.;:: } . .; ' "
//показать количество отосланньЕх: сообщений
MsgPreview.Text = string.Format(
*<centerxb>{0} mails have been sent</b></center>",
dt. Rows .Count. ToString ()'•);
MsgPreview.Visible - true;
ШШ. ' • • I ' ; " ; . i $m ШШШШШШ^. Wm Ш Ш •-••••• ii ШВё il • • \ i : Ш . . t
Эта программа более длинная, но работает она аналогично Preview_ciick. Она
выполняет следующие шаги:
• Специальные теги, находящиеся в списке, и общие установки заменяются
на соответствующие им значения, а при необходимости производится
кодирование текста
• Сообщение добавляется в архив с помощью метода Add о
класса NewsHistory
• Создается объект MaiiMessage и присваиваются значения его свойствам,
общим для всех подписчиков
• Для получения всех подписчиков текущего списка используется
экземпляр класса SubscribersDB
• Для каждого подписчика, полученного в результате запроса,
производится установка его адреса электронной почты в качестве
адреса назначения для отправляемого объекта, после чего происходит
отправка почты
• В управляющем элементе предварительного просмотра выводится
число отправленных сообщений
В рассмотренном коде существует несколько моментов, на которые следует
обратить внимание. Прежде всего в дополнение к обычным пространствам имен,
которые объявлялись и для других страниц, на этот раз необходимо объявлять еще
и пространство имен system.web.Maii, содержащее в себе классы, позволяющие
создавать сообщения и отправлять их по электронной почте посредством использу-
ющейся по умолчанию SMTP-службы, инсталлируемой на Windows 2000 Server.
Следующий момент, на который следует обратить внимание, имеет отношение
к самой первой строке кода:
Server.ScriptTimeout = 3600;
830 Практический пример
Отправка отдельного сообщения — очень быстрое задание, однако если есть не-
сколько тысяч подписчиков, то на это может потребоваться значительное время —
несколько минут или даже больше. Те из вас, кто уже знаком с программирова-
нием на традиционном ASP, знают, что по умолчанию странице дается 90 секунд
на выполнение кода сценария и на отправку всего сгенерированного HTML-кода
браузеру. Это значение, использующееся по умолчанию, может быть изменено
администратором IIS, либо "зашито" в программу страницы — что мы в данном
случае и делаем, устанавливая максимальное время, в течение которого страница
должна завершить свое выполнение, равное одному часу.
Класс Utilities
В файле sendEmaii.cs с кодом поддержки для замены специальных тегов в теле
и предмете сообщения используется класс u t i l i t i e s . Ниже приводится исчерпы-
вающий список методов класса. Обратите внимание на то, что они описаны как
статические; это означает, что, для того чтобы ими воспользоваться, нет необходи-
мости создавать экземпляр данного класса:
Класс Utilities
Метод Описание
public static string ReadTextFile(string FilePath)
public static bool SaveRextFile(string FilePath,
string FileText)
public static string
ProcessListTags(string Message,
string ConnString,
int ListID)
public static string
ProcessSubscriberTags (string Message,
string ConnString,
int SubscrlD)
public static string
ProcessSettingsTags (string Message,
string SettingsFilePath)
Позволяет получать содержимое заданного файла
Сохраняет строку FileText в заданном файле
и возвращает логическое значение,
свидетельствующее об успешном или
неуспешном завершении операции
Заменяет теги списка, обрамленные символами "#",
на значения, хранящиеся в базе данных
Заменяет теги подписчика, обрамленные
символами "#", на значения, хранящиеся в БД
Заменяет теги установок, обрамленные
символами "#", на значения, хранящиеся в Б Д
List: [с*
<ИКЙЗ лф**& * vowС*1 w Ss*«e ^
С* - Jssua •» Г 07/li/Cl .:*
f7 uZ/lvi'i .,.'•
A
Работа
с архивом новостей
Страница архива новостей выводит все
предыдущие новости для всех списков
рассылки либо в виде прямого текста,
либо в виде HTML — в зависимости от
того, в каком формате они отправля-
лись. На рисунке слева представлен
внешний вид страницы архива.
Страница
NewsHistory. aspx
Эта страница использует управляю-
щий элемент табличного представления
данных, но вместе с тем она обладает
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 831
некоторыми уникальными особенностями. Обратите внимание на то, что выбран-
ный ряд выводится другим цветом, нежели все остальные, а у столбца ISHTML есть
окно выбора, указывающее на то, должен ли вывод производится в виде HTML.
Поле Date указывает на дату отправления данного сообщения. Поскольку большая
часть кода не отличается от кода предыдущих страниц, мы не будем приводить весь
текст полностью, а приведем только код, описывающий столбцы ISHTML И Date.
<Columns>
. . . Code removed for clarity
<asp:BoundColumn HesderText="Subject" DataField="Subject"
Readonly="True" SortExpression="Subject" />
<asp:TemplateColumn HeaderText="IsHTML"
ItemStyle-Width^'eQpx" IternStyle-Horizoni:alAlign = "Center">
;• • <ItemTemplate>
V: : : <asp:CheckBox runat-" server*" Enabled^"false"
"Л(;):ф:. '•^•п:::у:. Checked='<%#
;-:;:;:.',:..;;:;.>-'-.,;::-:::;;:,::,:.y ••••,,:-
(bool)DataBinder.Eval(Container.Dataltem, "IsHTML")
/ > '""" ' . : : . . , ' . . • • • ' ^ / . ' ; • ' • " • . . ; • ; . . . ' . ; • ; : \ '
• </Ite.mTemplate> •
</asp:TempiateColumn> •
<asp:TemplateColumn HeaderText="Date"
SortExpre3sion=llSentDatetf ItemStyle-Width="9Qpx">
<ItemTemplate>
<asp:Label runat="server"
Text=='<%# string.Format(-{0:MM/dd/yy}",
DateTime.Parse(DataBinder.Eval(Container.Dataltem,
"SentDate") .ToStringO ) ) %>'
/>
</ItemTemplate>
' ••'• '.. ' :• : </asp:TemplateColumn> •
Как и для страницы Send Email, где мы привязываем общую переменную к текс-
товому окну, в данном случае столбец is HTML может использоваться в режиме
"только чтение", и в нем содержится отключенное окно выбора (отключенное,
поскольку информация о прошлых сообщениях не может изменяться администра-
тором посредством этой страницы), значение которого устанавливается в соответ-
ствии со значением поля ISHTML таблицы NewsHistory, хранящейся в базе данных,
и приводится к типу bool. .
Чтобы ПОЛуЧИТЬ Значения ПОЛЯ Date, ИСПОЛЬЗуеТСЯ меТОД DateTimeParse (), ПО-
ЗВОЛЯЮЩИЙ преобразовать строку из базы данных в значение типа DateTime, кото-
рое затем снова преобразовывается в строку для вывода на экран.
Код поддержки для NewsHistory. aspx
Пояснения, которыми мы сопроводим данный код, будут очень короткими, по-
скольку большая часть операций, уже обсуждалась для других файлов с кодом под-
держки. Единственной новой особенностью, заслуживающей обсуждения, является
процедура, обрабатывающая событие таблицы данных OnSelectedlndexChanged.
Когда некоторая строка оказывается выбранной, то тело соответствующего сооб-
щения извлекается, перекодируется в обычный тест и выводится в управляющем
элементе предварительного просмотра:
protected void NewsGrid_SelectionChanged(object sender. EventArgs e)
string Body;
. ..: NewsMailer.NewsHistoryDB news = new NewsMailer.NewsHisroryDB (GetConnStringO );
832 Практический пример
If получить ID выбранной строки
int NewsID = int.Parse(NewsGrid.DataKeys[NewsGrid.Selectedlndex].ToStringO);
// получить массив новостей из базы данных
Body = news. GetDetails(NewsID) ['Body].ToStringO;
// если формат новостей не HTML, осуществить кодировку текста Body
if (]Convert.ToBoolean(news.GetDetails(NewsID)["IsHTML"]))
Body = HttpUtility.HtmlEncode(Body);
// заменить новые строки символами <br>, чтобы показать их з элементе Label
Body = Body.Replace (Ли* , " ,Ъг>п) ;
Body = Body. Replace ( *\*r", " ") ;
// показать тело Body в элементе "предварительный просмотр*
MsgPreview.Text - Body;
Msg Preview.Visible = true;
Обратите внимание на то, что нам не приходится в данном случае заменять ни-
каких специальных тегов, поскольку все они были заменены перед тем, как сооб-
щение было помещено в архив, хранящийся в базе данных.
Кроме того, в тот момент, когда администратор изменяет просматриваемую
страницу таблицы данных, нам необходимо отказаться от выбранной строки, по-
скольку эти действия автоматически не выполняются:
protected void NewsGrid_PageChanged(Object sender, DataGridPageEventArgs e)
{
UnselectGridltemO ;
/ / изменить текущую страницу для чтения данных
NewsGrid.CurrentFagelndex - e.NewPageIndex;
BindGridO ;
}
protected void UnselectGridltemO
{
// спрятать элемент "предварительный просмотр"
NewsGrid.Selectedlndex = -1;
MsgPreview.Text = * T;
MsgPreview.Visible ~ false;
Ш
!tewt&«»tr««r - " - < - • • ; „ • 0 "
- • - ; '• * , .*•-- **
. . ,_„ .. :
МЙММЯМ л
В
Изменение установок
в режиме онлайн
Нам уже неоднократно приходилось использо-
вать значения, хранящиеся в XML-файле с установ-
ками NewsMailer. Settings, которые МЫ определили
в момент создания этого файла. Теперь нам потре-
буется web-страница, позволяющая модифицировать
эти установки в режиме онлайн — без необходимо-
сти садиться перед web-сервером и вручную вно-
сить изменения в базу данных. Страница, о которой
идет речь, изображена на рисунке слева.
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 833
Страница Settings.aspx
Страница ASP.NET формируется с помощью набора управляющих элементов,
к которым привязываются соответствующие установки, хранящиеся в базе данных
Settings. Они привязываются к общим переменным, значения которых задаются
в коде поддержки, как и для страницы Send Email. Настоящая страница является
очень большой, для иллюстрации ее работы мы приводим участок кода, в котором
описывается поле Sender Email, а также происходит наполнение соответствующего
текстового окна с выполнением дополнительной проверки допустимости:
<asp:TableRow>
<asp:TableCell Text="News Sender Email:" />
<asp:TableCel1>
<asp:TextBox runat="server" Width=M500px" ID-"SenderEmail"
Сlass-"TextBox" Text='<%# SenderEmailJValue %>' />
<asp:RequiredFieldValidator runat="server"
ContrclToValidate--" SenderEnia.il" ..
Display="dynamic"><br>* This field is required
' </asp:RequiredFieldValidator> :...,•
<asp:RegularExpressionValidator runat="server"
' validationExpression^". *§. *\ . . *w
ControlToValidate="SenderEmail"
Display= "dynamic"><br>* This Email address is not; valid
</asp:RegularExpressionVali -dator>
</asp:TableCell>
</asp:TableRow>
Приведенный выше управляющий элемент является особенным, поскольку
в нем присутствует не один, а два элемента, предназначенных для проверки допус-
тимости: один из них позволяет гарантировать, что текстовое окно не является пу-
стым в момент отправки формы, а второй — что строка с адресом электронной
почты представлена в допустимом формате. В последнем случае используется
ReguiarExpressionVaiidator, и, как следует из его названия, он выполняет про-
верку допустимости регулярного выражения. В настоящем примере используется
следующее выражение:
<asp:ReguiarExpressionVaiidator runat="server"
validationExpression=" . * @ . * \ . .*" .. : . ;:':::'::: ;4v> •;-*•;: • '••-.••.•:.r'::'.:"','--'::/-ControlToValidate="SenderEmail"
Display="dynamicI1><br>* This Email address is not valid
</asp:RegularExpressionValidator>
Это означает, что строка должна начинаться с символов (.*), затем в ней должен
находиться символ '@', потом произвольные символы, затем точка (для которой
используется escape-последовательность \.) и, наконец, произвольные символы.
Например, mbeiiinaso@vb2themax.com представляет собой допустимый адрес элек-
тронной ПОЧТЫ, В ТО время KaKmbellinaso@vb2themax ИЛИ mbellinaso.libero.it —
недопустимые адреса.
Регулярные выражения представляют собой весьма мощный инструмент для
проверки допустимости содержимого управляющего элемента, поскольку названные
выражения могут быть детальными и сложными; их использованию посвящены
целые книги. Кроме того, существует возможность при написании функции, произ-
водящей проверку допустимости, использовать метод CustomVaiidator, который
позволяет осуществлять еще более жесткий контроль.
834 Практический пример
Код поддержки для файла Settings.aspx
Код поддержки для внесения изменений в установки состоит из двух процедур:
одна из них — это метод Page_Load(), предназначенный для извлечения установок
из базы данных с помощью объектов AppConf ig и AppSettings и привязки их к со-
ответствующим серверным управляющим элементам посредством вызова метода
Page.DataB ind():
protected void Page_JL.oad(object sender,EventArgs e) •
• • • ••• • " V • < ./ .. • • ; ' -
if ( UsFostBack) ;
ШЩ••/.••:• "' • , ^ < ' •' ••••"•;' ;
// загрузить Бее установки
NewsMailer.AppSettings settings =
NewsMailer. AppConf ig GetSettings (Server.MapPath(GetSettingsFiIe ().).);
SubscribeURL_Value - settings.SubscribeURL;
SenderName_Value = settings.SenderName;
SenderEmail_Value ~ settings.SenderEmail; :
NewsSubject_Value = settings.NewsSubject;
SubscrSubject_Value = settings.SubscrSubject; : ;
; SubscrMessage__Value - settings.SubscrMessage; : : •{.
UnSubscrSubj ect__Value = settings.UnSubscrSubject;
x : :: . •'; UnSubscrMessage_Value = sett ings. UnSubscrMessage;
; Signature_Value = settings.Signature;
. SendSubscrEmai'lJvalue = sett ings. SendSubscr Email;
SendUnSubscrEmail_Value,= settings.SendUnSubscrEmail;
••• ':' ••';• .:• , • '•.'•,•..,•'• : .: •,• • P a g e . D a t a B i n d ( ) . ; . ' . • , . ; .••••':. , . '/•..••'•'- ; . . : ; ' ' V ';.}:•:',•/'•''.'.[ . . . ... . .
Вторая процедура — это update_ciick(), которая вызывается в момент, когда
мышь щелкает кнопку Update. Эта процедура собирает новые значения установок,
находящиеся в управляющих элементах, присваивает их свойствам нового объекта
AppSettings и вызывает метод SaveSettings о объекта AppConf ig для сериализа-
ЦИИ объекта settings В XML-фаЙЛ (в данном Случае — В NewsMailer. Settings):
protected void Update_Click{object sender,EventArgs e)
. . { . •. •, . • • • • . ' • : , • • . . • . • • • •: ;;. : ' " : . v . . • •'; v
NewsMailer.AppSettings settings = new NewsMailer.AppSettings();
// установить новые значения для всех свойств
settings.SubscribeURL = SubscribeURL.Text;
settings.SenderName = SenderName.Text ; ; •;
settings.SenderEmail -SendarEmai.Text ; :
settings.NewsSubject = NewsSubject.Text; :
settings.SubscrSubject = SubscrSubject.Text;
settings.SubscrMessage ~ SubscrMessage.Text;
settings.UnSubscrSubject = UnSubscrSubject.Text;
settings.UnSubscrMessage = UnSubscrMessage.Text;
settings.Signature = Signature.Text ;
settings.SendSubscrEmail = SendSubscrEmail.Checked;
settings.SendUnSubscrEmail'= SendUnSubscrEmail.Checked;
NewsMailer .AppConf ig. SaveSettings (Server. Map?ath( Get Sett ingsFil.e (.)•) , settings) ;
Изменение внешнего представления в режине онлайн
В самом начале этого раздела говорилось о том, что все стили для управляю-
щих элементов хранятся в отдельной таблице стилей, а не внутри страницы. На
самом деле, "зашитые" в программу цвета и другие параметры стилей внешнего
Практический пример 2 — Менеджер рассылки новостей в режиме онлайн 835
il
Тле eg
СсГг cJiapqt» any <«lir.bu:e of c-rv/ HTN'.L Sfement (ca'or
;?'u: x.;r,-.5:i\efi«'".iJ -'•--=, sans-serif;
font: м J>ml V^rdanii, AriaL sans-serif;
1ЙЖ--Г'"'"
^ : / - «is
I
•;.c>... ;h:;< ->г.у|й sheet used by ever,1 paqo. Vou
i, uz<: tv.c.) зг>й «fror> press ?ha Updato button to
1
J
!•
_J
представления всегда оборачиваются
головной болью, когда необходимо
внести какие-либо изменения, так как
приходится вручную проходить по
всем страницам и изменять все вхож-
дения для стиля, который мы хотим
модифицировать. Наличие таблицы
стилей позволяет существенно упрос-
тить жизнь. Однако, все равно было
бы хорошо иметь возможность редак-
тировать таблицу стилей в режиме
онлайн, вместо того, чтобы вносить
изменения в файл на локальном
компьютере, а затем отправлять этот
файл обратно на сервер. Реализация
страницы, которая позволяет редакти-
ровать файлы, требует всего лишь не-
скольких минут и нескольких строк
кода, и к созданию именно такой стра-
ницы мы сейчас и приступим.
На рисунке слева представлен наш
простой редактор таблиц стилей.
Если вы знаете CSS, то вы получаете возможность изменять стили управляю-
щих элементов ASP.NET, а полное изменение стиля всего пользовательского ин-
терфейса — это вопрос нескольких секунд!
Страница Layout.aspx
Этот файл не очень отличается от других управляющих элементов ASP.NET,
поэтому мы не будем приводить здесь весь код полностью. Изображенная ниже
строка кода, однако, требует дальнейших пояснений:
<asp:Label ID="FileNamen runat="Server" Text="Styles."ess" Visible="false" />
В этой строке объявляется скрытая надпись, которая используется для задания
имени файла, подлежащего редактированию.; это означает, что, изменяя эту уста-
новку, мы получаем возможность редактировать произвольный текстовый файл.
Администратору по-прежнему необходимо выполнить повторную загрузку, если он
изменяет путь к файлу в скрытых управляющих элементах, однако это оказывается
намного проще и быстрее, чем изменять значения в файлах с кодом поддержки,
поскольку в таком случае приходится заново транслировать и загружать весь мо-
дуль. Всегда помните, что приложение должно распространяться в откомпилиро-
ванном виде, а отсюда следует, что если какая-нибудь установка будет "зашита"
в программу, то это приведет к тому, что администратор сайта, работающий уда-
ленно, окажется не в состоянии изменить ее без помощи разработчи
Категория: информатика | Просмотров: 2281 | Добавил: basic | Рейтинг: 5.0/1
Всего комментариев: 4
4 xcsasdqwafasad  
0
http://prixviagragenerique50mg.net/ - vente viagra viagra
http://prezzoviagraitalia.net/ - viagra generico prezzo viagra 25 mg
http://precioviagraespana.net/ - precio viagra comprar viagra espana

3 asczxcsad  
0
http://achatviagrageneriquepascher.net/ - viagra viagra achat en ligne
http://comprarviagrasinreceta.net/ - viagra precio viagra 50 mg
http://acquistareviagrasenzaricetta.net/ - comprare viagra viagra ricetta medica
http://precioviagragenerico.net/ - precio viagra viagra precio

2 Harlam7168  
0
на этом интернет-ресурсе вы сможете взглянуть на огромный выбор интересных статей про http://ublaze.ru/forum/ftopic1149.html - ресивер триколор 8306

1 Janna7928  
0
тут на данном веб-блоге можно взглянуть на огромный набор уникальных новостей о ` http://www.infosuper.ru/ - Работа.

Имя *:
Email *:
Код *:
Календарь
«  Февраль 2010  »
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

krutoto.ucoz.ru
Бесплатный конструктор сайтов - uCoz