24.01.2012, 00:09 | #1 |
Участник
|
AX2012: сервисы и чудеса системного метода DictMethod.parameterCnt()
пытаюсь создать свой сервис и затем задеплоить его через сервисную группу, как написано в мануале What's New - Technical in Microsoft Dynamics® AX 2012 for Development в его 5 главе Chapter 5: Services and Application Integration.
Цитата:
Step by Step: Create the Data Contract Class
1. Open Microsoft Dynamics AX 2012. 2. Open a Developer workspace. 3. Open the AOT. 4. Create a new class named AddressFinder. 5. Enhance the class by adding the [DataContractAttribute] attribute. 6. Enter a method called Address which returns the address. 7. Enhance the method by adding the [DataMemberAttribute] attribute. X++: [DataMemberAttribute] public str address() { return "Demo Address"; } 1. Create a new class named AddressUtility. This is the service class. 2. Create a public method named getNearestLocation. This method instantiates the AddressFinder object and returns the AddressFinder object. 3. Enhance the class by adding the [SysEntryPointAttribute] attribute. X++: [SysEntryPointAttribute] public AddressFinder getNearestLocation() { AddressFinder addressFinder = new AddressFinder(); return addressFinder; } 1. Right-click the Services node in the AOT and select New Service. 2. Change the Name property to AddressService. 3. Set the Class property to AddressUtility. 4. Expand the AddressService service node. 5. Right-click the Operations node and select Add Operations. 6. Check the Add checkbox and click OK. 7. Right-click the Services Group node in the AOT and select New Service Group. 8. Change the Name property to AddressServiceGroup. 9. Drag the service under the service group node. 10. Right-click the AddressServiceGroup service group and select Deploy service group. X++: /// <summary> /// Microsoft internal use only. /// </summary> /// <param name="dictMethod">An instance of the <c>SysDictMethod</c> class.</param> /// <returns>A <c>boolean</c> Enumeration Type.</returns> static boolean isValidDataMember(SysDictMethod dictMethod) { // Alex Voytsekhovskiy (WMP) (2012/01/20) (Demande #) //--> Types retType, parType; int retId, parId; int parCnt; boolean res, allRes; str msg; ; res = dictMethod.compiledOk(); if (!res) { msg = "Not complied"; throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } res = dictMethod.utilElementType() == UtilElementType::ClassInstanceMethod; if (!res) { msg = "Not ClassInstanceMethod"; throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } res = dictMethod.accessSpecifier() == AccessSpecifier::public; if (!res) { msg = "Not Public method"; throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } parCnt = dictMethod.parameterCnt(); res =parCnt == 1; if (!res) { msg = strFmt("Not One and only one input parameter = %1", parCnt); throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } res = dictMethod.parameterOptional(1); if (!res) { msg = "Parameter is not optional"; throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } retType = dictMethod.returnType(); parType = dictMethod.parameterType(1); res = retType == parType; if (!res) { msg = strfmt("Return type %1 does not match parameter type %2", retType, parType); throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } retId = dictMethod.returnId(); parId = dictMethod.parameterId(1); res = retId == parId; if (!res) { msg = msg+"; "+ strfmt("Return Id %1 does not match parameter id %2", retId, parId); throw error(strfmt("%1.%2() is not valid DataMember; Errors: %3", dictMethod.parentName(), dictMethod.name(), msg)); } return res; //<-- // return ( // dictMethod.compiledOk() && // Compile OK // dictMethod.utilElementType() == UtilElementType::ClassInstanceMethod && // Instance method // dictMethod.accessSpecifier() == AccessSpecifier::public && // Public method // dictMethod.parameterCnt() == 1 && // One and only one input parameter // dictMethod.parameterOptional(1) && // Parameter is optional // dictMethod.returnType() == dictMethod.parameterType(1) && // Return type matches parameter type // dictMethod.returnId() == dictMethod.parameterId(1)); } X++: [DataMemberAttribute] public str address1(str s ='') { return "Demo Address"; } шутки ради нарисовал рядышком ещё один метод -- однояйцевый близнец предыдущего X++: [DataMemberAttribute] str gimme(str s = '') { ; return "gimme more"; } в этой связи вопрос: куда копать, и зачем методам, который выставляются через сервис вообще нужны параметры? (обратите внимание на проверки в методе) компиляция, forward compilation, CIL, перезапуск клиента, сервера и прочие танцы с бубном уже исполнялись. спасибо.
__________________
Felix nihil admirari |
|
24.01.2012, 13:16 | #2 |
Administrator
|
Перенес ответ в отдельную тему AX 2012 Создание сервиса по шагам
__________________
Возможно сделать все. Вопрос времени |
|
26.02.2013, 14:58 | #3 |
MCT
|
Дошел и мой черед до этого примера.
На самом деле все оказалось проще. Покопавшись в стандарте, нашел что всего-то надо было добавить X++: [AifDocumentReadAttribute, SysEntryPointAttribute] public AddressFinder getNearestLocation() { AddressFinder addressFinder = new AddressFinder(); return addressFinder; } У суханчика пример более расширенный.
__________________
Axapta book for developer |
|
|
За это сообщение автора поблагодарили: Logger (1). |
Теги |
aif, ax2012, dictmethod, web сервис, webservice, законченный пример |
|
|