Немного истории
Технология ASP
появилась в 1997 году и
предназначалась для построения web-страниц
в Internet Information Server (US). В сценариях ASP
HTML-код объединялся со сценарным
кодом, интерпретируемым IIS в ответ
на запросы со стороны клиента. В
результате строилась страница HTML, которая возвращалась клиенту. Технология ASP обладала рядом недостатков:
- быстродействие
сценариев оставляло желать
лучшего, поскольку в основу ASP
была заложена интерпретация
кода на стороне сервера;
- разработка
и сопровождение сценариев
затруднялись тем, что
представление страницы не
отделялось от управляющего
кода;
- сложности
с масштабированием, поскольку
страницы ASP не сохраняли
текущее состояние сеанса при
переходе на другие серверы web-комплекса
или после перезапуска;
- отсутствие
нормальной модели
безопасности.
Эти и другие
проблемы решаются в новой
технологии 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.
Ниже приведен
полный код страницы с разверткой
регионов:
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
происходят:
- в начале каждого запроса;
- при
возникновении ошибки;
- при
попытке аутентификации
пользователя (процесс
аутентификации
рассматривается ниже).
Простая web-служба
Как упоминалось
в главе 9, непосредственное
извлечение информации из web-страниц
— процесс медленный (из-за
необходимости анализировать всю
страницу) и ненадежный, поскольку
структура страницы может
измениться. Удобным средством
получения таких данных с web-сайта
является web-служба (Web service).
Иначе говоря,
сайт предоставляет свою
функциональность средствами, с
которыми можно работать в
программах (с точки зрения
программиста VB сайт, на котором
работает web-служба, напоминает
компонент, который предоставляет
свою функциональность программе).
В .NET создание web-служб,
используемых в клиентских
программах, становится делом почти
элементарным. В сущности, для этого
достаточно определить класс .NET и
пометить его члены, доступные через
web-службу, атрибутом <WebMethod( )>.
Рассмотрим простой пример —
допустим, мы создаем web-службу для
возвращения информации о погоде.
Создайте новый
проект 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-службы на стороне клиента
Если щелкнуть
на ссылке 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-службе, нетрудно
представить себе следующие
возможные шаги:
- объединение результатов нескольких обращений к web-службам в одном файле;
- применение к результату запроса преобразований XSL и построение новых страниц с HTML-кодом при помощи web-служб, работающих на разных сайтах.
Перед
нами одно из проявлений той
концепции, которую сейчас активно
внедряет Microsoft, — Web как глобальная
сеть, через которую пользователь
легко получает доступ к любым
необходимым данным.