{"id":1593,"date":"2008-04-19T17:06:00","date_gmt":"2008-04-19T17:06:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/cesardelatorre\/2008\/04\/19\/consuming-external-wcf-services-from-dynamics-ax-2009-x-code-dynamics-ax-5-0\/"},"modified":"2008-04-19T17:06:00","modified_gmt":"2008-04-19T17:06:00","slug":"consuming-external-wcf-services-from-dynamics-ax-2009-x-code-dynamics-ax-5-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/consuming-external-wcf-services-from-dynamics-ax-2009-x-code-dynamics-ax-5-0\/","title":{"rendered":"Consuming external WCF Services from Dynamics AX 2009 X++ code (Dynamics AX &#8220;5.0&#8221;)"},"content":{"rendered":"<p><P>I&#8217;m gonna talk about a new feature in Dynamics AX 2009 (Dynamics AX &#8220;5.0&#8221;) which is the really powerful possibility we have now about calling\/consuming external Web Services or even WCF Services from our X++ code.<\/P>\n<P>So, in Dynamics AX 4.0, we could execute external Web Services thanks to the <EM>AIF outbound web service adapters<\/EM>, but we couldn&#8217;t really consume those external Web Services from our X++ code&#8230; You can read a pretty good posting about that matter (AX 4.0 AIF and external Web Services) here:<\/P>\n<P><A title=\"http:\/\/blogs.msdn.com\/dpokluda\/archive\/2006\/10\/03\/Outbound-web-service-_2800_AIF_2900_.aspx\" href=\"http:\/\/blogs.msdn.com\/dpokluda\/archive\/2006\/10\/03\/Outbound-web-service-_2800_AIF_2900_.aspx\">http:\/\/blogs.msdn.com\/dpokluda\/archive\/2006\/10\/03\/Outbound-web-service-_2800_AIF_2900_.aspx<\/A><\/P>\n<P>But the good news are that in AX &#8220;5.0&#8221;, we are able to consume Web-Services and WCF Services from our X++ code almost like if I were consuming it from Visual Studio and a .NET program!!. \ud83d\ude42<\/P>\n<P>So, guess the first thing we need to do that&#8230;, we need a Web-Service!, or even better, a WCF Service!!. I have developed a pretty simple WCF Service using Visual Studio 2008 (in C#).<\/P>\n<P>It is a basic WCF Service about Stock Exchange, so when I provide a stock company Symbol (like MSFT), it would return the company name (like &#8220;Microsoft&#8221;). Of course, this Service&#8217;s business logic is quite dumb, it should access to a database, but in this case I&#8217;m checking just about &#8220;MSFT&#8221; case. But, it is alright as I need any Web Service.<\/P>\n<P>The WCF Service C# code is the following:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"892\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"890\"><STRONG>WCF Service Contract Interface:<BR><\/STRONG>\n<P>[ServiceContract]<BR>public interface IStockExchangeService<BR>{<BR>&nbsp;&nbsp;&nbsp; [OperationContract]<BR>&nbsp;&nbsp;&nbsp; string GeCompanyNameByStockSymbol(string stockSymbol);<BR>}<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>&nbsp;<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"892\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"890\"><STRONG>WCF Service Implementation class:<BR><\/STRONG>\n<P>public class StockExchangeService : IStockExchangeService<BR>{<BR>&nbsp;&nbsp;&nbsp; public string GeCompanyNameByStockSymbol(string stockSymbol)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string companyName; \n<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (stockSymbol)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case &#8220;MSFT&#8221;:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyName = &#8220;Microsoft&#8221;;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; companyName = &#8220;Company&#8217;s Name&#8221;;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } \n<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return companyName;<BR>&nbsp;&nbsp;&nbsp; }<BR>}<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>I have deployed this WCF Service in a regular IIS Web Server, and tested from a simple .NET WinForms App, just to check it was working ok. If you need help\/info about developing and deploying a WCF Service on IIS, take a look at this article:<\/P>\n<P><STRONG>How to: Host a WCF Service in IIS:<\/STRONG> <A title=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms733766.aspx\" href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms733766.aspx\">http:\/\/msdn2.microsoft.com\/en-us\/library\/ms733766.aspx<\/A><\/P>\n<P>OK!, so we have our external WCF Service up and running and we want to consume it from our X++ code within Dynamics AX &#8220;5.0&#8221;, right?.<\/P>\n<P>First thing we need to do is to add a WCF Service Reference to AX development environment, just like if we were doing a &#8220;Add Service Reference&#8221; from Visual Studio. To do so (at least with current BETA AX &#8220;5.0&#8221; version) we need to go (within AX client) to the menu &#8220;Tools&#8211;&gt;Development Tools&#8211;&gt;Application Integration Framework&#8211;&gt;Add Service Reference&#8221;, then we see a pretty simple window for that purpose:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_2.png\"><IMG height=\"227\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb.png\" width=\"409\" border=\"0\"><\/A> <\/P>\n<P>We have to type in all the WCF service info, basically, the URI address (in my case it was <A title=\"http:\/\/dynamicsvpc.contosoent.com\/ExternalWCFWebService\/StockExchangeService.svc?wsdl\" href=\"http:\/\/dynamicsvpc.contosoent.com\/ExternalWCFWebService\/StockExchangeService.svc?wsdl\">http:\/\/dynamicsvpc.contosoent.com\/ExternalWCFWebService\/StockExchangeService.svc?wsdl<\/A>) and a Service reference name\/namespace I want, like &#8220;StockExchangeWcfService&#8221;. Then, press over &#8220;OK&#8221; button, and, yes!, we&#8217;ll have all the proxy artifacts we could need to consume that WCF Service!.<\/P>\n<P>If you want to check about that WCF Service Reference to make sure it has been properly created, you can go to the menu &#8220;Basic&#8211;&gt;Setup&#8211;&gt;Application Integration Framework&#8211;&gt;Service References&#8221; and you&#8217;ll see a Window like the following where you can check it:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_4.png\"><IMG height=\"326\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_1.png\" width=\"871\" border=\"0\"><\/A> <\/P>\n<P>Yo can even configure the WCF Service when pressing the &#8220;Configure Service&#8221; button. And guess what is opened up?, yes!, exactly the same WCF Configuration Tool we can use from Visual Studio 2008! :-), from there we could configure WCF client end-points, changing the binding type (by default, in AX &#8220;5.0&#8221; CTP3, it is using <STRONG>wsHttpBinding <\/STRONG>binding, so it is secured by default based on Windows security and we have Service authentication and messages Encryption &#8220;for granted&#8221;), and so on&#8230;:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_8.png\"><IMG height=\"474\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_3.png\" width=\"860\" border=\"0\"><\/A> <\/P>\n<P>We could use another Binding like &#8220;<STRONG>basicHttpBinding<\/STRONG>&#8221; like if it were a basic Web Service (WS-I Basic Profile), etc., but no need to change it now, ok?<\/P>\n<P>If you&#8217;d want to change any of those parameters, beware that you should change it first on the WCF Service side, because it has to match with it.<\/P>\n<P>Great!, so it is ready for us, now let&#8217;s go to the X++ editor and write some code to consume it!.<\/P>\n<P>First of all, we create a X++ class to encapsulate my Service proxy calls, I always like to do it in this way, even in .NET. This kind of classes are called &#8220;Service-Agents&#8221;, so if in the future something about the Service has changed, you should change it just within your &#8220;Service Agent&#8221; class. That is the purpose of ENCAPSULATION.<\/P>\n<P>This is my X++ &#8220;Service Agent&#8221; class within AOT:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_10.png\"><IMG height=\"76\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_4.png\" width=\"324\" border=\"0\"><\/A> <\/P>\n<P>And my X++ code implementing the <STRONG>GetCompanyNameByStockSymbol()<\/STRONG>:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"927\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"925\">\n<P>public static str <STRONG>GeCompanyNameByStockSymbol<\/STRONG>(str stockSymbol)<BR>{<BR>&nbsp;&nbsp;&nbsp; str companyName;<BR>&nbsp;&nbsp;&nbsp; <STRONG>StockExchangeWcfService.IStockExchangeServiceClient proxy;<\/STRONG><BR>&nbsp;&nbsp;&nbsp; ; \n<P>&nbsp;&nbsp;&nbsp; new InteropPermission(InteropKind::ClrInterop).assert(); \n<P>&nbsp;&nbsp;&nbsp; \/\/ Call the WCF method.<BR>&nbsp;&nbsp;&nbsp; <STRONG>proxy = new StockExchangeWcfService.IStockExchangeServiceClient();<BR>&nbsp;&nbsp;&nbsp; companyName = proxy.GeCompanyNameByStockSymbol(stockSymbol); <\/STRONG>\n<P>&nbsp;&nbsp;&nbsp; CodeAccessPermission::revertAssert(); \n<P>&nbsp;&nbsp;&nbsp; return companyName; \n<P>}<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>I have highlighted in bold letters the most important code lines, I mean, the WCF Service proxy object variable, when instantiating the WCF Service class and, of course, when calling the &#8220;<STRONG>GeCompanyNameByStockSymbol()<\/STRONG>&#8221; Service method.<\/P>\n<P><STRONG>NOTE<\/STRONG>: In AX 2009 CTP3, it generated the same public class name that you have&nbsp;in your .NET WCF Service. But in the RTM version (AX 2009 Release), it seems it generates a class with the name of the interface plus the postfix &#8220;Client&#8221;, in this case &#8220;<STRONG>IStockExchangeServiceClient<\/STRONG>&#8221; instead &#8220;<STRONG>StockExchangeService<\/STRONG>&#8220;. Underneath, it is using an internal class which is kind of &#8220;.NET WCF Client way&#8221;, called &#8220;<STRONG>StockExchangeServiceClient<\/STRONG>&#8220;, but you don&#8217;t need to use this one.<\/P>\n<P>So, for instance, this is the code I was using in CTP3, you can compare it with the one (up above) that works with AX 2009 Release version (RTM):&nbsp;<\/P>\n<P>&nbsp;&nbsp;&nbsp; &#8230;.<\/P>\n<P><STRONG>&nbsp;&nbsp;&nbsp; StockExchangeWcfService.StockExchangeService proxy;<\/STRONG><BR>&nbsp;&nbsp;&nbsp; ; <\/P>\n<P>&nbsp;&nbsp;&nbsp; \/\/ Call the WCF method.<BR>&nbsp;&nbsp;&nbsp; <STRONG>proxy = new StockExchangeWcfService.StockExchangeService();<\/STRONG><\/P>\n<P><STRONG>&nbsp;&nbsp;&nbsp; &#8230;.<\/STRONG><STRONG><BR><\/STRONG>That&#8217;s it, really simple!, those are the most important steps we gotta make (beware we have not finished yet&#8230; keep on reading&#8230; ;-)). <\/P>\n<P>So, just to test our &#8220;Service Agent&#8221; class, we create a new Job, like the following:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"928\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"926\">\n<P>static void CallExternalWcfService(Args _args)<BR>{<BR>&nbsp;&nbsp;&nbsp; str stockSymbol;<BR>&nbsp;&nbsp;&nbsp; str companyName;<BR>&nbsp;&nbsp;&nbsp; ; \n<P>&nbsp;&nbsp;&nbsp; stockSymbol = &#8220;MSFT&#8221;;<BR>&nbsp;&nbsp;&nbsp; \/\/ Call the Service-Agent method.<BR>&nbsp;&nbsp;&nbsp; companyName = StockExchangeServiceAgent::GeCompanyNameByStockSymbol(stockSymbol); \n<P>&nbsp;&nbsp;&nbsp; print(companyName);<BR>&nbsp;&nbsp;&nbsp; pause; \n<P>}<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>And if we just run this Job, guess what&#8230; We&#8217;ll get a cute error!!, something like:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"930\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"928\"><STRONG>&#8220;Stack trace: Unhandled exception 9 was encountered.&#8221;<\/STRONG><BR><BR><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_12.png\"><IMG height=\"169\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_5.png\" width=\"370\" border=\"0\"><\/A> <\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Yep, not very descriptive, right?. :-), ok, but then, we may get these other errors:<\/P>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"932\" border=\"0\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"930\">\n<P><STRONG>&#8220;Clr object is not initialized&#8221;<BR>&#8220;Object &#8216;CLRObject&#8217; could not be created&#8221;<\/STRONG><\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>OK, this is because the proxy artifacts (Service Reference) generated by AX &#8220;5.0&#8221;, is using &#8220;<STRONG>CLR-Interop<\/STRONG>&#8221; underneath, and therefore, our X++ execution should be made within the AOS Server context. Because of we were calling that class from a Job, by default, it was trying to execute that class within the AX client context instead of the AOS Server context&#8230;<\/P>\n<P>So, no problem, let&#8217;s fix it!, what we gotta do is to specify that our &#8220;Service Agent&#8221; class should always be executed within the AOS Server. :-). To do so, we just go to the class properties and change the <STRONG>&#8220;<EM>RunOn<\/EM>&#8221; property<\/STRONG> to <STRONG>&#8220;<EM>Server<\/EM>&#8220;<\/STRONG>, instead of &#8220;<EM>Called from<\/EM>&#8221; (default value) or &#8220;<EM>Client<\/EM>&#8220;, which are not right in this case.<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_16.png\"><IMG height=\"255\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_7.png\" width=\"411\" border=\"0\"><\/A> <\/P>\n<P>And, yeah!, it works now!! \ud83d\ude42<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_18.png\"><IMG height=\"394\" alt=\"image\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/32\/2019\/03\/image_thumb_8.png\" width=\"508\" border=\"0\"><\/A> <\/P>\n<P>&#8220;Microsoft&#8221; is the value returned by my WCF Service when I provide &#8220;MSFT&#8221; as the stock company Symbol.<\/P>\n<P>Of course, you should try now to consume more complicated WCF Services, like getting data subsets (you&#8217;ll have to check data conversions, etc.), and so on..<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m gonna talk about a new feature in Dynamics AX 2009 (Dynamics AX &#8220;5.0&#8221;) which is the really powerful possibility we have now about calling\/consuming external Web Services or even WCF Services from our X++ code. So, in Dynamics AX 4.0, we could execute external Web Services thanks to the AIF outbound web service adapters, [&hellip;]<\/p>\n","protected":false},"author":362,"featured_media":12806,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[89,109],"class_list":["post-1593","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cesardelatorre","tag-soa","tag-wcf"],"acf":[],"blog_post_summary":"<p>I&#8217;m gonna talk about a new feature in Dynamics AX 2009 (Dynamics AX &#8220;5.0&#8221;) which is the really powerful possibility we have now about calling\/consuming external Web Services or even WCF Services from our X++ code. So, in Dynamics AX 4.0, we could execute external Web Services thanks to the AIF outbound web service adapters, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts\/1593","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/users\/362"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/comments?post=1593"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/posts\/1593\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/media\/12806"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/media?parent=1593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/categories?post=1593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cesardelatorre\/wp-json\/wp\/v2\/tags?post=1593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}