Сайт Алексея Муртазина (Star Cat) E-mail: starcat-rus@yandex.ru
Мои программы Новости сайта Мои идеи Мои стихи Форум Об авторе Мой ЖЖ
VB коды Статьи о VB6 API функции Самоучитель по VB.NET
Собрания сочинений Обмен ссылками Все работы с фото и видео
О моём деде Муртазине ГР Картинная галерея «Дыхание души»
Звёздный Кот

Самоучитель по VB.NET
Глава 14.

Интернет-приложения и службы

Я ненадолго прерву нормальное повествование и обращусь к конкретной группе читателей, к тем, кто не читал предыдущих глав, а сразу открыл книгу на этой странице, желая узнать, что в этой книге говорится о web-приложениях и службах и почему эта тема рассматривается только в конце.

Да, я обращаюсь к тем, кто просматривает книгу в магазине и пытается понять, что он держит в руках — серьезную профессиональную книгу о VB .NET или халтурную поделку, призванную заработать на модной теме?

Чтобы ответить на ваш вопрос, позвольте мне задать свой.

 

Что такое Microsoft .NET?

Ответ зависит от того, кому адресован этот вопрос.

Попробуйте спросить, что такое ActiveX, COM — а еще лучше Windows DNA? Вы услышите множество определений.

.NET захлестнул тот же поток маркетинговых статей, недостоверных и обрывочных сведений, вольных интерпретаций и неразберихи, от которого пострадали многие инициативы Microsoft. He думаю, что вы получите сколько-нибудь вразумительный ответ от сотрудников Microsoft — их ответы слишком сильно зависят от должности и от того, какую презентацию PowerPoint им показали последней.

Например, недавно я говорил с одним специалистом по маркетингу, который искренне считал, что Biztalk 2000 является существенной, неотъемлемой частью Microsoft .NET.

Конечно, это такая же важная составляющая общей стратегии Microsoft .NET, как .NET Enterprise Services (отчасти это Windows DNA под новым названием) и таинственный проект Hailstorm. Однако это вовсе не означает, что все эти составляющие абсолютно необходимы для работы с .NET — более того, это попросту неверно.

Насколько я понимаю, основной круг читателей этой книги складывается из программистов и менеджеров, организующих их работу. Определение .NET с точки зрения программиста было приведено в главе 4 — новая виртуальная машина, для которой мы программируем1.

Но какое место в этом определении занимает Интернет?

Со стратегических и маркетинговых позиций .NET выражает взгляд Microsoft на будущее Интернета — похоже, ярлык «.NET» будут лепить ко всему, что имеет сколько-нибудь отдаленное отношение к Интернету. С точки зрения программиста, Microsoft .NET представляет собой виртуальную машину, благодаря которой Интернет-программирование должно стать таким же простым, как традиционное программирование для Windows.

Я не буду тратить время на дальнейшие поиски определения Microsoft .NET — все равно определение (или по крайней мере стратегические приоритеты) завтра изменится. Для нас .NET — это прежде всего инструментарий программирования и архитектура, и Интернет-программирование занимает в этой картине далеко не последнее место.

Причина, по которой я не упоминал об этом до настоящего момента, проста: практически все, о чем говорилось в книге (за исключением главы 13), в равной степени относится и к Интернет-программированию в VB .NET.

Итак, вы просто листаете книгу, интересуясь, почему автор так долго откладывал тему Интернет-программирования? Надеюсь, вы поняли, что вам абсолютно необходимо вернуться к началу и прочитать все предыдущие главы — только так можно понять концепции, необходимые для программистов VB .NET в любой области — как в Интернет-программировании, так и в традиционном программировании для Windows.

1Имеется в виду виртуальная машина в классическом понимании, то есть совокупность требований и условий разработки программного обеспечения. Существует и другая трактовка виртуальной машины как специализированного эмулятора (пример — виртуальная машина Java).

Программирование для Интернета

Чтобы понять сущность Интернет-программирования, необходимо капитально разобраться в концепции Интернета с точки зрения Microsoft. Но прежде чем объяснять, в чем же эта концепция состоит, я хочу особо подчеркнуть одно важное обстоятельство: она не является неотъемлемой частью .NET. Microsoft .NET — инструмент, разработанный для реализации этой концепции, однако он с таким же успехом может применяться для реализации других идей (в том числе и ваших собственных).

Подход Microsoft к Интернету на самом деле прост и основан на одной принципиальной идее (которая, впрочем, никогда не высказывается вслух): Web в своем текущем состоянии никуда не годится.

Да, я знаю, что это звучит кощунственно, но выслушайте мои аргументы.

Во времена создания Web существовало несколько файловых форматов, которые прекрасно справлялись с воспроизведением текста и графики. Например, формат RTF (Rich Text Format) поддерживался большинством текстовых редакторов, а формат Adobe PDF позволял воспроизводить сложные документы в одинаковом виде практически на любом компьютере. Что же мы имеем сегодня?

HTML — стандарт, который не позволяет одинаково воспроизвести страницу в разных версиях одного и того же браузера, не говоря уже о разных1.

Что еще хуже, информация web-страниц перемежается с командами форматирования. Программе становится очень трудно извлечь нужную информацию из нагромождения форматных тегов. А поскольку web-сайт практически в любой момент может измениться, практически невозможно написать программу, позволяющую сколько-нибудь надежно читать данные с web-страниц.

Посмотрим, что происходит в области программирования. Сценарии ADP (Active Server Pages) содержат самую невероятную мешанину, которую только можно себе представить. Здесь и HTML-код, готовый для передачи клиенту, клиентские и серверные сценарные команды, следующие в непредсказуемом порядке. Многие из виденных мной сценариев ASP отличались крайне запутанной логикой, при виде которой вспоминалось «спагетти-программирование» и команда Goto. Где правила объектно-ориентированного программирования? Где принцип отделения пользовательского интерфейса от программного кода, позволяющий дизайнеру изменить страницу без помощи программиста, и наоборот?

Новые тенденции в web-программировании (в том числе и Microsoft .NET) наконец-то станут шагом в нужном направлении.

1Возможно, я преувеличиваю — но совсем немного.

 

XML

XML2. Название выглядит устрашающе. Похоже, нужно скорее бежать в магазин за новой толстой книгой. А может, у вас уже есть такая книга?

Возможно, для описания всех тонкостей XML действительно нужна большая книга (хотя я в этом сомневаюсь), но для его практического использования ничего такого не потребуется. XML — всего лишь файловый формат для хранения данных. Используемые в нем теги внешне напоминают теги HTML, однако теги XML определяют произвольные имена полей данных, а между начальным и конечным тегом находится значение указанного поля.

2Extensible Markup Language.

Ниже приведен простой пример: база данных в формате XML из проекта SimpleXML.

<?xml version="1.0" encoding="utf-8" ?> <?xml-stylesheet type="text/xsl"

  href="BillingExample.xslt"?> 

<BHlingTable>

<Heading>BiUing records</Heading>

 <data> 

<record>

<narae>Dan</name>

 <hours>5</hours>

<description>First job</description>

 </record> 

<record>

<name>Jill</name>

 <hours>3.2</hours>

<description>Second jot></description 

</record>

 </data>

 </BillingTable>

Нужно ли еще что-нибудь объяснять? Средства XML позволяют создать иерархическую структуру данных при помощи тегов, идентифицирующих фрагменты данных в файле.

Итак, XML описывает данные. Особая разновидность файлов XML — так называемые файлы XSL1— описывает способ просмотра этих данных.

Файл XSL предназначен для преобразования данных XML в другую форму, в данном случае — в формат HTML2. Файл BillingExample.xsIt указан в файле BillingExample.XML в качестве списка стилей (style sheet) — файла, описывающего параметры отображения файла XML. Файл BillingExample.xsIt приведен в листинге 14.1.

Листинг 14.1. Файл BillingExample.xsIt3

 <?xml version="1.0" encoding="UTF-8" ?> 

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output method="html" /> 

<xsl:template match="/"> 

<HTML> 

<Head>

 <Body>

 <hl>

<xsl:value-of select="//BillingTable/Heading" /> 

</hl>

<table border="l" width="106%"> 

<xsl:for-each select="//data/record"> 

<tr>

 <td>

<xsl:value-of select="name" /> 

</td>

<td>

<xsl:value-of select="hours" /> 

</td>

 <td>

<xsl:value-of select="description" />

 </td> 

</tr>

</xsl:for-each> </table> 

</Body>

 </Head>

 </HTML>

</xsl:template> 

</xsl:stylesheet>

1Extensible Stylesheet Language (или XSLT от слов «XSL Transform»).

2XSL также может использоваться для преобразования XML в другие форматы. В сущности, работа Biztalk основана на применении XML в качестве промежуточного формата для преобразования данных из практически любого исходного формата в практический любой итоговый формат.

3Все исходные тексты можно найти на сайте издательства «Питер» www.piter.com. —Примеч. ред.

Теги, начинающиеся с префикса xsl:, представляют команды XSL, интерпретируемые в процессе преобразования в соответствии со спецификацией XSL. В остальных тегах находится непосредственно выводимый код HTML. Тег «xsl:value-of» производит замену: данные, указанные в теге, читаются из файла XML и записываются в выходные данные HTML.

На следующем рисунке показано, как файл XML выглядит в виде web-страницы в Internet Explorer.

Файл XSL содержит все теги, необходимые для отображения файла XML в нужном формате.

XML является промышленным стандартом. Это означает, что Microsoft может влиять на развитие XML, но не обладает правами на него. Решение Microsoft взять на вооружение и интегрировать XML выглядит весьма впечатляюще, особенно учитывая традиционную тягу Microsoft к установлению собственных стандартов.

XML помогает отделить данные в Интернете от их визуального представления. Позднее в этой главе будет показано, как проблема разделения функциональности web-сайта и его внешнего вида решается в ASP .NET.

 

Распределенные приложения

В этой книге я постарался уделять особое внимание тем принципам, на которых основана работа программного кода. Если вы понимаете базовые принципы тех языков и программных инструментов, с которыми вы работаете, найти подробности реализации в документации Microsoft относительно просто. Размышляя над тем, о чем следует написать в этой главе, я был несколько растерян. Эта тема тоже заслуживает отдельной книги (уверен, что даже сейчас к печати готовится немало книг, посвященных ASP .NET и Интернет-программированию в VB .NET). К тому же я не хотел пересказывать материал, который можно (и нужно) найти в документации Microsoft. Что делать?

Ответ нашелся в тот момент, когда я начал писать примеры программ. Подлинная суть Интернет-программирования в .NET заключается не в web-службах, ASP .NET, XML или другой конкретной технологии, а в подходе к написанию приложения.

Когда-то в прошлом типичная программа представляла собой отдельный исполняемый файл (иногда с библиотеками или оверлейными модулями). Позднее вошло в моду программирование «клиент-сервер» — отделение пользовательского интерфейса от уровня операций с базами данных. Затем появилась «трехуровневая архитектура», в которой выделялись уровни пользовательского интерфейса, промежуточный уровень с бизнес-логикой и уровень базы данных. Клиенты разделились на «тонких» и «толстых»: «толстый» клиент обладал расширенным пользовательским интерфейсом, при распространении и запуске которого на клиентском компьютере иногда возникали проблемы; «тонкий» клиент обладал бедным интерфейсом, но зато его распространение происходило относительно легко1.

Каждое из этих новомодных веяний немедленно объявлялось новейшим и лучшим решением всех задач. Издательства выпускали десятки томов, посвященных новой архитектуре, а программисты пытались понять, какое отношение новая архитектура имеет к их конкретным задачам.

Наконец я понял, о чем следует написать эту главу (и чего нет в документации Microsoft). В ней должно содержаться основательное введение в распределенные приложения с освещением их роли в .NET Framework.

Итак, предположим, некая вымышленная компания платит своим сотрудникам по повременному тарифу, для чего ей требуется точно и быстро получать информацию о затратах рабочего времени.

В следующем разделе предложено одно из возможных решений для программистов .NET.

1По иронии судьбы так называемые «тонкие» клиенты, работающие в браузере, обычно требуют больше системных ресурсов и порождают больше проблем с установкой, чем традиционные «толстые» клиенты.

 

Подход к проектированию приложений в .NET

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

Уровень базы данных

Допустим, у организации имеется база данных с информацией о рабочем времени сотрудников. Реализация базы данных не рассматривается даже в общих чертах — эта тема выходит далеко за рамки книги. В нашем примере база данных моделируется простым набором данных в файле XML.

Все обращения к базе данных осуществляются через компонент, находящийся в каталоге BillingComponent. Этот компонент сохраняет данные в файле XML в соответствии со схемой, определяемой в файле BillingSet.xsd (листинг 14.2).

Листинг 14.2. Файл BillingSet.xsd

<?xml version="l.0" encoding="utf-8" ?> 

<xsd:schema id="BillingSet"

targetNamespace="http://tempuri.org/BillingSet.xsd"

elementFormDefault="qualifled" xmlns="http://tempuri.org/Bi11ingSet.xsd"

  xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

<xsd:element name="Bi HingTable">

 <xsd:complexType>

 <xsd:sequence>

<xsd:element name="Name" type="xsd:string" />

 <xsd:element name="Hours" type="xsd:integer" />

 <xsd:element name="Description" type="xsd:string" />

 </xsd: sequence>

 </xsd:complexType>

 </xsd:element>

 </xsd:schema>

Файл схемы (schema file) XML описывает структуру данных, но не содержит самих данных. Все элементы данных обладают сильной типизацией, что упрощает их сохранение и загрузку из файлов XML в соответствии со схемой. В данном примере схема состоит из трех полей: имя сотрудника, количество рабочих часов и описание проекта.

Класс BillingComponent (листинг 14.3) используется при всех обращениях к базе данных. В реальных приложениях для разных типов операций с базой данных обычно используются разные объекты. Например, один объект специализируется на записи информации в базу и включается в приложения и компоненты, используемые сотрудниками. Другой объект специализируется на чтении информации из базы данных — вероятно, он будет использоваться в бухгалтерии.

ВНИМАНИЕ 

 Измените константу BillingXMLLocation в соответствии с местонахождением файла XML. Прежде чем запускать какие-либо примеры, не забудьте скопировать в указанный каталог файл BillingSet.xsd.

Листинг 14.3. Файл BillingComponent.vb

1Billing Component

' Copyright ©2001 by Desaware Inc. All Rights Reserved

Public omponent

Inherits System.ComponentModel.Component

' Приведите в соответствие с каталогом,

' используемым в вашей системе.

Private Const BillingXMLLocation As String = _

"d:\MovingToVBNet\Source\chl4\"

#Region " Component Designer generated code "

Public Sub New(ByVal Container As System.ComponentModel.IContainer)

 Myont>

Container.Add(Me)

 End Sub

Public Sub New() 

MyBase.New()

' Необходимо для работы дизайнера компонентов.

 Ini tializeComponentO

' Дальнейшая инициализация выполняется 1после вызова

 Initia11zeComponent(). 

OpenXML()

End Sub

' Необходимо для работы дизайнера компонентов.

 Private components As System.ComponentModel.Container

' ВНИМАНИЕ: следующий фрагмент необходим ' для работы дизайнера компонентов.

' Для его модификации следует использовать дизайнер компонентов. 

' Не изменяйте его в редакторе!

<System.Diagnostics.DebuggerStepThrough()> Private Sub

 InitializeComponent()

1BillingComponent

 End Sub 

#End Region

Private myds As New DataSet()

 Private xmllocation As String

Public Sub OpenXML()

Dim loc As String

xmllocation = BillingXMLLocation

myds.ReadXmlSchema(xmllocation & "billingset.xsd")

Try myds.ReadXml(xmllocation & "BillingData.xml")

Catch e As Exception

End Try

Dim t As DataTable

 End Sub

Public Sub AddRecord(ByVal Name As String, ByVal Hours As Double, 

ByVal Description As String)

Dim dr As DataRow

dr = myds.Tables(O).NewRow

dr.Item(O) = Name

dr.Item(l) = Hours

dr.Item(2) = Description

myds.Tables(0).Rows.Add(dr)

' Обновить набор данных

myds.AcceptChanges()

 End Sub

Public Overloads Overrides Sub Dispose()

 MyBase. Dispose()

myds.AcceptChanges()

myds.WriteXmHxml. location & "Bi llingData.xml", _

 XmlWriteMode.IgnoreSchema)

 myds.Dispose()

 End Sub

Public Readonly Property Info() As DataSet

Get

 Return myds

End Get

 End Property

End

Рассмотрим важнейшие методы этого класса.

Сразу же после создания компонент читает файл схемы XML и загружает текущий файл базы данных (если он существует). Данные загружаются в объект Dataset ADO .NET. Для обращения к объекту используется свойство Info. Объект Dataset в ADO .NET содержит «снимок» данных на некоторый момент времени, причем в нашем примере это особенно хорошо видно. База данных XML обновляется лишь в момент фактической записи при вызове Di spose.

Метод Add Record включает новую запись в базу данных.

В этом компоненте следует обратить внимание на два обстоятельства. Во-первых, этот простой пример всего лишь демонстрирует целый класс решений по низкоуровневым операциям с базами данных. Конечно, одновременное обращение нескольких пользователей к данным, хранящимся в формате XML, вызовет серьезные проблемы синхронизации. Впрочем, и такой подход может использоваться в ситуации, когда каждый пользователь работает с отдельной копией данных (маловероятно, чтобы пользователь работал с одним экземпляром данных сразу из нескольких приложений).

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

Вероятно, в .NET компонент BillingCoinponent будет находиться либо в одном каталоге с базой данных, либо на сервере, связанном с базой данных по локальной сети1. В обоих вариантах для работы с клиентом может использоваться локально установленное приложение, играющее роль традиционного «толстого клиента». Этот сценарий рассматривается в следующем разделе.

1 Компонент BillmgComponent можно настроить и для удаленного подключения к базе данных, но это потребует подробного описания средств удаленного доступа .NET. Кроме того, как будет показано ниже, у этой задачи есть и другие решения.

Традиционное клиентское приложение Windows

Приложение BillingWinApp демонстрирует стандартную ситуацию, при которой среди пользователей локальной сети распространяется специальное приложение для ввода информации в базу данных. Приложение BillingWinApp содержит ссылку на компонент BillingComponent (откройте проект BillingWinApp, включающий как компонент, так и приложение Windows). В данном примере они находятся в одной системе. Отредактируйте ссылку на базу данных в BillingComponent в соответствии с ее текущим местонахождением (или спроектируйте компонент BillingComponent с поддержкой удаленного доступа).

Код приложения очень прост. Объект Dataset с загруженными данными назначается в качестве источника данных элемента DataGrid:

Private Billinglnfo As New MovingToVBNet .Bi Uing. BillingComponent ()

/ Private Sub Forml_Load(ByVal. sender As Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

If components Is Nothing Then components = New _

 System.ComponentModeI.Container()

components.Add (Billinglnfo)

DataGridl.DataSource = Billinglnfo.Info

DataGridl.NavigateTo(0, "BillingTable")

DataGridl.CurrentRowIndex = 0

 End Sub

Особого упоминания заслуживает лишь включение компонента Billinglnfo в коллекцию компонентов формы. Поскольку с компонентом не ассоциируется собственный дизайнер, он не находится под управлением дизайнера Visual Studio и поэтому не включается автоматически в список компонентов. Включение компонента в коллекцию компонентов обеспечивает вызов его метода Dispose при вызове Dispose для формы. Вызов Dispose очень важен, поскольку в этом методе компонент Billinglnfo записывает обновленные данные XML.

Для просмотра текущего содержимого базы данных и добавления новых записей используется элемент DataGrid (рис. 14.1).

Рис. 14.1. Работа с базой данных в традиционном приложении Windows

То, что вы видели до настоящего момента, было прямым аналогом традиционной трехуровневой архитектуры с «толстым» клиентом. Но это только начало.

 

Web-приложение

Web-приложения принадлежат к числу основных новшеств Microsoft .NET и основываются на новой версии ASP (Active Server Pages), называемой ASP .NET. Между ASP и ASP .NET существуют многочисленные различия. Вероятно, самое важное из них заключается в том, что для разработки приложений ASP .NET может использоваться любой язык .NET. Иначе говоря, для написания сценариев ASP .NET вам уже не придется ограничиваться VBScript и JavaScript. Более того, сами термины «сценарии» и «сценарные языки» стали неуместными, поскольку в ASP .NET нет сценариев как таковых: выполняется полноценный код, откомпилированный для .NET. В ASP .NET поддерживаются VB .NET, C# и все остальные языки .NET.

И опытные разработчики ASP, и новички должны запомнить главный принцип Интернет-программирования в .NET:разработчики Visual Studio .NET стремились к тому, чтобы разработка web-приложений по сложности не превосходила программирование традиционных приложений Windows.

Другими словами, предполагалось, что вы сможете воспользоваться всем опытом программирования традиционных приложений Windows и применить его непосредственно к Интернет-программированию.

Следует заметить, что в целом эта задача была успешно выполнена.

При создании web-приложения вы работаете с дизайнером, очень похожим на форму Windows. Вы размещаете элементы на форме и задаете их свойства. Если дважды щелкнуть на элементе, вам будет предложено ввести код обработки событий данного элемента. Такие приложения работают практически так же, как и приложения VB, если не считать того, что пользовательский интерфейс реализуется передачей HTML-кода браузеру. Элементы управления в web-приложениях по своим возможностям несколько уступают стандартным элементам Windows, что объясняется ограниченными возможностям HTML, но в целом процесс разработки почти не отличается от программирования традиционных приложений.

Простой пример этой технологии приведен в проекте ch!4SimpleWebApp.

ВНИМАНИЕ 

Все примеры web-приложений и web-служб находятся в отдельном каталоге Webs в архиве примеров. Каждый подкаталог представляет виртуальный каталог на сервере. Чтобы установить эти примеры, создайте на сервере новые виртуальные подкаталоги и скопируйте в них необходимые файлы. Возможно, самое простое решение — создать для каждого проекта новое web-приложение или web-службу, а затем скопировать файлы примеров поверх файлов нового проекта (я успешно пользовался этим способом). Я отказался от написания сценариев или программ установки, чтобы не повредить нормальной работе вашей системы, поскольку на момент написания книги все продукты .NET существовали лишь в предварительных версиях.

Простое web-приложение

Создайте web-приложение и разместите на форме две кнопки: Webform Button и HTML Button (эти типы элементов расположены на разных вкладках панели инструментов).

Щелкните на элементе HTML Button правой кнопкой мыши и выберите в контекстном меню команду запуска на сервере.

В результате будут созданы два файла. Файл WebForml.aspx является файлом ASP .NET и загружается в браузере при помощи web-приложения. Файл WebForml.aspx содержит код обработки страницы в VB .NET.

Помните, в самом начале главы я жаловался на то, что в файлах ASP HTML-код причудливо смешивается с командами клиентских и серверных сценариев? В ASP .NET такая возможность сохраняется, однако пользователи Visual Studio без особого труда отделят интерфейсный код HTML от серверного кода, сосредоточенного в отдельном файле. Редактирование файла ASPX, содержащего визуальные компоненты, обычно производится перетаскиванием элементов на поверхности дизайнера и изменением значений их свойств. Возможно, вам вообще никогда не придется вручную редактировать файлы ASPX на уровне исходного текста.

Одно из великих преимуществ Visual Studio перед «ручным» программированием заключается в том, что программист может не думать о тегах и сгенерированном коде HTML и поручить Visual Studio всю черновую работу по связыванию событий и свойств с элементами.

Файл Webforml.aspx приведен в листинге 14.4.

Листинг 14.4. Файл Webforml.aspx

<Х@ Page Language="vb" AutoEventW1reup="false" Codebehind="WebForml.aspx.vb" 

Inner 1ts="chl4S1mpleWebApp.WebForrnl"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 

<HTML>

 <HEAD>

<tme></title>

<meta name="GENERATOR" content="M1crosoft Visual Studio.NET 7.0">

 <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> 

<meta name="vs_defaultClientScript" content="JavaScript">

 <meta name="vs_targetSchema"

content="http://schemas.rnicrosoft.com/intellisense/ie5"> 

</HEAD> 

<body>

<form id="Forml" method="post" runat="server"> 

<P>

<INPUT type="button" yalue="HtmlButton" 

id="HTMLButton"

name="Buttonl" runat="server"> 

</P> 

<asp:Button id="WebControlButton" runat="server"

Text="WebControlButton"></asp:Button>

 </form> 

</body> 

</HTML>

Как видно из листинга, файл ASPX в основном состоит из обычного кода HTML и нескольких серверных тегов с префиксом asp. В листинге 14.5 приведен модуль Webforml.aspx.vb.

Листинг 14.5. Файл Webforml.aspx.vb

Public

Inherits System.Web.UI.Page

 Protected WithEvents HTMLButton As_

Systern.Web.UI.HtmlControls.HtmUnputButton

 Protected WithEvents WebControlButton As _

Systera.Web.UI.WebControls.Button

#Region " Web Form Designer Generated Code "

' Необходимо для работы дизайнера web-форм.

<System.Diagnostics.DebuggerStepThrough()> Private Sub _

InitializeComponent()

End Sub

Protected Sub Page_Init(ByVal Sender As System.Object, _

 ByVal e As System.EventArgs) Handles MyBase.Init

'ВНИМАНИЕ: вызов метода необходим

' для работы дизайнера 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 HTMLButton_ServerClick(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles HtmlButton.ServerClick

Page.Response.Write("HTML Button was clicked")

 End Sub

Private Sub WebControlButton_Click(ByVal sender As Object,

 ByVal e As System.EventArgs) Handles WebControlButton.Click

Page.Response.Write("Web control button was clicked") 

End Sub 

End

Обратите внимание: код практически неотличим от аналогичного кода VB .NET для работы с формой приложения Windows. Главное различие заключается в том, что в качестве базового выбран класс System.Web. UI. Page вместо System.Wi ndows. Forms. Form. В остальном определения элементов выглядят практически так же.

Когда браузер запрашивает web-страницу, ASP .NET создает класс WebForml. ASP .NET вызывает методы Page_Init и Page_Load и все остальные методы, которые вы переопределяете в своей реализации, инициирует события на основании полученной информации, задает все свойства объектов (в частности, используемых элементов) и обеспечивает сохранение этих свойств, чтобы они оставались действительными на протяжении всего сеанса даже при запросе других страниц.

Как это делается?

Не знаю, да это и не важно. Просто маленькое волшебство ASP .NET, благодаря которому .NET так упрощает программирование web-приложений.

Одной из положительных сторон web-элементов является то, что они могут разрабатываться с учетом используемого браузера или генерировать базовый, платформенно-независимый HTML-код — даже при использовании серверных технологий Microsoft вы сможете сгенерировать код, совместимый с любым браузером.

В начале этого раздела я предложил разместить в дизайнере ASP .NET две кнопки из разных групп панели инструментов (HTML и Web Forms). Эти кнопки представляют два разных типа элементов, используемых в приложениях ASP .NET. В документации отмечен ряд различий между HTML-элементами и web-элементами. В частности, HTML-элементы непосредственно отображаются на теги HTML, а web-элементы обеспечивают более высокий уровень абстракции и обладают расширенными возможностями. Но главное различие проявляется при попытке открыть страницу aspx в традиционном редакторе web-страниц вроде Microsoft FrontPage1.

1Чтобы открыть файл Webform I .aspx в FrontPage или другом редакторе web-страниц, следует переименовать его в Webforml.asp.Вы увидите только кнопку HTML.

Дело в том, что теги HTML описывают стандартные элементы, а для определения web-элементов используются специальные теги, не поддерживаемые обычными редакторами HTML (в нашем примере — тег asp:Button). Редактор web-форм Visual Studio распознает эти теги и соответствующим образом воспроизводит web-элементы на форме.

Если вы предпочитаете работать во внешней программе с собственным редактором HTML, вероятно, ваш выбор будет в основном ограничиваться HTML-элементами. При использовании web-элементов теги придется вводить вручную. Кроме того, положение web-элементов должно быть согласовано с программой, чтобы она могла правильно учитывать его при выводе.

Мы подошли к очень важному аспекту программирования web-приложений в Visual Studio.

Web-приложения Visual Studio разрабатывались для удобства программиста. При помощи Visual Studio вы сможете быстро создавать сложные web-приложения с минимальными затратами времени (при условии, что вы освоили общие навыки .NET-программирования, а это отнюдь не простая задача). Однако многие web-дизайнеры слабо разбираются в программировании, искренне презирают FrontPage и предпочитают работать в продуктах других фирм, например в Dream-Weaver. Вряд ли они захотят переносить свои разработки в редактор web-страниц Visual Studio — функциональный, но внешне не впечатляющий. На момент написания книги ни одна независимая фирма, занимающаяся созданием редакторов HTML, не объявила об интеграции своего продукта с Visual Studio.

Интересно, как будут развиваться события. Захотят ли web-дизайнеры осваивать Visual Studio? Привыкнут ли разработчики web-приложений к отделению пользовательского интерфейса от программного кода? Сейчас еще рано судить об оптимальном пути интеграции этих двух подходов.

Web-приложение Billinglnfo

В каталоге CH14WebBilling находится web-приложение WebBilling. Допустим, вымышленная компания из предыдущего примера хочет, чтобы ее сотрудники регистрировали свои затраты времени в Интернете при помощи web-браузера.

На рис. 14.2 показана структура формы в окне Visual Studio Webform Designer. Информация вводится в трех текстовых полях. Рядом находится элемент Range-Validator, который проверяет, что введенное число часов задано в интервале от 0,1 до 200 (сообщение, показанное на экране, отображается лишь при вводе недопустимой величины).

В двух элементах Label выводятся два введенных значения, последнее и предпоследнее, тем самым демонстрируется возможность хранения дополнительных данных в объекте Session. Элемент DataGrid содержит текущее содержимое базы данных, но в,отличие от Windows-версии этот элемент не позволяет редактировать записи непосредственно в элементе.

Рис. 14.2. Форма WebBilling в режиме конструирования

В листинге 14.6 показан вспомогательный код Visual Basic для файла WebBilling.aspx.

Листинг 14.6. Код модуля VB в приложении WebBilling

Public Inherits System.Web.UI.Page

Protected WithEvents txtName As System.Web.UI.WebControls.TextBox Protected WithEvents txtHours As System.Web.UI.WebControls.TextBox Protected WithEvents txtDescription As System.Web.UI.WebControls.TextBox Protected WithEvents DataGridl As System.Web.UI.WebControls.DataGrid Protected WithEvents LastEntryLabel As System.Web.UI.WebControls.Label

Protected WithEvents CurrentEntryLabel As

Systern.Web.Ul.WebControls.Label 

Protected WithEvents RangeValidatorl As _

Systern.Web.UI.WebControls.RangeValidator

 Protected WithEvents cmdAddEntry As System.Web,UI.WebControls.Button

#Region " Web Form Designer Generated Code "

' Необходимо для работы дизайнера web-форм.

 <System.Diagnostics.DebuggerStepThrough()> Private _ 

Sub InitializeComponent()

End Sub

Protected Sub Page_Init(ByVal Sender As System.Object, _

ByVaT e As System.EventArgs) Handles MyBase.Init

'ВНИМАНИЕ: вызов метода необходим

' для работы дизайнера web-форм.

' Не изменяйте его в редакторе!

InitializeComponent() 

End Sub

#End Region

Private Billinglnfo As MovingToVBNet.Billing.BillingComponent

 Private LastEntrylnfo As String

Private Sub Page_Load(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles MyBase.Load

Billinglnfo = New MovingToVBNet .Billing. BillingComponent()

Dim dv As New DataView(Billinglnfo.Info.Tables(O))

DataGridl.DataSource = dv

DataGridl.DataBindO

If Page.IsPostBack Then

LastEntrylnfo = CType(Session("LastEntry"), String)

 LastEntryLabel.Text = "Prior entry: " & LastEntrylnfo

End If

 End Sub

Private Sub cmdAddEntry_Click(ByVal sender As System.Object,

 ByVal e As System.EventArgs) Handles cmdAddEntry.Click

 Billinglnfo.AddRecord(txtName.Text,

  CInt(txtHours.Text),

txtDescription.Text) Session("LastEntry") = txtName.Text & ": " & txtHours.Text &_

" hours - " & txtDescription.Text 

CurrentEntryLabel.Text = "Current entry: " & txtName.Text & _

": " & txtHours.Text & " -hours - " & txtDescription.Text

 txtHours.Text = "" 

txtDescription.Text = ""

' Обновить таблицу

Dim dv As New DataView(BillingInfo.Info.Tables(0))

DataGridl.DataSource = dv

DataGridl.DataBind()

End Sub

Protected Overrides Sub Render(ByVal writer As

 System.Web.UI.HtmlTextWriter)

MyBase.Render (writer)

writer.WriteLine ("Here is some extra text ")

End Sub

Private Sub WebForml_Unload(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles MyBase.Unload

Billinglnfo.Dispose()

 End Sub

End

Приведенный код обладает рядом интересных особенностей.

  • Объекты элементов управления определяются точно так же, как в традиционных приложениях Windows.
  •  При обработке события Page_Load создается экземпляр класса BillingComponent. Программа создает объект ADO DataView для таблицы ВillingTable и назначает его источником данных для элемента DataGrid. Связывание элемента с данными осуществляется вызовом метода DataBind.
  • Свойство Page.IsPostBack позволяет узнать, была ли страница загружена в первый раз или повторно.
  •  Сеансовые переменные (Session) используются для хранения информации уровня сеанса для одной или нескольких страниц приложения.
  •  Переопределение метода Render позволяет сгенерировать для страницы дополнительный код HTML.

В рассмотренной ситуации web-приложение открывает замечательные возможности: чтобы работники нашей вымышленной компании могли сохранить информацию о своем рабочем времени, им достаточно простого доступа к Web. Но и это решение далеко не исчерпывает всех возможностей, предоставляемых .NET.

 

Решение с использованием web-службы

Предположим, наша компания решила также реализовать операции с базой данных с использованием web-службы. Web-служба представляет собой средство предоставления доступа к объекту через Web. В отличие от web-приложений, web-службы не обладают пользовательским интерфейсом — у них есть только методы и свойства.

Пример WebBillingService в каталоге CH14WebBillingService показывает, как предоставить доступ к методам исходного компонента BillingComponent через web-службу.

Класс WebBillingService приведен в листинге 14.7. Он выглядит настолько тривиально, что даже не требует комментариев. Единственное его отличие от стандартных компонентов Windows заключается в том, что он объявлен производным от класса System.Web. Services .WebService, а с некоторыми из его методов связывается атрибут WebMethod().

Листинг 14.7. Класс WebBillingService Imports System.Web.Services

Public ngService 

Inherits System.Web.Services.WebService

#Region " Web Services Designer Generated Code "

Public Sub New() 

MyBase.New()

' Необходимо для работы дизайнера web-служб. 

InitializeComponent()

' Дальнейшая инициализация выполняется 

' после вызова InitializeComponent().

End Sub

' Необходимо для работы дизайнера web-служб.

Private components As System.ComponentModel.Container

1ВНИМАНИЕ: следующий фрагмент необходим 

' для работы дизайнера web-служб. 

' Для его модификации следует использовать 1дизайнер web-служб. 

'Не изменяйте его в редакторе!

<System.Diagnostics.DebuggerStepThrough()> 

Private Sub InitializeComponentO

components = New System.ComponentModel.Container()

 End Sub

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

' ВНИМАНИЕ: следующий фрагмент необходим

' для работы дизайнера web-служб. 1Не изменяйте его в редакторе!

 End Sub

#End Region

Dim Billlnfo As MovingToVBNet.Billing.BillingComponent

<WebMethod()> Public Sub AddBi UingRecord(ByVal Name As String,

 ByVal hours As Double, ByVal Description As String)

Billlnfo = New MovingToVBNet .Billing.BillingComponent()

Billlnfo,AddRecord(Name, hours, Description)

Billlnfo. DisposeQ End Sub

<WebMethod()> Public Function GetBi llinglnfo() As DataSet

 Billlnfo = New MovingToVBNet.Billing.BillingComponent()

 Return (Billlnfo.Info)

End Function

End

При запуске этой службы в среде Visual Studio выводится разнообразная информация о web-службе, в том числе списки всех методов и свойств и примерный

синтаксис их вызова с использованием SOAP, команд HTTP Get и Post. Более того, вы даже сможете обращаться к методам и свойствам, если они достаточно просты для вызова простой командой HTTP Get.

Поскольку для транспортировки обращений используется протокол HTTP, службы могут работать на любом web-сервере на базе IIS. Поскольку большинство брандмауэров (firewalls) разрешает прохождение запросов HTTP (обязательное условие для всех общедоступных web-серверов), тем самым решается одна из самых больших проблем из области удаленного доступа.

Этой информации достаточно для использования web-службы из любого приложения или компонента, способного генерировать запросы HTTP. Если вы работаете с web-службой из приложения Visual Studio, задача становится еще проще.

 

Проектирование распределенных приложений

«Клиент-сервер», «трехуровневая архитектура», «распределенные приложения» — все эти термины описывают стандартные архитектурные решения из области сетевого программирования. Вместо того чтобы дополнять этот список новыми терминами, Microsoft .NET скорее предлагает взглянуть на распределенные приложения с новой точки зрения. Все существующие решения предполагают, что в вашем решении будет воплощена одна конкретная архитектура, а это требование накладывает немалую ответственность на проектировщика, поскольку ошибки неминуемо приводят к снижению быстродействия, потерям времени и денег. .NET предлагает другой подход. Вместо того чтобы выбирать конкретную архитектуру и придерживаться ее, вы создаете компоненты и используете их в разных сочетаниях. В некоторых ситуациях это позволяет найти не одно, а несколько оптимальных решений.

В приведенном выше примере было принято ключевое решение — создать компонент BillingComponent, обеспечивающий подключение к базе данных. При наличии готового компонента написать «толстого» клиента для локальной сети совсем несложно. Так же просто и создать web-приложение для удаленного доступа через браузер.

Пример BillingWinAppWeb показывает, как интегрировать web-службу с «толстым клиентом» простым включением web-ссылки в проект. В результате все объекты и их члены немедленно становятся доступными для приложения Windows, словно компонент установлен на локальном компьютере. Вся черная работа по сериализации объектов и маршалингу при обращениях к методам и свойствам web-службы и обратно выполняется автоматически. Круг замыкается: web-службы позволяют создавать удаленные приложения «толстых клиентов» без сложностей DCOM или проблем с настройкой брандмауэров.

Но и это не все!

Рассмотрим некоторые возможности, ставшие доступными благодаря существованию web-служб.

  •  Приложение для PDA (Personal Digital Assistant) или сотового телефона, позволяющее оперативно ввести информацию и отправить ее посредством вызова метода web-службы на базе простого запроса HTTP.
  •  Макрос Word, фиксирующий время открытия документа. Перед закрытием документа макрос предлагает ввести описание и сохраняет продолжительность работы над документом в базе данных, используя web-службу.
  •  Программа для сотового телефона, регистрирующая все звонки и при помощи web-службы сохраняющая номер и продолжительность каждого разговора в базе данных.
  •  Web-форму из описанного выше web-приложения легко превратить в web-элемент. Размещение этого элемента на других web-страницах позволит работникам вводить данные о затратах времени даже при работе с другими частями корпоративного web-сайта.
  •  Вы можете создать элемент на базе формы Windows и использовать его в качестве «толстого клиента» в браузере (по аналогии с использованием элементов ActiveX в СОМ). Элемент предоставляет расширенный пользовательский интерфейс в браузере, но при этом он будет использовать ту же web-службу.

Иначе говоря, web-служба позволяет в значительной степени автоматизировать утомительный и неточный процесс сбора статистики о затратах рабочего времени1.

В настоящее время web-сайты в основном предоставляют информацию в форме, доступной для человека. По мнению Microsoft, в будущем Web превратится в сеть компьютеров, предоставляющих в распоряжение пользователя объекты с определенной функциональностью.

Сейчас трудно сказать, насколько эти представления соответствуют действительности. Конечно, во многих случаях такой подход вполне оправдан. Например, такая компания, как Federal Express, могла бы создать специальную web-службу для отслеживания заказов, чтобы другие web-сайты могли реализовать отслеживание самостоятельно, не отсылая своих посетителей на web-сайт Federal Express. Впрочем, пока трудно сказать, приживутся ли такие модели в других сферах бизнеса и насколько распространенными они станут.

Независимо от того, превратятся ли общедоступные web-службы в модное направление программирования, они наверняка будут использоваться во многих серьезных программах в качестве основы для построения распределенных приложений.

Итак, настоящий подход к Интернет-программированию в .NET формулируется следующим образом: вместо того чтобы выбирать в своем решении один вариант архитектуры, вы можете выбрать все варианты сразу — при этом web-службы играют роль «клея», обеспечивающего взаимодействие разных компонентов.

При разработке решений на базе .NET основное внимание должно уделяться не конкретной архитектуре, а разбиению на компоненты. Если вам удастся определить универсальный набор компонентов, вы будете пользоваться значительной свободой при выборе их места в практической реализации. Например, если тестирование выявит недостаточную пропускную способность канала между базой данных и бизнес-объектом, вы сможете легко переместить компонент на сервер или опробовать другие каналы удаленного доступа.

1Я не уверен, что работников сильно обрадует «Большой брат», наблюдающий за всем, что они делают. Помните: то, что выможете что-то сделать, вовсе не означает, что этонужно делать.

 

Поддержка Winsock

Средства Интернет-программирования в .NET не ограничиваются высокоуровневыми web-приложениями и web-службами. В .NET предусмотрен удобный класс для работы непосредственно с Winsock.

В листинге 14.8 показан пример приложения, предназначенного для опроса (probing) портов. Подобные программы часто используются хакерами и экспертами в области безопасности для поиска уязвимых мест в защите системы.

Листинг 14.8. Приложение Probe

Imports System.Net 

Public rm 

Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New() 

MyBase.New()

' Необходимо для работы дизайнера форм Windows. 

InitializeComponent()

1Дальнейшая инициализация выполняется 

' после вызова InitializeComponent().

End Sub

' Форма переопределяет Dispose для очистки списка компонентов. 

Public Overloads Overrides Sub Dispose()

MyBase.Dispose()

If Not (components Is Nothing) Then 

components. Dispose()

End If

 End Sub

' Разрешить доступ к элементам пользовательского интерфейса 

' из другого потока.

' Windows обеспечивает автоматический маршалинг.

 Friend WithEvents listBoxl As System.Windows.Forms.ListBox 

Friend WithEvents txtIP As System.Windows.Forms.TextBox

 Friend WithEvents cmdProbe As System.Windows.Forms.Button 

Friend WithEvents labell As System.Windows.Forms.Label 

Friend WithEvents statusBarl As System.Windows.Forms.StatusBar

' Необходимо для работы дизайнера форм Windows.

 Private components As System.ComponentModel.Container

' ВНИМАНИЕ: следующий фрагмент необходим

' для дизайнера форм Windows.

' Для его модификации следует использовать

1дизайнер форм Windows.

1Не изменяйте его в редакторе!

<System.Diagnostics.DebuggerStepTnrough()> Private Sub _

InitializeComponent()

Me.txtIP = New System.Windows. Forms.TextBox()

Me.cmdProbe = New System.Windows. Forms.Button()

Me.labell = New System.Windows.Forms.Label()

Me.listBoxl = New System. Windows. Forms. ListBox()

 Me.statusBarl = New System.Windows.Forms.StatusBar()

 Me.Suspendlavout()

'txtli-

Me.txtlP.Location = New System.Drawing.Point(88, 16)

Me.txtIP.Name = "txtlP"

He.txtIP.,Size = New System.Drawing.Size(184, 20)

Me.txtlP.Tablndex = 1

He.txtIP.Text = ""

'cmdProbe

He.cmdProbe.Location = New System.Drawing.Point(112, 48)

He.cmdProbe .Name = "cmdProbe"

He.cmdProbe.Size = New System.Drawing.Size(64, 24)

He.cmdProbe.Tablndex = 3

He.cmdProbe.Text = "Probe"

'labell

Me.labell.Location = New System.Drawing.Point(32, 16)

Me.labell.Name = "labell"

He.labetl.Size = New System.Drawing.Size(56, 23)

He.labell.Tablndex =2

He.labell.Text = "IP:"

He.labell.ТехtAlign = System.Orawing.ContentAlignment.HiddleRight

'listBoxl

Me.listBoxl.Location = New System.Drawing.Point(16, 88)

 Me.listBoxl.Name = "listBoxl"

He.listBoxl.Size = New System.Drawing.Size(256, 160) 

Me.listBoxl.Tablndex = 0

'statusBarl

Me.statusBarl.Location = New System.Drawing.Point(0, 253)

Me.statusBarl.Name = "statusBarl"

Me.statusBarl.Size = New System.Drawing.Size(292, 20)

He.statusBarl.Tablndex = 5

He.statusBarl.Text = "statusBarl"

'ProbeForm

He.AutoScaleBaseSize = New System.Drawing.Size(5, 13)

He.ClientSize = New System.Drawing.Size(292, 273)

He.Controls.AddRange(New System.Windows.Forms.Control()

{He.statusBarl, He.cmdProbe, He.labell, Me.txtIP, Me.listBoxl})

Me.Name = "ProbeForm"

Me.Text = "port prober"

Me.ResumeLayout (False)

End Sub

#End Region

Private ProbingThread As Threading.Thread 

Private ProbertProber

Private Sub cmdProbe_Click(ByVal sender As System.Object, _

 ByVal e As System.EventArgs) Handles cmdProbe.Click

 If cmdProbeO.Text = "Stop" Then

Proberhread = True

ProbingThread.Join()

cmdProbeO.Text = "Probe"

ProbingThread = Nothing

Proberg

Exit Sub

 End If

ProbercketProberQ Prober= Me

ProbingThread = New System.Threading.Thread(New _

 Threading.Threadstart(AddressOf ProberdEntry))

 cmdProbeO.Text = "Stop" listBoxl().Items.Clear()

ProbingThread.Start()

 End Sub

Friend Function 

GetlPO As String

Return txtlP.Text

 End Function

Friend Sub SetStatus(ByVal s As String)

Me.statusBarl.Text = s 

End Sub

Friend Sub AddToList(ByVal s As String)

listBoxl.Items.Add (s) 

End Sub

 End

Delegate Function fNoParams() As String 

Delegate Sub fSetString(ByVal s As String)

ober

Friend TheForm As ProbeForm 

Friend StopTheThread As Boolean 

Public Sub SubThreadEntry()

Dim s As Sockets.Socket

Dim ip As IPAddress

Dim ep As IPEndPoint

Dim textfp As fNoParams = AddressOf TheForm.GetIP

ip = IPAddress.Parse(CStr(TheForm.Invoke(textfp)))

 Dim portnumber As Integer For portnumber = 1 To &H7FFF

Dim fpstat As fSetString = AddressOf TheForm.SetStatus

  TheForm. Invoke(f pstat, New StringO {"Checking port: " &_

Str(portnumber)})

ep = New IPEndPoint(ip, portnumber) 

s = New Sockets.Socket(Sockets.AddressFamily.InterNetwork, _

Sockets.SocketType.Stream, Sockets.ProtocolType.Tcp)

 Try

s.Connect (ep) Dim plist As fSetString = AddressOf

 TheForm.AddToList

TheForm. Invoke(plist. New StringO {"Connected to port " &_

Str(portnumber)}) 

Catch ex As Exception debug.WriteLineC

Failed port " & Str(portnumber) &_

" - " & ex.Message)

 End Try

s.Close()

If StopTheThread Then Exit Sub 

' Запрос на завершение

 Next 

 End Sub

End

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

  • Очень удобный метод ipaddress. Parse преобразует IP-адрес из текстовой формы в структуру IPAddress.
  •  Вместо прямых обращений к форме фонового потока используется метод Invoke. Вспомните, о чем говорилось в главе 13 — формы небезопасны по отношению к потокам.

Взгляд со стороны

Иногда меня спрашивают, сколько авторов на меня работает. Уверяю вас, я действительно сам пишу свои книги и даже готовлю все иллюстрации (хотя для того, чтобы они хорошо смотрелись, обычно приходится прибегать к услугам специалистов по компьютерной графике).

Тем не менее я охотно прислушиваюсь к чужому мнению. Этой книге очень повезло с техническим редактором: Скотт Стабберт работает в Microsoft и участвует в разработке обучающих материалов и примеров программ для .NET (всего того, что Microsoft обычно демонстрирует на презентациях или семинарах). Он особенно хорошо разбирается в аспектах .NET, связанных с web-программированием, поэтому я попросил его сказать несколько слов по поводу роли .NET в Web. Привожу его мнение почти дословно.

«...web-элементы очень, очень важны. Чтобы лучше понять их роль, необходимо вернуться к выходу VB3. Почему Visual Basic стал таким популярным языком? По нескольким причинам, но самой главной из них были элементы VBX. На рынке каждую неделю появлялись всевозможные новинки, созданные независимыми фирмами, и программисты с нетерпением ждали очередного выпуска „Visual Basic Programmers Journal". Некоторые разработки были просто замечательными — „сногсшибательными", как любит выражаться наш друг мистер Джобе. Другие... мягко говоря, не блистали качеством. Люди покупали хорошее, а плохое отправлялось на помойку1.

1Не могу удержаться от замечания (это снова Дэн) — моя компания Desaware выпустила свой первый продукт в эпоху VB1. Хотя природная скромность не позволяет мне расхваливать качество своих разработок, факт налицо — мы продолжаем работать!

А теперь перенесемся на целую эпоху (по крайней мере, так кажется) — с середины в конец 90-х годов, когда появились такие инструменты, как Visual Inter-Dev, FrontPage и т. д. Эти инструменты пишут код за вас. Более того, этот код работает — но попробуйте изменить его и заставить делать то, что хотите вы. Автоматически сгенерированный код никогда не работает в точности так, как было задумано. Автоматизированное построение web-сайтов чем-то напоминает нарезку печенья по готовой форме: получается быстро и удобно, но за это приходится расплачиваться потерей индивидуальности. Профессионалы обычно пишут весь код вручную, поскольку вспомогательные программы не удовлетворяют их повышенным требованиям. Очень часто сгенерированный код трудно редактировать и сопровождать, а иногда он и вовсе оказывается бесполезным. Впрочем, я отвлекся.

Итак, web-элементы являются Интернет-аналогом элементов VBX/OCX. Появятся новые „сногсшибательные" разработки — возможно, среди их авторов окажетесь и вы. Конечно, будут и неудачи. Со временем качество элементов будет оцениваться по качеству сгенерированного ими кода HTML/DHTML и клиентских сценариев. Хорошо написанный web-элемент будет изменять свои выходные данные в зависимости от типа браузера или, скажем, при запросе страницы с сотового телефона через протокол WAP (Wireless Application Protocol).

Архитектура web-элемента способствует развитию унифицированного кода, адаптируемого для конкретного случая программистом, использующим элемент. Проблема «штампованного» HTML-кода решается при помощи шаблонов. Кстати говоря, перед нами еще один уровень отделения интерфейса от реализации. Разработчик элемента определяет его функциональность, а программист, использующий элемент, определяет специфические особенности генерируемого HTML-кода.

Классы web-элементов (как и всех остальных элементов .NET) можно взять за основу для определения ваших собственных элементов и изменить их поведение в случае надобности.

Ожидается, что web-элементы, как и родственные им элементы VBX/OCX, сформируют развитый рынок для продуктов независимых фирм. Несомненно, в таком развитии событий заинтересованы все компании и особенно программисты VB, которым было бы интересно заняться web-приложениями.

В настоящее время во многих компаниях идет лихорадочная работа над элементами, которые должны быть готовы к выходу окончательной версии .NET, ивы как представитель сообщества программистов VB от этого только выиграете. Рынок вознаградит хорошие разработки и накажет плохие (во всяком случае, мы на это надеемся), а с каждым новым элементом ASP .NET Framework станет еще мощнее и удобнее в использовании».

Спасибо, Скотт.

Честно говоря, я не уверен в его правоте. Конечно, я согласен с тем, что возможности web-элементов колоссальны, но говорить о рыночных перспективах пока рано — хотя я не сомневаюсь, что многие разработчики компонентов предложат свои web-элементы и некоторые из них будут пользоваться успехом. Конечно, компания Desaware давно отказалась от разработки общих элементов пользовательского интерфейса — мы предпочитаем заниматься более творческими и менее очевидными вещами. Но кто знает? Может, и мне суждено написать пару-тройку web-элементов. Поживем — увидим...

 

Итоги

В этой главе в основном рассматриваются архитектурные решения и концепции, а не конкретные реализации. Вы узнали, что XML и XSL в действительности чрезвычайно просты, а вся шумиха вокруг них объясняется не столько их сложностью, сколько простотой и элегантностью. Также было показано, что правильное разбиение на компоненты позволяет создавать по-настоящему распределенные приложения. В этой главе были продемонстрированы разные способы использования компонентов, от традиционных «толстых клиентов», вся функциональность которых сосредоточена в одной системе, до web-приложений и web-служб. Идеология распределенных приложений в сочетании с логически согласованной архитектурой .NET обеспечивает необходимую гибкость для интеграции новых систем и технологий по мере их появления — в том числе и разработанных за пределами Microsoft.

Назад   Вперёд

 


Инфо
Сайт создан: 20 июня 2015 г.
Рейтинг@Mail.ru
Главная страница