KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Симон Робинсон - C# для профессионалов. Том II

Симон Робинсон - C# для профессионалов. Том II

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Симон Робинсон, "C# для профессионалов. Том II" бесплатно, без регистрации.
Перейти на страницу:

</form>

Соединим обработчик события нажатия кнопки со службой Web. Для начала добавим в проект ссылку на службу Web. Чтобы сделать это, щелкнем правой кнопкой мыши на приложении в Solution Explorer и выберем пункт Add Web Reference… В появившемся окне введем URL файла .vsdisco службы Web:

Здесь можно следовать по ссылкам справа, чтобы получить те же самые описания с границы Web службы, которые мы видели в предыдущем разделе, и добавить ссылку с помощью кнопки Add Reference Нажатие на эту кнопку приведет к следующим изменениям в Solution Explorer:

Папка, содержащая нашу ссылку Web, называется по имени сервера, где расположена служба, в данном случае — localhost. Это также пространство имен, на которое необходимо ссылаться, чтобы использовать класс прокси, поэтому имеет смысл переименовать папку, что можно сделать с помощью щелчка правой кнопкой мыши на папке. Если переименовать эту папку в myWebService и добавить инструкцию using в код…

using PCSWebClient1.myWebService;

…то тогда можно будет использовать службу в нашем классе.

Добавим обработчик событий к кнопке на форме с помощью следующего кода:

protected void triggerButton_Сlick(object sender, System.EventArgs e) {

 Service1 myService = new Service1();

 resultLabel.Text = myService.CanWeFixIt();

}

Нажатие кнопки во время выполнения приложения приведет к выводу CanWeFixIt() в окне браузера.

Служба Web может впоследствии измениться, но с помощью такого метода можно просто сделать щелчок правой кнопкой мыши на ссылке Web в проводнике сервера и выбрать Update Web Reference. Это создаст для нас новый класс прокси.

Расширение примера заказа помещения для проведения мероприятий

Теперь, когда мы знакомы с основами создания и использования служб Web, давайте применим наши знания, расширив приложение заказа помещения для проведения мероприятий из предыдущей главы. В частности, извлечем детали доступа к базе данных из приложения и поместим их в службу Web. Эта служба Web имеет два метода:

□ GetData(), который будет возвращать объект DataSet, содержащий все три таблицы базы данных PCSWebApp3.

□ AddEvent(), добавляющий событие и возвращающий обновленную версию DataSet, которая включает изменение

Кроме того, мы создадим службу Web, помня о некоторых приемах сокращения нагрузки из предыдущей главы. В частности, мы будем хранить DataSet на уровне приложения в приложении службы Web. Это означает, что несколько запросов данных не потребуют работы дополнительных запросов к базе данных. Данные в этом DataSet уровня приложения обновятся, когда в базу данных добавятся новые данные. Это означает, что изменения, сделанные в базе данных другими средствами, такими как редактирование вручную, не будут отражаться в этом DataSet. Тем не менее, до тех пор, пока мы знаем, что наша служба Web является единственным местом с прямым доступом к данным, нам не о чем беспокоиться.

Служба Web заказа помещения для проведения мероприятий

Создайте новый проект службы Web в VS.NET с именем PCSWebSrv2. Для начала добавим код в обработчик Application_Start() в global.asax. Мы хотим загрузить все данные из PCSWebApp3.mdb в множество данных и сохранить его. Это будет по большей части включать код, с которым мы знакомы, так как перенос базы данных в DataSet уже делали. Фактически, можно скопировать весь нужный код из WebForm1.aspx.cs в PCSWebApp3 из предыдущей главы, включая строку соединения с базой данных (которая здесь не показана, так как у читателя она должна быть, скорее всего, другой):

protected void Application_Start (Object sender, EventArgs e) {

 System.Data.DataSet ds;

 System.Data.OleDb.OleDbConnection оleDbConnection1;

 System.Data.OleDb.OleDbDataAdapter daAttendees;

 System.Data.OleDb.OleDbDataAdapter daRooms;

 System.Data.OleDb.OleDbDacaAdapter daEvents;

 oleDbConnection1 = new System.Data.OleDb.OleDbConnection();

 oleDbConnection1.ConnectionStnng = @" ... ";

 oleDbConnection1.Open(); ds = new DataSet();

 daAttendees =

  new System.Data.OleDb.OleDbDataAdapter(

  "SELECT * FROM Attendees", oleDbConnection1);

 daRooms =

  new System.Data.OleDb.OleDbDataAdapter(

  "SELECT * FROM Rooms", oleDbConnection1);

 daEvents =

  new System.Data.OleDb.OleDbDataAdapter(

  "SELECT * FROM Events", oleDbConnection1);

 daAttendees.Fill(ds, "Attendees");

 daRooms.Fill(ds, "Rooms");

 daEvents.Fill(ds, "Events");

 oleDbConnection1.Close();

 Application["ds"] = ds;

}

Необходимо отметить важный код в последней строке. Объекты Application (и Session) имеют коллекцию пар имя/значение, которую можно использовать для хранения данных. Здесь создается имя ds в хранилище объекта Application, которое получает сериализованное значение DataSet из ds, содержащее таблицы Attendees, Rooms и Events из базы данных. Это значение будет доступно всем экземплярам службы Web в любое время.

Чтобы приведенный выше код работал, нам нужно также добавить ссылку на пространство имен System.Data в пространстве имен PCSWebSrv2 в global.asax:

namespace PCSWebSrv2 {

 ...

 using System.Data;

Эта техника очень полезна для данных, предназначенных только для чтения, так как несколько потоков выполнения смогут к нему обращаться, сокращая нагрузку на базу данных. Отметим, однако, что таблица Events скорее всего должна измениться и будет обновлять DataSet на уровне приложения, когда это произойдет. Мы скоро это увидим.

Затем необходимо добавить к службе в Service1.asmx.cs метод GetData():

[WebMethod]

public DataSet GetData() {

 return (DataSet)Application["ds"];

}

Здесь для доступа к множеству данных используется тот же синтаксис, что и в Application_Load(), где просто выполняется преобразование типа данных в правильный тип, а также возврат.

Метод AddEvent() немного сложнее. Концептуально нам необходимо сделать следующее:

□ Получить данные события от клиента.

□ Создать инструкцию SQL INSERT с помощью этих данных.

□ Соединиться с базой данных и выполнить инструкцию SQL.

□ Если добавление выполнится успешно, то обновить данные в Application["ds"].

□ Вернуть уведомление об успехе или отказе клиенту (мы оставляем клиенту возможность обновить его DataSet, если потребуется).

Начиная сверху, принимаем все поля как строки:

[WebMethod]

public int AddEvent(String eventName, String eventRoom, String eventAttendees, String eventDate) {

}

Затем мы объявляем объекты, которые нужны для доступа к базе данных, соединяемся с базой данных и выполняем запрос, используя код аналогичный коду в PCSWebApp3 (здесь также требуется строка соединения, которая здесь не показана):

[WebMethod]

public int AddEvent(String eventName, String eventRoom, String eventAttendees, String eventDate) {

 System.Data.OleDb.OleDbConnection oleDbConnection1;

 System.Data.OleDb.OleDbDataAdapter dbEvents;

 DataSet ds;

 oleDbConnection1 = new System.Data.OleDb.OleDbConnection();

 OleDbConnection1.ConnectionString = @" ... ";

 String oleDbCommand =

  "INSERT INTO Events (Name, Room, AttendeeList, " +

  " EventDate) VALUES ('" + eventName + "', +

  eventRoom + "', '" + eventAttendees + "', '" + eventDate + "')";

 System.Data.OleDb.OleDbCommand insertCommand =

  new System.Data.OleDb.OleDbCommand(oleDbCommand, oleDbConnection1);

 oleDbConnection1.Open();

 queryResult = insertCommand.ExecuteNonQuery();

}

Используем, как и прежде, queryResult для хранения числа строк, затронутых запросом. Мы можем проверить его, чтобы оценить наш успех. Если все происходит хорошо, выполняется новый запрос на базе данных для обновления таблицы Events в нашем DataSet. Жизненно важно блокировать данные приложения во время выполнения обновлений, чтобы гарантировать, что никакие другие потоки выполнения не могут получить доступ к Application["ds"] во время его обновления. Это можно сделать с помощью методов Lock() и UnLock() объекта Application:

[WebMethod]

public int AddEvent(String eventName, String eventRoom, String eventAttendees, String eventDate) {

 ...

 int queryResult = insertCommand.ExecuteNonQuery();

 if (queryResult == 1) {

  daEvents =

   new System.Data.OleDb.OleDbDataAdapter(

   "SELECT * FROM Events", oleDbConnection1);

  Application.Lock();

  ds = (DataSet) Application["ds"];

  ds.Tables["Events"].Clear();

  daEvents.Fill(ds, "Events");

  Application["ds"] = ds;

  Application.UnLock();

  oleDbConnection1.Close();

 }

}

Наконец, мы возвращаем queryResult, позволяя клиенту узнать, что запрос был успешным:

[WebMethod]

public int AddEvent(String eventName, String eventRoom, String eventAttendees, String eventDate) {

 ...

 return queryResult;

}

Это завершает создание службы Web. Как и прежде, есть возможность протестировать эту службу, направляя браузер Web на файл .asmx, поэтому мы можем добавить записи и взглянуть на представление XML для DataSet, возвращаемое GetData(), не создавая никакого клиентского кода.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*