【转】D365 FO第三方集成(三)---服务实现
D365 FO的Custom?Service的實(shí)現(xiàn)比AX2012簡(jiǎn)單了很多。
AX2012服務(wù)方法要用屬性SysEntryPointAttribute標(biāo)記,添加到Services以后,還要發(fā)布服務(wù)并在系統(tǒng)管理入站端口添加操作,服務(wù)運(yùn)行在CIL下,所以每次改動(dòng)服務(wù)方法的代碼都要增量生成CIL。
AX2012只支持SOAP,不支持Restful,個(gè)人偏愛Restful,主要是SOAP的代理類在不同的平臺(tái)有說不清道不明的問題,在AX2012的時(shí)候,我是通過.NET?WCF封裝了一下,把SOAP封裝成了Restful的服務(wù)。
在D365?FO這些問題都不是問題了,任何類都可以直接添加到Services節(jié)點(diǎn),服務(wù)方法不需要再用SysEntryPointAttribute標(biāo)記。只要把Services節(jié)點(diǎn)添加到Service Groups,D365?FO就直接把類里的方法
暴露成SOAP和Json-Based服務(wù)。
D365?FO沒有稱呼Restful服務(wù)而是稱為json-based服務(wù)。
Restful和json-based這兩個(gè)東西不是一個(gè)層面的東西,Restful是一種網(wǎng)絡(luò)應(yīng)用程序的設(shè)計(jì)風(fēng)格和開發(fā)方式,Restful的數(shù)據(jù)傳輸既可以用json也可以用xml,也可以用其他格式。
在.NET WCF?Restful實(shí)現(xiàn)里是通過Content-Type來識(shí)別的。根據(jù)Content-Type來決定調(diào)用方傳過來的數(shù)據(jù)是什么格式的,可以是xml,json,也可以是text/plain。
D365?FO里的服務(wù)稱為Json-base服務(wù),顧名思義調(diào)用服務(wù)方法的時(shí)候入?yún)⒑头祷刂刀急仨毷呛戏ǖ膉son格式。
這個(gè)跟WCF Restful的RequestFormat和ResponseFormat格式指定Json,http?request的ContentType指定為json是一樣的。
框架負(fù)責(zé)反序列化和序列化,個(gè)人不是很喜歡這種方式,異常不是很容易捕獲,如果第三方傳入的數(shù)據(jù)有問題,序列化失敗會(huì)內(nèi)部錯(cuò)誤500,不好排錯(cuò)。
另外第三方提供的入?yún)⒁膊灰欢ň褪呛戏ǖ膉son格式,可能就是一堆沒有規(guī)律的字符串,傳入以后再作分析可能更方便。
WCF?Restful可以直接接收text/plain,方法入?yún)⒂肧ystem.IO.Stream,接收以后再做分析。
既然D365?FO只支持Json格式,我覺得把第三方提供的數(shù)據(jù)都作為一個(gè)字符串,封裝到j(luò)son里,作為一個(gè)入?yún)魅?#xff0c;方法接收以后再根據(jù)數(shù)據(jù)情況分析可能更靈活。
當(dāng)然這個(gè)每個(gè)人都有自己的偏好,怎么實(shí)現(xiàn)都可以。
以D365提供的示例代碼為例說明步驟:
1.創(chuàng)建類Class1,添加方法
?
1 class Class12 {3 public str EchoString(str input)4 {5 return input;6 }7 8 public ComplexContract1 GetComplexContract()9 { 10 ComplexContract1 complexContract = new ComplexContract1(); 11 List contractList = new List(Types::Class); 12 Contract1 contract = new Contract1(); 13 contract.parmStringMember("SomeString"); 14 contractList.addEnd(contract); 15 contract = new Contract1(); 16 contract.parmStringMember("SomeString2"); 17 contractList.addEnd(contract); 18 complexContract.parmContractList(contractList); 19 return complexContract; 20 } 21 22 public ComplexContract1 EchoComplexContract(ComplexContract1 input) 23 { 24 return input; 25 } 26 27 [AifCollectionTypeAttribute('return', Types::Class, classStr(Contract1))] 28 public List GetContractList() 29 { 30 List contractList = new List(Types::Class); 31 Contract1 contract = new Contract1(); 32 contract.parmStringMember("SomeString"); 33 contractList.addEnd(contract); 34 contract = new Contract1(); 35 contract.parmStringMember("SomeString2"); 36 contractList.addEnd(contract); 37 return contractList; 38 } 39 40 [AifCollectionTypeAttribute('return', Types::Class, classStr(Contract1)), 41 AifCollectionTypeAttribute('input', Types::Class, classStr(Contract1))] 42 public List EchoContractList(List input) 43 { 44 return input; 45 } 46 47 }?
因?yàn)镈365?FO目前(10.0.0.10)還不支持泛型,所以List作為入?yún)⒑头祷刂档臅r(shí)候,需要用屬性指定List里class的類型,這樣通知序列化框架應(yīng)該用哪個(gè)類進(jìn)行序列化和反序列化。
試了一下,D365?FO(10.0.0.10)的服務(wù)方法已經(jīng)支持返回.NET的類型了,所以在C#里定義一個(gè)繼承泛型List的類,用來做入?yún)⒑头祷刂?#xff0c;這樣也就不用List了。
不過正如前文說的,個(gè)人不是很喜歡直接返回實(shí)體,入?yún)⒑头祷刂抵苯佑米址苯印?br /> 所以我自己封裝的話,都會(huì)是這樣的方法
至于序列化和反序化還是在方法體內(nèi)進(jìn)行吧。
2.定義Service
在Project里新增Service,然后關(guān)聯(lián)Class1
?
?3.新增Service?Group,把Service1添加到Service?Group
編譯程序,服務(wù)器端的代碼就這么簡(jiǎn)單。
下一篇blog介紹一下客戶端如何調(diào)用服務(wù)器端方法。
總結(jié)
以上是生活随笔為你收集整理的【转】D365 FO第三方集成(三)---服务实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1万元存一年多少利息?2020年银行存款
- 下一篇: 【转】01Teams的前世今生