Как сделать SOAP/WSDL-вебсервис на ASP.NET/MONO для вызова его из FLEX
Наиболее целесообразную и грамотную технология построения клиент-серверных приложений и тонких клиентов для браузера (которая мне видится на данный момент - начало 2011-го года) - я покажу на этой страничке. Суть ее в том, чтобы делать клиента, работающего в браузере на Flex - а на сервере поднимать WebService, откуда Flex-приложение получает данные. На мой взгляд такая технология дает просто адские преимущества:
- Серверная часть может быть развернута и в устаревшей операционной системе Windows (c программным кодом, принадлежащим одному человеку - Биллу Гейтсу) и в современной OpenSource операционной системе Linux (чей код является общественным достоянием). Описанный здесь подход позволяет в несколько кликов мышкой портировать серверный компонент из закрытой билогейтсовской среды NET в OpenSource среду MONO на Linux.
- Таким способом можно избежать обширного программирования на Язваскрипт и применения монстрообразных и тормозных библиотек типа JQUERY - как это требуется для тонких клиентов с активным интерфейсом. В соседнем топике я описал фотосладер (Мой первый фото-слайдер на Flex 4), в котором я показал, что Flex-код не только работает быстрее JavaScript (это и не удивительно, это ведь откомпилированный код), но и вес откомпилированного байт-кода небольшой, относительно исходных Javascript библиотек.
- Программирование на Flex в исполнительной среде Flash-плеера несложное и напоминает программирование Windows-приложений. Плюс конечно фантатические возможности анимации и графики Flash. А чтобы преобразовать Web-приложение на Flex в десктопное приложение AIR - требуется буквально несколько кликов мышкой. Причем это может быть десктопное приложение от Macintosh и Windows до Linux.
- В браузере отрабатывает откомпилированный байт-код Flex, что дает помимо всего вышеперечисленного сохранение авторских прав на клиентскую часть и скорость работы приложения. Кроме того виртуальная машина Flash-плеера установлена у 99,1% интернет-пользователей, что превышает количество интернет-пользователей у кого разрешена работа JavaScript и JAVA.
- Простая и понятная спецификация SOAP/WSDL-сервиса, позволяет четко разрезать приложение на серверную и клиентскую часть и позволяет обратиться к этому интерфейсу из множества клиентов - начиная от диалоговых инструметов типа Altova, кончая Win/Web-приложениями, сделанными по любой технологии. Это позволяет в процессе жизненного цикла приложения гнуть его как на шарнирах. Например заменить со временем (при необходимости) серверный NET-компонент приложения на другой компонент, сделанный например на JAVA или Delphi. Или со временем сделать другой клиент для этого Web-сервиса вместо Flex-компонента - NET-приложение, JavaScript-приложение, JAVA-апплет и так далее.
Ниже я покажу те самые волшебные 50 кликов мышкой по нужным местам на экране монитора, которые позволяют создать простейший Web-сервис, который можно использовать во Flex-компоненте. Сами по себе эти 50 кликов мышкой ничего особенного для NET-программиста из себя не представляют, но для человека, который пришел во Flex из анимации и графики - это чтиво должно быть весьма занятно.
Для выполнения описанных ниже операций необходима Microsoft Visual Studio 2010, как ее получить бесплатно я описал здесь - Знакомство с Visual Studio 2010.
Для начала давайте немного сориентируемся в множестве разновидностей Web-сервисов, существующих в различных фреймворках ASP.NET:
- NET 2.0 : Web Service (ASMX)
- NET 3.0 : Web Service (ASMX), WCF Service (SVC)
- NET 3.5 : Web Service (ASMX), WCF Service (SVC)
- NET 4.0 : WCF Service (SVC), REST Service (Service/{ID}), WCF Workflow Service (XAMLX), AJAX Enabled WCF Service (SVC)
Итого, как вы видите, у микрософта существует минимум ПЯТЬ основных типов веб-сервисов. Кроме того, существует еще несколько смежных c Web-сервисами технологий, начиная от того что можно сформировать на ASP.NET просто XML (в любом фреймворке). Одной из этих смежных технологий - я воспользовался в соседнем топике, чтобы показать как из FLEX можно получить данные с сервера - OpenSource Freeware FotoSlider on Flex 3 and jQuery. Однако обратите внимание, что Web-сервис тоже выдает XML - что слегка похоже на простую отдачу XML обычным хандлером, НО - даже если вы сформируете хандлером полный SOAP-конверт и SOAP-BODY, то вебсервиса вы так не получите. Ибо вебсервис подразумевает еще и особый заголовок SOAPAction формируемый IIS, и, конечно, более сложную логику передачи клиенту служебных запросов со схемой WSDL.
Обратите также внимание на то, что ссылки на сервисы в проектах (при добавлении Web-сервисов, сделанных в разных фреймворках) ставятся по разному - на ASMX-сервис ссылка ставится как Add Web Reference, а на SVC-сервисы как Add Service Reference.
Также обратите внимание, что NET 4.0 плохо совместим с фрейворками NET 2.0, NET 3.0, NET 3.5 - он должен быть отдельно догружен в IIS и требует другого отладчика. В принципе существует еще NET 1.1, но сейчас на нем реально уже никто не пишет - однако сайтов на нем полно для апгрейда в более новую среду. Этот фреймворк тоже совершенно несовместим ни с чем, даже с NET 2.0. Раньше на сайте MS лежал список из нескольких тысяч методов которые пропали в NET 2.0 относительно NET 1.1 и которые добавились. Когда-то, в далеком 2005-м году, я делал обзор что нового появилось в NET 2.0 относительно NET 1.1 - Мое первое знакомство с ASP2 и VS2005. А теперь уже пора делать обзор - что из NET 2.0 пропало в NET 4.0, а что появилось.
Поскольку web-сервис обычно работает с базой (это может быть огромный XML-файл куда делаются запросы по XPATCH - или в более распространенном виде SQL-сервер), то надо понять по какой из многочисленных технологий форматировать буфер памяти, где хранится вычитанный из базы результат:
- Первый вариант - вообще не использоваться никаких замороченных микрософтовских технологий для форматирования буфера в памяти кампутера, а просто определить вручную класс с полями и читать туда записи из базы. Вот простой пример такой обвязки - Пример обработки XML без LINQ, которая вычитывает XML из базы, парсит его по XPATCH и просто ложит распарсенный данные в Property класса. Вот еще более тупой пример, когда из базы вычитываются уже готовые поля, а не XML (который еще и распарсить надо, как в предыдущем примере) - Фрагмент реальной BLL на PostgeSQL. Это наиболее простой из существующих способов и во многих случаях это проще всего - вообще не применять крученые микрософтовские технологии для форматирования буфера памяти (изучение которых может отнять в тысячу раз больше времени, чем простое ручное расписывание адресов в памяти переменными).
- Второй вариант - воспользоваться форматированием буфера в ОЗУ одной из фирменных микрософтовских технологий:
- NET 2.0 : DataSet (XSD)
- NET 3.0 : DataSet (XSD)
- NET 3.5 : DataSet (XSD), LINQ (dbml), ADO NET Entity (edmx)
- NET 4.0 : DataSet (XSD), LINQ (dbml), ADO NET Entity (edmx)
Сама по себе LINQ тоже довольно громоздкая технология и делится на несколько разновидностей, подробнее я их перечислил на страничке Извлекаем пользу из LINQ. А Entity - это еще более накрученная надстройка чем LINQ. Мне не вполне понятно дает ли ее изучение облегчение и ускорение проектирования NET-приложений или просто обьектно-программирующие индусы (о которых я написал в конце этой заметки - Знакомство с Adobe Flex 4) забивают головы программистам всяким ненужным хламом (и попутно отжимают у идиота Билла Гейтса немного денюжки за разработку этого хлама).
- Вычитывать данные из SQL и память с помощью сторонних библиотек, таких как NHibernate и подобных. Мне этот вариант представляется наиболее сложным, громоздким и негибким. Хотя в каких-то безвыходных ситуациях, возможно, иначе нельзя. Но у меня пока таких безнадежных ситуаций не было.
И наконец, на самом нижнем уровне Web-сервиса лежит собственно хранилище данных. Это может быть огромный XML-файл (например экспортированный из 1С), запросы в который делаются по XPATCH (иногда эти фраменты XML лежат не в файловой системе, а в SQL, как в этом примере - Пример обработки XML на XLINQ, но в подавляющем большинстве случаев данные все-таки хранятся в SQL-сервере.
Вообще различных SQL-серверов существует не менее двух десятков, я достаточно уверенно умею работать с тремя из них:
Итак, вы видите, что собрать Web-сервис на ASP.NET для использования его во FLEX можно множеством способов - на самом верхнем уровне это может быть ASMX или различные варианты SVC-сервисов. Их можно выполнить в различных несовместимых друг с другом фремворках, средах хостинга, операционных системах. Буфера для хранения данных можно тоже форматировать самым разным образом - от ручного и DataSet до LINQ и Entity. И наконец, база под этим всем хозяйством может быть тоже совершенно разная - от XML-файла, лежащего в файловой системе, до самых разных SQL-серверов.
Поэтому описание построение Web-сервиса для использования его во FLEX может быть безгранично - если комбинировать эти варианты (да еще и скомбинировать что именно возвращает Web-сервис - просто число, одну строку рекордсета, весь рекордсет из нескольких строк данных, рекордсет переменного форматата и тд), да потом еще и описать с какими особенностями каждый из этих вариантов работает на MONO в LINUX - то это получится тысячи примеров (или книга на миллион страниц).
Поэтому ниже я опишу лишь несколько примеров WebService, которыми я постараюсь зацепить побольше технологий. Описание будет произведено на примере общедоступных данных, которые существуют для любого SQL-сервера - Фальсификация выборов в Москве (база данных для статистических исследований).
Итак, первый пример будет описан для следующей среды работы сервиса:
- Операционная система (Linux-MONO, Windows-NET)
- Фреймфорк (NET 1.1, NET 2.0, NET 3.0, NET 3.5, NET 4.0)
- Вид веб-сервиса (Web Service, WCF Service, REST Service, WCF Workflow Service, AJAX Enabled WCF Service)
- Способ разметки буфера в памяти (вручную, MS-DataSet, MS-LINQ, MS-Entity, NHibernate)
- СУБД (PostgreSQL, MS SQL, MySQL)
Углубляясь в еще более глубокие детали работы WCF-сервиса в этой среде - алгоритм его работы можно организовать тысячей способов. Только три главных атрибута, управляющих поведением среды web-сервиса - имеют сотни вариантов сочетаний режимов работы Web-сервиса:
Еще есть сотни параметров, которые можно настраивать через config-файл web-сервиса (где их смотреть я покажу чуть ниже). И самое главное что web-сервис ведет себя совершенно по-разному при различных сочетаниях этих режимов работы. В доказательство я взял десяток первых попавшихся мне табличек из первой попавшейся под руку книжки по программированию web-сервисов.
Для использования всех этих параметров для начала надо понять, что они управляют СРЕДОЙ выполнения той функции, которую мы создадим дальше (за 50 кликов мышкой). Движок ASP.NET читает все эти атрибуты у созданных нами классов, читает параметры из конфига и в зависимости от этих параметров по разному подключает созданную функцию. Ну например может подключить один-единственный экземпляр этой функции для обслуживания всех запросов от всех клиентов, может для обслуживания всех запросов от одного клиента, может создать на каждый запрос новый персональный экземпляр класса с указанной ниже смысловой функцией. Это в упрощенном виде описание лишь одного атрибута InstanceConrextMode - а подобных атрибутов сотни.
Надеюсь теперь понятно, насколько непросто флешеру-аниматору найти в этом море те самые (буквально волшебные) 50 кликов мышкой, которые приведут результату - простейшему WCF-сервису, который можно будет использовать во Flex.
Обратите внимание, что построение веб-сервисов - весьма неплохо оцениваемая работа. Как я понимаю, она минимум раз в двадцать дороже обычной html-верстки, которая потребовала в два раза больше кликов мышкой - Верстка в ASP NET MVC. Так выполним же ту самую волшебную последовательность кликов мышкой по нужным местам на экране и создадим Web-сервис, пригодный для Flex. Итак, тыкаем мышкой в нужные места на экране монитора первые пять раз и получаем рыбку проекта WCF-сервиса в NET 4.0.
Итак рыбка проекта создана - есть некие функции, которые будут в виде калбеков встроены в общий микрософтовский движок WCF. Место встраивания и режимы вызова этих функций (как я уже говорил) определяются многочисленными атрибутами и параметрами конфигурации. Где находятся основные атрибуты - я показывыл выше, теперь посмотрим где находится конфигурация и как ее можно менять с помощью редактора конфигурации SvcConfigEditor (но менять мы ее сейчас не будем).
Как вы можете увидеть микрософтовский движок WCF требует две вещи - интерфейс без реализации (на основе которого будет в процессе служебного обмена между клиентом и сервером создан прокси на клиента и сгенерирован WSDL) - это файл IService1.vb и файл Service1.svc, где будут находится созданные нами функции, которые вызовет движок WCF.
Теперь я сделаю то же самое, что делаю всегда со своими проектами - добавлю их в Subversion. Это позволяет мне отслеживать любые изменения в любом проекте, делать несколько версий кода, откатываться по любой версии назад на любое количество шагов, передавать код другим проггерам и видеть что они там поменяли - в общем я к этому сервису привык. Что за зверь Subversion - вы можете почитать на моей страничке - Избавляемся от Team Foundation Server - ставим Subversion.
Так, тыкаем созданную рыбку проекта и смотрим - все ли нормально в нашей среде работы - поднимется ли рыбка Web-сервиса на девелоперской машине.
Отлично, рыбка web-сервиса, которую нам предлагает MS - поднялась. Стартануд девелоперский сервер WebDev.WebServer40, в котором хостится рыбка нашего вебсервиса, он слушает адрес http://localhost:1493. стартанул WCFTestClient, которым можно прочитать WSDL, определенным нашим интерфейсом IService1.
Перед тем как писать настоящую прогу на FLEX, использующую weв-сервис, его надо проверить. Вэб-сервисы тестируют четырьмя широкоизвестными способами:
- Тестовым клиентом WCFTestClient
- Браузером
- Альтовой
- Visual Studio 2010
Мы по ходу дела посмотрим все четыре способа проверки работы сервиса, а чтобы проверить его работу браузером - надо просто отдать браузеру адрес вэб-сервиса.
Далее я внесу в конфигурацию строку коннекта к моему SQL-серверу. В этом SQL-сервере у меня уже загружена база для этого примера (которую вы можете скачать с этой странички). И в этом SQL-сервере у меня уже прописан логин и пароль для коннекта к этой базе и с этим логином/паролем мы будем работать в этом проекте.
Теперь откроем ту же базу не из-под конкретного логина, прописанного у нас в конфиге, а входом из Windows-аутентификации непосредственно внутри Visual Studio. Это нужно будет нам чтобы создать модель базы инструментами студии. Удаляем ненужную папочку для работы SQLExpress и создаем буфер в памяти для считывания данных из SQL-сервера.
Теперь выполняем действие, требующее развитие развитой мотории пальцев. Если вам меньше трех лет от роду, то так долго вы не сможете удерживать левую кнопку мышки прижатой. Если больше - должно получится. Перетаскиваем на левую панель вьюшку, а на правую две процедуры. Среди программистов это действие называется drag-and-drop.
Этих двух процедур в изначально распространяемой базе с протоколом преступлений чуровского бандформирования - нет. Эти две процы я добавил для этого проекта. Это два копеечных отбора:
1: ALTER procedure [dbo].[GetResultForUIK]
2: (@UIK as integer)
3: as
4: SELECT *
5: FROM [Criminal].[dbo].[PartyResult]
6: WHERE @UIK=[Участковая избирательная комиссия]
7: GO
8: ALTER procedure [dbo].[GetAllUIK]
9: as
10: SELECT [Участковая избирательная комиссия]
11: FROM [Criminal].[dbo].[PartyResult]
12: ORDER BY isnull(cast([Московское городское региональное отделение Партии "ЕДИНАЯ РОССИЯ"]as integer),0)
13: GO
Теперь меняем ConnectionString который создала студия для Linq-To-SQL на наш постоянный коннект к SQL-серверу, а временный студийный коннект выбрасываем.
Теперь внимание. Важная галка Unidirectional без которой ничего работать не будет. Если вы не знаете что ее надо вообще поставить или не знаете где ее искать - никакого web-сервиса у вас не получится.
Все, с буфером памяти для чтения данных из SQL-сервера мы закончили, его можно закрыть (и зачикать в SVN). Благодаря этому дизайнеру мы избавились от ручной разметки памяти в стиле Ассемблера, когда мы должны вручную разметить каждую область памяти (в соответствии с типом данных) и присвоить каждой области памяти (соответствующей полю в базе данных SQL) имя. Все это за нас сделал этот самый дизайнер Linq to SQL. Кроме того, он даст нам возможность удобного отбора нужных данных из этого буфера памяти (если записей в этом буфере будет много).
Теперь открываем рыбку интерфейса, удаляем его и создаем там свой интерфейс для вызова наших двух процедур. Именно по этому интерфейсу движок WCF построит WSDL и будет подключать функции нашего сервиса. По этому же интерфейсу будет строиться и клиент web-сервиса.
1: <ServiceContract()>
2: Public Interface IService1
3:
4: <OperationContract()>
5: Function Tst(ByVal value As Integer) As String
6:
7: <OperationContract()>
8: Function GetCriminalForUIK(ByVal UIK As Integer) As GetResultForUIKResult
9:
10: <OperationContract()>
11: Function GetAllCriminal() As System.Collections.Generic.List(Of GetAllUIKResult)
12:
13: End Interface
Теперь ставим точку в этой головоломке. Открываем реализацию этого интерфейса, то есть собственно те самые калбеки, которые движок WCF подключит и вызовет в нужных местах своего алгоритма. Дальше делаем раз-два-три. Раз - это стираем то что там было. Два - ставим мышку после слово Iservice1 и жмакаем на нее. И три - вносим во внутрь функций искомые пять строчек кода.
1: Public Class Service1
2: Implements IService1
3:
4: Public Function Tst(ByVal value As Integer) As String Implements IService1.Tst
5: Return "OK - " & value.ToString
6: End Function
7:
8: Public Function GetCriminalForUIK(ByVal UIK As Integer) As GetResultForUIKResult Implements IService1.GetCriminalForUIK
9: Dim CriminalDB As New CrimeResultDataContext
10: Return CriminalDB.GetResultForUIK(UIK).ToList(0)
11: End Function
12:
13: Public Function GetAllCriminal() As System.Collections.Generic.List(Of GetAllUIKResult) Implements IService1.GetAllCriminal
14: Dim CriminalDB As New CrimeResultDataContext
15: Return CriminalDB.GetAllUIK.ToList
16: End Function
17: End Class
С простейшим видом Web-сервиса, в описанных выше условиях - это в основном все. Осталось проверить что получилось. Тыкаем RUN и смотрим:
Так, а вторая функция сервиса не отработала. У клиента стоит слишком малая длина принимаемых данных MaxReceivedMessageSize. Можно конечно подправить конфиг этому клиенту, но мы пойдем иначе - ведь я обещал показать и другие способы проверки Web-service.
Итак, берем Альтову, вносим ей адрес WSDL и отправляем реквест. Результат превосходный и свидетельствует о полной работоспособности созданного нами простейшего вебсервиса.
Последнее, что я бы хотел показать для полноты описания - перед тем как мы уйдем во Flex - как можно приконнектиться к этому сервису самой же студией. Итак, запускаем ее еще в одном экземпляре - создаем любой тип проекта (мы его даже сохранять не будем, это будет временный проект).
Теперь тыкаем в AddReference и выбираем ServiceReference. Берем адрес нашего сервиса и вносим его в адресную строку ссылки.
Нажимаем GO и получаем ссылку наш web-сервис (и построенный по нашему WSDL прокси-классу).
Проверим, получился ли прокси-класс и работает ли он.
Да, все отлично. Есть и подсказка и все работает в run-time.
На самом деле, конечно, не все так гладко не только с сервисом, но даже и с клиентом. По поводу микрософтовского клиента в Web-сервису и его глюков у меня много чего написано на сайте (WCF_CLIENT - клиент Web-сервиса), я даже распространяю свой (альтернативный микрософтовскому) клиент веб-сервиса - WCF_CLIENT - клиент Web-сервиса - но в общем не будем столь глубоко углубляться в тему вебсервисов. И наконец-то перейдем к главному клиенту web-сервиса, ради которого и затевалось все это описание.
Здесь конечно нам уже потребуется IDE для работы во флексе, как его получить (в том числе бесплатно) - у меня описано на страничке Знакомство с Adobe Flex 4. Итак, cоздаем новый Flex-проект и вносим в него определение сервиса. Я уже показал достаточно инструментов, чтобы прочитать ими WSDL. Поэтому для начала внесем определение сервиса вручную.
Для работы Flex-клиента Web-сервиса требуется лишь определение сервиса и всего две функции, одна из которых вызывает сервис, а во второй получается результат. Это самый минимальный код. Я добавил к нему лишь кнопку, которая неактивна, пока вычитывается WSDL и идет служебный обмен между клиентом и собственно сервисом.
1: <?xml version="1.0" encoding="utf-8"?>
2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
3: xmlns:s="library://ns.adobe.com/flex/spark"
4: xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
5: <fx:Script>
6: <![CDATA[
7: import mx.collections.ArrayCollection;
8: import mx.controls.Alert;
9: import mx.rpc.events.ResultEvent;
10: import mx.rpc.soap.LoadEvent;
11:
12: [Bindable]
13: public var WebServiceResult:ArrayCollection ;
14:
15: protected function GetSOAP_loadHandler(event:LoadEvent):void
16: {
17: ReadButton.enabled=true;
18: }
19:
20: protected function ReadButton_clickHandler(event:MouseEvent):void
21: {
22: GetSOAP.GetCriminalForUIK(UikNumber.text);
23: }
24:
25: protected function GetOneRecordHandler(event:ResultEvent):void
26: {
27: WebServiceResult=event.result as ArrayCollection;
28: }
29: ]]>
30: </fx:Script>
31:
32: <fx:Declarations>
33: <!-- Place non-visual elements (e.g., services, value objects) here -->
34: <mx:WebService id="GetSOAP" wsdl="http://seo.vb-net.com/?wsdl" load="GetSOAP_loadHandler(event)">
35: <mx:operation name="Tst" result="GetOneRecordHandler(event)" />
36: <mx:operation name="GetCriminalForUIK" result="GetOneRecordHandler(event)" />
37: <mx:operation name="GetAllCriminal" result="GetOneRecordHandler(event)" />
38: </mx:WebService>
39: </fx:Declarations>
40:
41: <s:TextInput id="UikNumber" x="42" y="10" width="85"/>
42: <s:Label x="10" y="17" text="UIK"/>
43: <s:Button id="ReadButton" x="143" y="11" label="Read" width="54" enabled="false" click="ReadButton_clickHandler(event)"/>
44:
45:
46: </s:Application>
Посмотрим что получилось. Вот протокол обращения к web-сервису, зафиксированный сетевым снифером:
Пока кнопка стала активной FireBug зафиксировал четыре запроса от Flash-плеера:
И пятым запросом идет собственно обращение к сервису:
Посмотрим, что показывает отладчик.
Как видите, все отлично. Флексовый тег WebService автоматически на ходу построил клиент веб-сервиса. Теперь можно все это добавить на Флекс-форму и например даже отрисовать Флексом весь график фальсификации выборов, который я отрисовал вручную экселом на страничке, откуда вы сгружали базу данных для этого примера. Для этого придется сначала методом сервиса GetAllCriminal прочитать весь список UIK, потом результаты каждого UIK методом GetCriminalForUIK.
Можно также воспользоваться встроенным во Flex мастером посроения клиентского прокси-класса веб-сервиса (ровно так же, как мы добавляли выше ServiceReference в Visual Studio). Но тут из-за моих русских букв в именах свойств, возвращаемых сервисом - получается много ручных корректировок. С нормальным сервисом (без русских букв) все работает лучше чем в Visual Studio - даже есть автоматический построитель формы для отображения результатов запроса к сервису.
Во-втором примере мы проигнорируем, что обьектнопрограммирующие индусы отжали от Билла Гейста несколько миллиардов долларов на разработку и LINQ и WCF и MS SQL - и создадим web-сервис, который будет работать как будто бы Билл Гейтc съэкономил на оплате этих разработок. Любопытно, что работать в этом случае все будет лучше и быстрее. Увы, когда постоянно наблюдаешь такое - как старые технологии работают проще, лучше и быстрее новых - формируется некое циничное отношение и к умственным способностям Билла и к умственным способностям его обьектно-программирующих индусов.
Итак, во втором примере среда нашего вэбсервиса будет такая:
- Операционная система (Linux-MONO, Windows-NET)
- Фреймфорк (NET 1.1, NET 2.0, NET 3.0, NET 3.5, NET 4.0)
- Вид веб-сервиса (Web Service, WCF Service, REST Service, WCF Workflow Service, AJAX Enabled WCF Service)
- Способ разметки буфера в памяти (вручную, MS-DataSet, MS-LINQ, MS-Entity, NHibernate)
- СУБД (PostgreSQL, MS SQL, MySQL)
Создаем новый проект и добавляем, сразу доабвляю в конфиг строку коннекта к моей базе и добавляю в проект ссылки на драйвер/провайдер доступа к MySQL.
У меня есть своя собственная обвязка из нескольких строк кода, которая заменяет тупые индустские придумки типа Entity Framework из миллиарда строк кода и позволяет сократить код запросов к базе в теле проги до одной строки. Этот код в откомпилированном виде вы можете сгрузить с моего сайта, куда я выкладываю свои Freeware OpenSource-проги, ну а я для ускорения просто добавлю исходник этих нескольких строк кода в этот проект.
Теперь открываем код сервиса и вводим восемь коротеньких строчечек кода в наш метод веб-сервиса:
1: Imports System.Web.Services
2: Imports System.Web.Services.Protocols
3: Imports System.ComponentModel
4:
5: <System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
6: <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
7: <ToolboxItem(False)> _
8: Public Class Service1
9: Inherits System.Web.Services.WebService
10:
11: <WebMethod()> _
12: Public Function GetArea() As Data.DataTable
13: Dim ReadOneUik As New ExecMySQL_RDR()
14: Dim DT1 As New Data.DataTable
15: Dim DR1 = ReadOneUik.ExecMySQL("Select * from area", Data.CommandType.Text)
16: If DR1.Read Then
17: DT1.Load(DR1)
18: End If
19: ReadOneUik.Close()
20: Return DT1
21: End Function
22:
23: End Class
Как видите все тупо. Настолько тупо что даже не требуется никакой индустский визуальный дизайнер. Это даже не полный датасет, а его вырожденная форма - просто буфер в ОЗУ. Так называемый нетипизированный датасет. Однако его применения позволяет избежать не только изучения тупых индустских придумок типа LINQ - но и дает СУПЕР-качество создаваемой проге. При изменении структуры данных в SQL-сервере - перекомпиляция проги не требуется, не нужно удалять созданную визуальным дизайнером типизированную обвязку и создавать новую. Фактически это супер-долгоживущий код. Помимо всего прочего - это еще и работает в миллион раз быстрее чем LINQ.
Но такой подход не позволяет превращать программистов в быдло - в кормовую базу Билла Гейтса (и не дает зарабатывать индусам на своей национальной индустской забаве - создании новых, все более и более громоздких и бессмысленных обьектов для доступа к данным).
Все работает чудесно. Теперь открываем Флекс и читаем данные из этого сервиса ровно в пять строчек кода:
1: <?xml version="1.0" encoding="utf-8"?>
2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
3: xmlns:s="library://ns.adobe.com/flex/spark"
4: xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" >
5: <fx:Script>
6: <![CDATA[
7: import mx.collections.ArrayCollection;
8: import mx.controls.Alert;
9: import mx.events.FlexEvent;
10: import mx.rpc.events.ResultEvent;
11: import mx.rpc.soap.LoadEvent;
12: import mx.utils.object_proxy;
13:
14: [Bindable]
15: public var GetSoap2Result:mx.utils.ObjectProxy ;
16:
17: protected function GetSOAP2_loadHandler(event:LoadEvent):void
18: {
19: GetSOAP2.GetArea();
20: }
21:
22: protected function GetAreaHandler(event:ResultEvent):void
23: {
24: GetSoap2Result=event.result.Tables.area;
25: }
26: ]]>
27: </fx:Script>
28:
29: <fx:Declarations>
30:
31: <mx:WebService id="GetSOAP2" wsdl="http://localhost:1135/Service1.asmx?wsdl" load="GetSOAP2_loadHandler(event)">
32: <mx:operation name="GetArea" result="GetAreaHandler(event)" />
33: </mx:WebService>
34:
35: </fx:Declarations>
36:
37: </s:Application>
Все работает чудесно, цель достигнута. В среде флекса мы тоже видим результат работы сервиса.
Обратите внимание, что в этом примере мы отказались от использования Microsoft SQL Server - как я неоднократно обьяснял на своем сайте, это НЕ прога для хранения реляционно-нормализованных данных - это прога для создания из секты микрософтовцев КОРМОВОЙ БАЗЫ для Билла Гейтса. Этот сервер устроен так, чтобы так развести программиста и коммерсанта, чтобы в конечном итоге побудить их К ПОКУПКАМ у Билла Гейтса.
Еще один подобный пример использования MySQL вы можете посмотреть у меня на сайте на страничке Избавляемся от базы стандартных пользователей ASP.NET на MS SQL - пример ASP.NET сайта на MySQL.
Наконец, в третьем примере мы проигнорируем разработку индусами не только LINQ и WCF, не только MS SQL, не только NET 4.0, но даже DataSet из NET 2.0 и даже Windows - и создадим Web-сервис на самой быстрой в мире СУБД с открытым исходным кодом PostgreSQL, разметим буфер вручную просто языковыми средствами Бейсика и даже развернем созданную софтину в Linux. На этом примере видно - насколько было бы всем лучше, если бы микрософта просто не существовало. И насколко бы все работало проще и быстрее - если бы в информационной индустрии не гадили своими придумками обьектно-программирующие индусы Билла Гейтса.
Итак, в третьем примере среда нашего веб-сервиса будет еще проще:
- Операционная система (Linux-MONO, Windows-NET)
- Фреймфорк (NET 1.1, NET 2.0, NET 3.0, NET 3.5, NET 4.0)
- Вид веб-сервиса (Web Service, WCF Service, REST Service, WCF Workflow Service, AJAX Enabled WCF Service)
- Способ разметки буфера в памяти (вручную, MS-DataSet, MS-LINQ, MS-Entity, NHibernate)
- СУБД (PostgreSQL, MS SQL, MySQL)
Кроме простейшего синхронного обращения к web-сервису из FLEX(как описано выше) - можно сделать прокси для асинхронного обращения:
Кроме того, на моем сайте вы можете почитать, как сделать КЛИЕНТА к SOAP-WSDL сервису (не только на Flex, как это подразумевается в этом топике):
- Организация SSL транспортного уровня по программно загружаемому клиентскому сертификату - клиент с использованием PostrgreSQL.
- WCF_CLIENT - клиент Web-сервиса (вторая версия)
- Как парсить XML SOAP в MS SQL
- SOAP-WSDL сервис - не всегда лучший способ обмена данными между приложениями. Об альтернативных методах обмена данными (XML,TEXT, JSON, SOCKET, FTP/ZIP и других) вы можете почитать на моей страничке - SOAP/WSDL vs XML data exchange.
|