При первом знакомстве с ASP .NET возникает обманчивое
впечатление, что перед вами всего лишь очередной способ динамического
построения web-страниц. В действительности возможности ASP .NET выходят далеко
за рамки того, что можно было сделать традиционными
средствами ASP. Хотя ASP .NET сохраняет совместимость с ASP, это совершенно
новая и вполне самостоятельная технология. Так, в ASP .NET входят элементы web-форм,
которые должны сыграть по отношению к броузерным приложениям ту же роль, что
и классические элементы VB для программирования Windows-приложений для любых
клиентов — как для броузеров на PC, так и для портативных устройств. Откомпилированный
код ASP .NET значительно быстрее работает на сервере; он хорошо масштабируется,
использует модель безопасности .NET, поддерживает несколько способов аутентификации
и т. д.
Вероятно,
ASP .NET станет первой частью .NET, широко используемой в коммерческих приложениях.
Microsoft настолько гордится своими достижениями в области ASP .NET, что помимо
перевода некоторых частей своего сайта на эту технологию компания пошла на беспрецедентный
шаг, разрешив использование коммерческих приложений на базе ASP .NET бета-версии
2!
Эта короткая
глава написана для того, чтобы дать некоторое представление о новых возможностях
ASP .NET программистам с опытом работы на ASP. Конечно, она не заменит специализированных
книг по ASP .NET, уже появившихся на рынке.
Технология
ASP появилась в 1997 году и предназначалась для построения web-страниц в Internet
Information Server (US). В сценариях ASP HTML-код объединялся со сценарным кодом,
интерпретируемым IIS в ответ на запросы со стороны клиента. В результате строилась
страница HTML, которая возвращалась клиенту. Технология ASP обладала рядом недостатков:
Эти и другие
проблемы решаются в новой технологии ASP .NET.
Простое
web-приложение для ASP .NET
Выберите
в диалоговом окне New Project значок приложения ASP .NET.
После небольшой
задержки VS IDE создает страницу, которой по умолчанию присваивается имя WebFormsl.aspx.
Сгенерированная страница содержит код вывода для приложения ASP .NET. Примерный
вид VS .NET IDE показан на рис. 12.1. Обратите внимание, сколько файлов было
создано для такой простой страницы (имена файлов перечислены в окне решения).
Посмотрите на каскадный список стилей, определяющий общие параметры внешнего
вида страницы. Дизайнер очень похож на дизайнер форм Windows, описанный в главе
8. Слева расположена панель, с которой элементы перетаскиваются на web-страницу
(конечно, web-страницы на стадии конструирования обладают меньшими возможностями
по сравнению с формами Windows, поскольку они должны работать в броузере).
Создайте
на форме надпись и кнопку. Растяните надпись по ширине страницы, расположите
кнопку под надписью и выровняйте по центру, при этом генерируются экземпляры
классов из пространства System. Web. UI. WebControl. Ссылка на это пространство
имен автоматически включается в решение при создании «скелета» нового
приложения ASP .NET. В свойстве Text надписи следует ввести пустую строку, а
в свойстве Text кнопки вводится текст «Click me!». Изменения свойств
сохраняются в HTML-коде, содержащемся в странице .aspx. Чтобы просмотреть базовый
HTML-код, можно выполнить команду View > HTML Source (клавиши Ctrl+PageDown)
или выбрать вкладку HTML в IDE. В следующем фрагменте ключевые строки выделяются
жирным шрифтом1.
<%@Page Language="vb"AutoEventWireup="false"
Codebehind="WebForml.aspx.vb"
Inherits="WebApplicationl.WebForml'l>
<!DOCTYPE HTML PUBLIC "-//W3C//
DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title></title>
<meta name="GENERATOR"
content="Microsoft
Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE"content="Visua1
Basic 7.0">
<meta name="vs_defaultClientScript"content="JavaScript">
<meta name="vs_ta rgetSchema"
content= "http://schemes.microsoft.com/intel1i sense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Forml"niethod="post''runat="server">
<asp:Button id="Buttonl"style="Z-INDEX:101;LEFT:311px: POSITION:absolute;TOP:212px"r'bnat-"server"Text-"Click me!" Width="123px"Height="67px">
</asp:Button>
<asp:Label id="Labe11"
style="Z-INDEX:102;LEFT:
15px;POSITION:absolute: TOP:40px"runat="server
"Width="631px"Height="132px">
</asp:Label>
</form>
</body>
</HTML>
Рис.
12.1. Простое приложение ASP .NET в IDE
В первой
выделенной строке атрибуту runat присваивается значение server, указывающее
на то, что код элемента должен выполняться на стороне сервера, а не на стороне
клиента. В принципе код ASP .NET может работать и на стороне клиента, но это
делается очень редко, поскольку многие возможности ASP .NET становятся недоступными
(в сущности, при этом выполняется сценарий клиентской стороны, не имеющий ничего
общего с ASP .NET).
Обратите
внимание: все теги элементов страницы снабжаются префиксом <asp:. Дело в
том, что элементы ASP .NET не являются элементами HTML. Они находятся
на сервере, и обычные элементы HTML используются только в страницах, передаваемых
клиенту (там, где это возможно). Так, в HTML не существует аналогов для таких
элементов ASP .NET, как календарь или элемент интервальной проверки. В этом
случае в ASP .NET для достижения желаемого эффекта используется
комбинация обычных элементов HTML, сценарного кода и кода, работающего на стороне
сервера.
Если дважды
щелкнуть на кнопке, в окне программы открывается процедура события Cl i ck.
Открывшаяся страница имеет много общего с приложениями, созданными на базе форм
Windows; она тоже содержит автоматически сгенерированный код, который будет
описан ниже. В приложениях ASP .NET код обычно отделяется от средств визуального
представления и хранится в отдельном файле с двойным расширением .aspx.vb.
Включите
в процедуру события Cl ick следующий фрагмент:
Private Sub Buttonl_Click(ByVal sender As System.Object,_
ByVal e As System.EventArgs)
Handles Buttonl.Click
Me.Label 1.Font.Size
= FontUnit.XLarge
Me.Label 1.Text = "Welcome to ASP .NET @" & Now
End Sub
Обратите
внимание на сходство этого кода с обработчиками событий в приложениях форм Windows,
включая наличие параметров sender и EventArgs. Свойство Font в web-элементах
несколько отличается от одноименного свойства форм Windows, и это вполне естественно,
поскольку количество шрифтов, отображаемых в страницах HTML, заметно ограничено
по сравнению с формами Windows. Также обратите внимание на возможность использования
встроенных функций .NET (таких, как Now) в коде ASP .NET. Приложения ASP .NET
обладают полноценным доступом к .NET Framework. В частности, это означает, что
для обращения к данным в ASP .NET могут использоваться все элементы и вся программная
поддержка баз данных .NET (см. главу И).
При нажатии
клавиши F5 VS .NET IDE генерирует web-страницу и автоматически отображает ее
в Internet Explorer. После нажатия кнопки окно приобретает вид, показанный на
рис. 12.2.
Приложения
ASP .NET, как и другие классы приложений .NET, компилируются в би-блиотеки DLL.
IDE генерирует для DLL файл описания сборки, хранящийся на сервере. В приложение
ASP .NET также входит страница .aspx и другие сопутствующие файлы.
Ниже приведен
полный код страницы с разверткой регионов:
Public Class
WebForml
Inherits System.Web.UI.Page
Protected WithEvents Labell As System.Web.UI.WebControls.Label
Protected WithEvents
Buttonl As System.Web.UI.WebControls.Button #Region "Web Form Designer
Generated Code "
'This call is required by the Web Form Designer. <System.Diagnostics.DebuggerStepThrough()>
Private Sub _
InitializeComponent()
End Sub
Private Sub
Page_Init(ByVal
sender As System.Object.
ByVal e As System.EventArgs)
Handles MyBase.Init
'CODEGEN: следующий
вызов необходим для дизайнера форм Web.
' Не изменяйте
его в редакторе!
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object._
ByVal e As System.EventArgs)
Handles MyBase.Load
' Здесь размещается пользовательский код инициализации страницы
End Sub
Private Sub Bultonl_Click(ByVal sender As System.Object._
ByVal e As System.EventArgs) Handles Buttonl.Click Me.Label1.Font.Size_
FontUnit.XLarge Me.Label1.Text = "Welcome to ASP .NET @" & Now
End Sub
End Class
Рис.
12.2. Результат выполнения простейшего кода ASP .NET
В ASP .NET
используется файл globalasax — аналог файла global.asa из ASP. Главное различие
между этими файлами заключается в том, что обращения к файлу global.asax происходят:
Если
вы захотите добавить в global.asax код инициализации приложения, включите его
в функцию InitializeComponent(), поскольку именно эта функция вызывается при
загрузке приложения.
Сценарии
ASP .NET программируются в обычном стиле VB .NET, однако в зависимости от
типа клиентского броузера генерируется разный код HTML. Например, если клиент
работает в последней версии Internet Explorer, в сгенерированном коде используются
конструкции DHTML, а интервальная проверка осуществляется на стороне клиента.
Но если в качестве броузера используется сотовый телефон с поддержкой WAP (Wireless
Application Protocol), будет сгенерирован код WML (версия HTML для этой платформы),
а все необходимые проверки будут выполняться сервером. И все это происходит
автоматически, совершенно не требуя особых действий со стороны программиста![Если,
конечно, вы не займетесь разработкой нестандартных элементов для форм Web —
в этом случае вам придется изрядно потрудиться. Элементы форм ^Veb должны знать,
какой код следует генерировать для каждой конкретной платформы.]
Ниже приведен
код предыдущего примера, сгенерированный для клиентского броузера Internet Explorer,
работающего в Windows XP. Ключевые строки выделены жирным шрифтом:
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML>
<HEAO>
<title></title>
<meta name="GENERATOR"content="Microsoft
Visual Studio.NET 7.0">
<meta name="CODE_LANGUAGE"content="Visual
Basic 7.0">
<meta name="vs_defaultClientScnpt"content="JavaScnpt">
<meta name="vs_targetSchema"
content="http://schemas.microsoft.com/intel1isense/ie5">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form name="Forml"
method="post" action="WebForml.aspx" id="Forml">
<input type="hidden"
name="_VIEWSTATE" value="dDwxMDA3MzE2MzEy0zs+"/>
<input type="subm1t"
name="Buttonl" value="Click me!" id="Buttonl"
style="height:67px;width:123px;Z-INDEX:
101: LEFT :311px:
POSITION:absolute;TOP:212px"/>
<span id="Labell"style="height:132px:width:631px:Z-INDEX:102:
LEFT:15px;POSITION:absolute:TOP:40px"></span>
</form>
</body>
</HTML>
Из выделенного
фрагмента видно, что в сгенерированный для клиентской стороны HTML-код включена
форма HTML с атрибутом post и скрытым полем _VIEWSTATE. Эти строки позволяют
ASP .NET сохранять информацию состояния, не требуя специальных действий со стороны
клиента. Скрытое поле _VIEWSTATE содержит зашифрованные данные, по которым ASP
.NET может восстановить страницу и ее состояние. Механизм шифрования представляет
собой особую разновидность сериализации; чтобы отключить сохранение состояния,
задайте свойству ЕпаЫе-ViewState значение False.
Чтобы лучше
понять, как происходит сохранение состояния, нажмите кнопку и снова просмотрите
исходный текст. На этот раз ключевые строки HTML-кода будут выглядеть примерно
так:
<form name="Forml"
method="post" action="WebForml.aspx" id="Forml">
<input type="hidden"
name="_VIEWSTATE"
value="dDwxMDA3MzE2MzEy03Q802w8aTwxPjs+
02w8dDw7bDxpPDM+Oz47bDxOPHA,
8cDxsPEZvbnRfU216ZTtUZXh0018hUOI7PjtsPFN5
c3RlbS5XZWIuVUkuV2Vi029udHJvbH
MuRm9udFVuaXQsIFN5c3RlbS5XZWIsIFZlcnNpb
249MS4wLjIOMTEuMCwgQ3VsdHVyZT
luZXVOcmFsLCBQdWJsaWNLZXlUb2tlbjliMDNmN
WY3ZjExZDUwYTNhPFgtT6FyZ2U+0
ldlbGNvbWUgdG8gQVNQLk5FVCBAOC8xOS8yMDAx
IDEyOjM20jAwIFBN02k8MTQwOT
47Pj47Pjs7Pjs+Pjs+Pjs+"/>
Хотя базовый
файл .aspx, указанный в атрибуте тега <form>, остался прежним, скрытая
переменная _VIEWSTATE изменилась весьма основательно. Фактически в этом поле
сохранено полное состояние элементов HTML и данных формы. Одно из преимуществ
этого подхода заключается в том, что программист избавляется от хлопот с сохранением
состояния. Он просто задает свойству EnableViewState значение True и переходит
к программированию логики страницы. С другой стороны, с каждой страницей приходится
пересылать дополнительные данные. В большинстве случаев их объем относительно
невелик, поэтому преимущества компенсируют недостатки.
Элементы
ввода (тег <input>) на стороне клиента всегда запоминают свое состояние
даже после пересылки данных на сервер и обратно. ASP .NET не позволяет отключать
автоматическое сохранение состояния для элементов ввода.
Наконец,
у каждой страницы .aspx имеется свойство Sessi on, возвращающее объект с информацией
о текущей странице. Объект Session можно рассматривать как своего рода «cynepcookie»
с возможностью сохранения данных по ключу (как в хэш-таблицах). Пример:
Session("user
name") = TextBox1.Text
Содержимое
текстового поля TextBoxl сохраняется в объекте Session, а при обращениях к -нему
используется строка "user name".
Нехватка
места не позволяет развивать эту тему, однако мы хотим обратить внимание читателя
на одно обстоятельство. В особо сложных ситуациях, когда сохранение всех данных
в объекте Session, находящемся в памяти сервера, нежелательно, информация сохраняется
в базе данных SQL Server. Более того, если сайт обслуживается web-комплексом,
вы даже можете указать, на каком сервере должна храниться эта информация! Эти
две особенности значительно улучшают масштабируемость приложений ASP .NET.
В ранних
версиях Windows конфигурационные данные хранились в ini-файлах, на смену которым
пришел глобальный реестр. В ASP .NET приложения фактически
возвращаются к временам текстовых ini-файлов — конфигурационные данные хранятся
в текстовом файле Web.config, находящемся в каталоге приложения. Этот файл определяет
условия выполнения приложений ASP .NET — такие как параметры отладки и системы
безопасности. Конфигурационные файлы имеют довольно сложную структуру. Ниже
приведено содержимое файла Web.config для предыдущего примера:
1 <?xml version-"1.0"
encoding="utf-8"?>
2 <configuration>
3 <system.web>
4 <!--DYNAMIC
DEBUG COMPILATION
5 Set compilation
debug="true" to insert debugging symbols (.pdb
6 information)into
the compiled page.Because this creates a larger file
7 that executes
more slowly,you should set this value to true only when
8 debugging.and
to false at all other times.For more information,refer
9 to the documentation
about debugging ASP .NET files.
10 -->
11 compilation
defaultl_anguage="vb" debug="true"/>
12 <!--CUSTOM
ERROR MESSAGES
13 Set customErrors
mode="0n" or "RemoteOnly" to enable custom error
14 messages.
"Off"to disable.Add <error> tags for each of the errors
15 you want
to handle.
16 -->
17 <customErrors
mode="RemoteOnly"/>
18 <!--AUTHENTICATION
19 This section
sets the authentication policies of the application.
20 Possible
modes are "Windows". "Forms". "Passport" and "None"
21 -->
22 <authentication
mode="windows"/>
23 <!--AUTHORIZATION
24 This section
sets the authorization policies of the application.You can
25 allow or
deny access to application resources by user or role.
26 Wildcards:
"*" mean everyone, "?" means anonymous (unauthenticated)
27 users.
28 -->
29 <authorization>
30 <allow
users- "*" /><!-- Allow all users -->
31 <!--<allow
users="[comma separated list of users]"
32 roles="[comma
separated list of roles]"/>
33 <deny
users="[comma separated list of users ]"
34 roles="[comma
separated list of roles]"/>
35 -->
36 </authorization>
37 <!--APPLICATION-LEVEL
TRACE LOGGING
38 Application»level
tracing enables trace log output for every page within
39 an application.Set
trace enabled= "true"to enable application trace
40 logging.If
pageOutput- "true",the trace information will be displayed at
41 the bottom
of each page.Otherwise,you can view the application trace
42 log by browsing
the "trace.axd"page from your Web application root.
43 -->
44 <trace
enabled- "false" requestLimit = "10"
45 pageOutput
= "false" traceMode = "SortByTime"
46 localOnly-
"true" />
47 (--SESSION
STATE SETTINGS
48 By default
ASP .NET uses cookies to identify which requests belong to a
49 particular
session.If cookies are not available.a session can be
50 tracked by
adding a session identifier session.To disable cookies.set
51 sessionState
cookieless = "true"'
52 -->
53 <sessionState
54 mode="InProc"
55 stateConnectionString
- "tcpip=127.0.0.1:42424"
56 sqlConnectionSthng
= "data source=127.0.0.1:user id=sa:password="
57 cookieless="false"
58 timeout="20"
59 />
60 <!--PREVENT
SOURCE CODE DOWNLOAD
61 This section
sets the types of files that will not be downloaded.As
62 well as entering
a httphandler for a file type.you must also *
63 associate
that file type with the xspisapi.dll in the App Mappings
64 property
of the Web site.or the file can be downloaded.lt is
65 recommended
that you use this section to prevent your sources from
66 being downloaded.
67 -->
68 <httpHandlers>
69 <add verb=
"*" path= "*.vb"
70 type= "System.Web.HttpNotFoundHandler.System.Web"/>
71 <add verb="*"
path = "*.cs"
72 type= "System.Web.HttpNotFoundHandler.System.Web"/>
73 <add verb="*"
path="*.vbproj"
74 type= "System.Web.HttpNotFoundHandler.System.Web"/>
75 <add verb="*"
path="*.csproj"
76 type= "System.Web.HttpNotFoundHandler.System.Web"/>
77 <add verb="*"
path-"*.webinfo"
78 type= "System.Web.HttpNotFoundHandler.System.Web"/>
79 </httpHandlers>
80 <!--GLOBALIZATION
81 This section
sets the globalization settings of the application.
82 -->
83 <globalization
requestEncoding= "utf-8" responseEncoding="utf-8"/>
84 </system.web>
85 </configuration>
Из строки
1 видно, что страницы ASP .NET, как и многие объекты .NET, строятся на
базе XML. В строках 2-11 содержится часть конфигурационного файла, которая управляет
настройками компиляции и определяет режим использования страницы — тестирование/разработка
или нормальная работа. В этой части файла также указываются языки, использованные
в странице (как видно из строки И, в приведенном примере это VB).
При
переводе приложения в рабочий режим установите в файле Web.config параметр debug=false.
Отладочный режим играет важную роль в процессе разработки, но на стадии использования
он может серьезно замедлить работу приложения ASP .NET — в некоторых случаях
на порядок и даже более.
Следующий
раздел относится к проверке привилегий пользователя (строки 18-36). В приведенном
листинге параметрам аутентификации присвоено значение «*»; это
означает, что работа с приложением разрешена любому пользователю. Как видно
из автоматически сгенерированных комментариев к этому разделу, вы также можете
разрешить или запретить доступ к приложению при помощи ключевых слов allow и
deny.
Хорошая схема
аутентификации занимает важное место в программировании распределенных приложений.
Каким образом страница узнает, кем является ее пользователь? В ASP .NET поддерживаются
три разновидности схем аутентификации, перечисленные в табл. 12.1.
Таблица
12.1. Схемы аутентификации в ASP .NET
Схема аутентификации |
Описание |
||
Windows | Используется встроенная схема аутентификации IIS (на экране появляется диалоговое окно для ввода имени и пароля). Пользователь должен иметь учетную запись на данном компьютере | ||
Forms | Наиболее распространенная форма аутентификации. После успешной регистрации сервер генерирует cookie, автоматически включаемое в заголовок сообщения на протяжении сеанса. При настройке этой схемы аутентификации указывается имя регистрационной формы и управляющая ею страница ASP .NET | ||
Passport | Новая схема аутентификации, активно внедряемая компанией Microsoft | ||
Первые
две схемы вполне стандартные, только третья относительно нова. Поиск на сайте
Googte показывает, что на момент написания книги существовали тысячи web-страниц
с обсуждением достоинств и недостатков схемы аутентификации Microsoft Passport.
При желании вы можете самостоятельно изучить эту тему и принять собственное
решение.
Помните,
что при любой схеме аутентификации HTTP остается текстовым протоколом, поэтому
информация передается клиенту в незашифрованном виде и может быть похищена методом
перехвата пакетов (packet sniffing). Для борьбы с перехватом используется транспортный
механизм SSL (Secure Socket Layer).
Классы
.NET WebRequest и WebResponse автоматически используют SSL для URL, начинающихся
с префикса «https».
Строки 47-59
управляют состоянием сеанса. В большинстве случаев используются стандартные
механизмы ASP .NET, обладающие достаточно мощными возможностями. Начиная со
строки 60 и до конца файла реализуется одна занятная возможность ASP .NET, представляющая
особый интерес для тех, кто хочет защитить свою интеллектуальную собственность.
В этом разделе приводится список типов файлов, которые не должны приниматься
клиентом с сервера.
Как упоминалось
в главе 9, непосредственное извлечение информации из web-страниц — процесс медленный
(из-за необходимости анализировать всю страницу) и ненадежный, поскольку структура
страницы может измениться. Удобным средством получения таких данных с web-сайта
является web-служба (Web service).
Иначе говоря,
сайт предоставляет свою функциональность средствами, с которыми можно работать
в программах (с точки зрения программиста VB сайт, на котором работает web-служба,
напоминает компонент, который предоставляет свою функциональность программе).
Выражаясь
точнее, web-служба представляет собой функциональную возможность сервера, с
которой клиент работает при помощи HTML, XML и стандартных протоколов Web.
В .NET создание
web-служб, используемых в клиентских программах, становится делом почти элементарным.
В сущности, для этого достаточно определить класс .NET и пометить его члены,
доступные через web-службу, атрибутом <WebMethod( )>. Рассмотрим простой
пример — допустим, мы создаем web-службу для возвращения информации о погоде.
Для
простоты в нашем примере возвращаемые данные жестко кодируются в функции GetWeather.
Создайте
новый проект web-службы, для чего следует выбрать значок ASP .NET Web Service
в диалоговом окне New Project. Результат показан на рис. 12.3.
Рис.
12.3. Проект web-службы в IDE
Дважды щелкните
на дизайнере и обратите внимание на автоматически сгенерированный код:
Public Class
Servicel
Inherits System.Web.Services.WebService
Класс System.
Web. Services. WebServi се является базовым для всех web-служб .NET. Благодаря
наследованию в вашем распоряжении оказываются все возможности этого класса,
в том числе и свойство Context для получения запроса HTTP, использованного для
обращения к странице через Web.
Включите
следующий фрагмент перед командой End Class:
<WebMethod()>Public Function GetWeather(ByVal City As String)
As String Select
Case City
' Получить информацию о погоде в Сиэттле
Case "Seattle"
Return "The
current temperature is 64 degrees. " & _
"and raining of course."
Case Else
Return "Can't find data for " & City & "."
End Select
End Function
При нажатии
клавиши F5 VS .NET IDE автоматически генерирует web-страницу наподобие показанной
на рис. 12.4. На этой странице приводится общая информация о web-службе.
Рис.
12.4. Автоматически сгенерированная страница с описанием web-службы
При
создании web-службы VS.NET IDE автоматически генерирует XML-файл с описанием
службы, написанный на языке WSDL (Web Service Language Description). Программисты
COM могут рассматривать его как аналог библиотеки типов. Редактирование сгенерированного
файла .vsdisco позволяет изменить информацию о web-службе, содержащуюся в файле
WSDL. В частности, рис. 12.4 был получен на основании кода WSDL.
Использование
web-службы на стороне клиента
Если щелкнуть
на ссылке GetWeather на рис. 12.4, в броузере загружается страница, показанная
на рис. 12.5. На странице приведен код, который может использоваться для обращения
к web-службе. В разделе «SOAP» описывается доступ к службе через
протокол SOAP, основанный на XML. Этот протокол отличается наибольшей гибкостью,
но простым его не назовешь. В простейшем варианте обращения к web-службе используется
запрос HTTP GET. Прототип выглядит следующим образом:
/WebServicel/Servicel.asmx/
GetWeather?city=string НTTР/1.1
Host:Local Host
Рис.
12.5. Простейший вариант использования web-службы
Введите в
текстовом поле строку Seattle и нажмите кнопку Invoke. Примерный вид страницы
показан на рис. 12.6.
Рис.
12.6. Результаты обращения к web-службе
Результат
представлен в формате XML, что позволяет легко проанализировать данные в программе.
Также обратите внимание на то, что в автоматически сгенерированном коде показано,
как обращаться к web-службе за пределами IDE. Для этого необходимо лишь сгенерировать
правильный запрос HTTP GET или SOAP. Ниже приведен пример построения запроса
GET в консольном приложении, использующем для отправки запроса GET классы WebRequest
и WebResponse пространства имен System.Net:
1 Imports System.Net
2 Imports System.I0
3 Module Module1
4 Sub Main()
5 Dim myResponse
As WebResponse
6 Try
7 Dim myWebServiceRequest
As WebRequest
8 myWebServiceRequest
- WebRequest.Create _
9 ("http://localhost/WebServicel/Servicel.
asmx/GetWeather?dty=SeattIe")
10 myResponse
= _
11 myWebServiceRequest.GetResponse()
12 Dim theAnswer
As String
13 Dim aStream As New StreamReader
(myResponse.GetResponseStream)
14 theAnswer
= aStream.ReadToEnd
15 MsgBox(theAnswer)
16 Catch e As
Exception
17 Console.WriteLine(e.Message)
18 Finally
19 myResponse.
Close()
20 End Try
21 End Sub
22 End Module
Ключевая
роль в этом листинге принадлежит строке 8 (продолжающейся в строке 9), в которой
серверу передается запрос GET. Как было показано в главе 9, результат представляет
собой поток данных, используемый для построения StreamReader (строка 13). Строка
14 читает в строковую переменную весь текст потока. Строка 19 закрывает объект
запроса HTTP и освобождает все связанные с ним ресурсы. Кстати, переменная
myResponse была объявлена в строке 5 именно потому, что при объявлении ее в
блоке Try (строки 6-15) переменная оказалась бы недоступной для секции Fi nal
ly. Результат выполнения программы показан на рис. 12.7.
Рис.
12.7. Результат обращения к web-службе с использованием запроса GET
С запросами
SOAP дело обстоит несколько сложнее. Вряд ли кому-нибудь захочется генерировать
их вручную. Вместо этого можно воспользоваться командой Project > Add
Web Reference или утилитой командной строки wsdl.exe, входящей в поставку .NET
Framework. Оба варианта приводят к одному результату — генерируется вспомогательный
класс-посредник, который используется в программе.
Пожалуй,
решение с утилитой командной строки отличается большей гибкостью. Ниже показано,
как выглядела командная строка в нашем случае. Хотя приведенный пример разбит
на две строки, его следует ввести в одной строке:
"С:\Program Fi1es\Microsoft.NET\FrameworkSDK\Bin\wsdl"/language:VB"
http://localhost/WebServicel/Servicel.asmx?wsdl
При запуске
с ключом /language: VB утилита создает файл с кодом вспомогательного класса
Servicel.vb, по умолчанию находящийся в одном каталоге с wsdl.exe (выходной
каталог задается ключом out). Основной код сгенерированного класса выглядит
так (ключевые строки выделены жирным шрифтом):
Option Strict
Off
Option Explicit
On
Imports System
Imports System.Diagnostics
Imports System.Web.Services
Imports System.Web.Servi
ces.Protocols
Imports System.Xml.Serialization
'This source code was auto-generated by wsdl,Version=l.0.2914.16.
<System.Web.Servi ces.WebServi ceBi ndi ngAttri bute(Name:="ServicelSoap". [Namespace ]:="http://tempuri,org/")> _
Public Class
Servicel
Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
<System.Diagnostics.DebuggerStepThroughAttri
bute()> _
Public Sub New()
MyBase.New Me.Url ="http://localhost/WebServicel/Servicel.asmx"
End Sub
<System.Diagnostics.DebuggerStepThroughAttri
bute().
System.Web.Services.Protocols.
SoapDocumentMethodAttri bute _
("http://tempuri.org/GetWeather".
Use:=System.Web.Services.Description.
SoapBindingUse.Literal.
ParameterStyle:=System.Web.Services.
Protocols.SoapParameterStyle.Wrapped)>
_
Public Function GetWeather(ByVal city
As String)As
String
Dimresults() As Object=Me.Invoke
("GetWeather". New Object 0 {city})
Return CType(results(0).
String)
End Function
<System.Diagnostics.
DebuggerStepThroughAttribute()>
_
Public Function
BeginGetWeather(ByVal city As String._
ByVal callback As System.AsyncCallback.
ByVal asyncState As Object) As System.IAsyncResult
Return
Me.Beginlnvoke("GetWeather",
New Object()
{city}.call back.asyncState)
End Function
<System.Diagnostics.DebuggerStepThroughAttributet)> _
Public Function
EndGetWeather(ByVal asyncResult
As System.IAsyncResult) As String
Dim results()As Object = Me.EndInvoke(asyncResult)
Return
CType(results(0), String)
End Function
End Class
Затем в проект
включается код класса (или ссылка на него) и ссылки на сборки System. Web, System.
XML и System. Web.Services. Остается лишь создать экземпляр вспомогательного
класса и вызвать функцию GetWeather!
Теперь, когда
вы знаете, как получить результаты обращения к web-службе, нетрудно представить
себе следующие возможные шаги:
Перед нами одно из проявлений той концепции, которую сейчас активно внедряет Microsoft, — Web как глобальная сеть, через которую пользователь легко получает доступ к любым необходимым данным.
Когда тот или иной физик использует понятие "физический вакуум", он либо не понимает абсурдности этого термина, либо лукавит, являясь скрытым или явным приверженцем релятивистской идеологии.
Понять абсурдность этого понятия легче всего обратившись к истокам его возникновения. Рождено оно было Полем Дираком в 1930-х, когда стало ясно, что отрицание эфира в чистом виде, как это делал великий математик, но посредственный физик Анри Пуанкаре, уже нельзя. Слишком много фактов противоречит этому.
Для защиты релятивизма Поль Дирак ввел афизическое и алогичное понятие отрицательной энергии, а затем и существование "моря" двух компенсирующих друг друга энергий в вакууме - положительной и отрицательной, а также "моря" компенсирующих друг друга частиц - виртуальных (то есть кажущихся) электронов и позитронов в вакууме.
Однако такая постановка является внутренне противоречивой (виртуальные частицы ненаблюдаемы и их по произволу можно считать в одном случае отсутствующими, а в другом - присутствующими) и противоречащей релятивизму (то есть отрицанию эфира, так как при наличии таких частиц в вакууме релятивизм уже просто невозможен). Подробнее читайте в FAQ по эфирной физике.