24.01.2012, 12:33 | #1 |
Administrator
|
AX 2012 Создание сервиса по шагам
Выделено из AX2012: сервисы и чудеса системного метода DictMethod.parameterCnt()
Я тоже тут столкнулся с граблями. Мануал написан не очень корректно. Но я дошел до конца и получил рабочий пример. Суть: Есть класс, публикуемый как сервис. В данном примере - это AddressUtility. Есть класс, который является типом возвращаемого значения одного из методов публикуемого класса. В данном примере - это AddressFinder. Идея данного примера: Из Visual Studio (внешнего приложения) идет запрос к АХ (т.е. АХ получает некоторые входящие данные, о которых в данном примере почему-то не упоминается). Затем АХ как-то должна вернуть эти данные. Так вот, АХ инициализирует тут класс AddressFinder и в него "напихивает" данные (аналогично оператору Struct в С++ / классу Struct в Х++). UPD: Зачеркнул некорректную фразу. Однако, стоит заметить, что выражение, указываемое в квадратных скобках действительно является классом в Х++. Соответственно, как было бы правильно написать в мануале: 0. Задача: Получить по коду клиента его имя (в связи с тем, что поле CustTable.Name теперь "уехало" в DirPartyTable и чтобы получить имя клиента - теперь нужно сделать джойн CustTable и DirPartyTable). 1. Создаем класс Tutorial_ServiceData, который будет состоять из двух переменных с их parm-методами: X++: [DataContractAttribute] class Tutorial_ServiceData { CustName custName; CustAccount custAccount; } [DataMemberAttribute] public CustAccount parmCustAccount(CustAccount _custAccount = custAccount) { custAccount = _custAccount; return custAccount; } [DataMemberAttribute] public CustName parmCustName(CustName _custName = custName) { custName = _custName; return custName; } X++: class Tutorial_Service { } [SysEntryPointAttribute, AifCollectionTypeAttribute('_custAccount', Types::String, extendedtypestr(CustAccount))] public Tutorial_ServiceData getCustData(CustAccount _custAccount) { Tutorial_ServiceData tutorial_ServiceData; CustTable custTable; ; custTable = CustTable::find(_custAccount); tutorial_ServiceData = new Tutorial_ServiceData(); tutorial_ServiceData.parmCustAccount(custTable.AccountNum); tutorial_ServiceData.parmCustName(custTable.name()); return tutorial_ServiceData; } У сервиса нужно указать ExternalName - его название "снаружи". В моем случае - это Tutorial_LabService 4. Публикуем группу сервисов Tutorial_ServiceGroup (щелкаем правой кнопкой мыши по группе и выбираем пункт Deploy Service Group). По сути - это и есть процедура генерации CIL. Теперь наш сервис доступен по пути _http://localhost:8101/DynamicsAx/Services/Tutorial_ServiceGroup (это если порт "Services WDSL" в настройках АОСа указан 8101). 5. В проект Visual Studio (я создавал новый - типа консольное приложение) добавляем ссылку на нашу группу сервисов. В узел Service References добавляем новую ссылку и указываем что наша группа сервисов будет внутри консольного приложения называться Tutorial_Reference: 6. По добавленной ссылке в проекте кликаем правой кнопкой мыши и смотрим ее в Object Browser: 7. Пишем в Visual Studio следующий код (здесь идет обращение к нашему сервису уже по External Name): PHP код:
Небольшая подстава тут с суффиксом Client у переменной сервиса - с ходу не догадаешься.
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 24.01.2012 в 18:12. |
|
|
За это сообщение автора поблагодарили: mazzy (5), Logger (25), lev (13), AvrDen (1), MikeR (3), gl00mie (10), wojzeh (2), greench (1), kornix (1), AP-1055D (1), (1). |
24.01.2012, 16:54 | #2 |
Участник
|
мегапример! думаю, всем пригодится. приеду на работу -- проверю.
пока могу точно сказать, что твоё предположение о том, что: "За количество параметров отвечает "волшебная" фраза [DataMemberAttribute] перед началом метода. Это класс в Х++. Я так понимаю - что именно оттуда тянется "лишний" параметр." неверно, если мы всё ещё говорим о DictMethod.ParamCnt(). после того, как я просто немного поменял имя "невалидного" метода, всё пошло без проблем. подозреваю, что где-то в глубинах мироздания что-то вроде кеша мешает жить спокойно. (очистка стандартными SysFlush* на клиенте и сервере ничего не дала)
__________________
Felix nihil admirari |
|
|
За это сообщение автора поблагодарили: sukhanchik (4). |
24.01.2012, 18:03 | #3 |
Administrator
|
Виноват. Спутал с SysEntryPointAttribute. Спасибо за замечание. Откорректировал исходный пост, чтобы не вводить в заблуждение последующих читателей.
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 24.01.2012 в 18:13. |
|
24.01.2012, 23:01 | #4 |
Участник
|
а вот такой вопрос о мастере создания сервисов: нужно ли городить весь огород с генерацией на базе запроса всех этих классов, чтобы, например, просто изменить значения в той же таблице inventTable? (client.read(), client.update())
__________________
Felix nihil admirari |
|
25.01.2012, 00:08 | #5 |
Administrator
|
Цитата:
Т.е. для ситуации, когда интегрируются 2 системы в онлайн-режиме и инициатором интеграции является не АХ - то вариант сервисов - пожалуй будет наиболее удобен, нежели какие-либо другие варианты (опять-таки - тут вопрос авторизации и т.д.). К примеру, интеграция АХ (2009) с Lotus в онлайн режиме - в моем случае после перебора всех возможных вариантов - свелась к единственному варианту - через веб-сервис. Ибо иные варианты не работали по тем или иным причинам.
__________________
Возможно сделать все. Вопрос времени |
|
25.01.2012, 01:29 | #6 |
Участник
|
да, у меня как раз такой случай, когда внешняя система хочет менять и создавать записи в таблице EcoResProduct, InventTable etc, и понятно, что веб-сервис в таком случае будет вполне уместен, но мой вопрос был о том, что стоит ли использовать визард для создания всех этих артефактов или проще руками всё нарисовать?
__________________
Felix nihil admirari |
|
25.01.2012, 01:53 | #7 |
Administrator
|
Цитата:
Сообщение от wojzeh
да, у меня как раз такой случай, когда внешняя система хочет менять и создавать записи в таблице EcoResProduct, InventTable etc, и понятно, что веб-сервис в таком случае будет вполне уместен, но мой вопрос был о том, что стоит ли использовать визард для создания всех этих артефактов или проще руками всё нарисовать?
__________________
Возможно сделать все. Вопрос времени |
|
14.11.2012, 12:44 | #8 |
северный Будда
|
упп
Немного приподниму тему
DAX2012. Возникла идея добавить на корпоративный сайт формочку создания клиента. Ну т.е. сайн открывают, вбивают название и адрес клиента, нажимают "Подтвердить" - и в Аксапте генерится новый клиент (я упрощаю, конечно, но общий смысл такой). Для этой цели был создан и успешно развёрнут сервис. Т.е. я дошёл до п.5. А вот что делать дальше? Как с веб-страницы запустить этот сервис, да ещё и с параметрами? Возможно, вопрос глупый, но я никогда раньше веб-разработкой не занимался. Подскажите, плз.
__________________
С уважением, Вячеслав |
|
15.11.2012, 10:03 | #9 |
Участник
|
Если эта веб страница создана в VS, то надо добавить в проект ссылку на сервис, также как вы добавляете ссылки на другие сборки.
|
|
15.11.2012, 13:14 | #10 |
северный Будда
|
а если на php?
__________________
С уважением, Вячеслав |
|
15.11.2012, 13:37 | #11 |
Участник
|
Не то?
PHP код:
|
|
15.11.2012, 15:08 | #12 |
северный Будда
|
спс за помощь. ссылка на сервис, конечно, есть
код попробую обязательно. сразу хочу уточнить - какая его часть параметризует вызов? P.S. блин, как тяжело смотреть на незнакомый язык программирования...
__________________
С уважением, Вячеслав |
|
15.11.2012, 15:34 | #13 |
Участник
|
|
|
25.08.2021, 11:56 | #14 |
Участник
|
Пункт 4.
У сервиса нужно указать ExternalName - его название "снаружи". В моем случае - это Tutorial_LabService Проблема у меня в файле ХМL есть строка <Action>http://tempuri.org/ExportSalesForecastService/read</Action> Пространство имен + Сервис + Метод Так вот интересует именно то что указан метод read хотя в этом сервисе нет этого метода. Там метод create, в ах 2009 есть настройка внешний код там указывается сервис и метод. Подскажите где эта настройка в ах 2012? В таблице AifAction есть запись там есть поле ExternalAction в нем указан метод read. |
|
25.08.2021, 17:36 | #15 |
Administrator
|
Цитата:
Сообщение от Nick42
Пункт 4.
У сервиса нужно указать ExternalName - его название "снаружи". В моем случае - это Tutorial_LabService Проблема у меня в файле ХМL есть строка <Action>http://tempuri.org/ExportSalesForecastService/read</Action> Пространство имен + Сервис + Метод Так вот интересует именно то что указан метод read хотя в этом сервисе нет этого метода. Там метод create, в ах 2009 есть настройка внешний код там указывается сервис и метод. Подскажите где эта настройка в ах 2012? В таблице AifAction есть запись там есть поле ExternalAction в нем указан метод read.
__________________
Возможно сделать все. Вопрос времени |
|
26.08.2021, 11:54 | #16 |
Участник
|
Извиняюсь не проверил что написал а написал что попало(.
Речь идет о внешнем сервисе который указывается в свойствах сервиса поле ExternalName. Так вот указываю имя сервиса который должен принять XML. Обновляю сервис появляется запись в таблице AifAction и в ней поле есть внешний код (ExternalAction) туда попадает значение Read. А из таблицы AifService берется значение сервиса AifService.Name и AifService.Namespase. так собирается в ХМЛ строка ниже. <Action>http://tempuri.org/ExportSalesForecastService/read</Action> В ней записан сервис базы с которого идет отправка XML и метод его а мне нужен тот сервис что я указал в поле ExternalName и его метод. Вопрос есть ли настройки этого или я их найти не могу? Последний раз редактировалось Nick42; 26.08.2021 в 12:13. |
|
26.08.2021, 12:26 | #17 |
Участник
|
Далее нашел в классе AifMessage метод initializeOperationContext в нем исправил(пока не знаю правильно или нет) код. Класс на sys слое изменил сервис на service.ExternalName и изменил поле в таблице AifAction.ExternalAction на create было read. но тут проблема после обновления сервиса в Регистрациях услуг поле это опять становится read.
После этих действий в ХМЛ вышла правильная строка которая мне нужна. |
|
Теги |
aif, ax2012, dictmethod, web сервис, webservice, законченный пример |
|
|