Last week I needed to use a third-party web service in AX2009. I created a service reference in AOT, so AX generated necessary code and configuration and I was immediately able to get data from the service. Quickly done, almost without any work. Great.
But I wouldn’t write about it if that was all. The given web service is to be used interactively – you type some input, the web service is called, data is displayed and so on. Sometimes you also type incorrect input and the services returns a special message with an error code and text describing the problem.
What I expected was getting a FaultException that I would catch and handle in some way. Instead I got the following error:
Type ‘System.ServiceModel.Channels.ReceivedFault’ in assembly ‘System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ is not marked as serializable.
I tried to search the web and I’m obviously not the first one running into this error, but I didn’t find any useful explanation or solution.
So I looked into the actual implementation and discovered that the proxy generated by AX extends the Microsoft.Dynamics.IntegrationFramework.WebService.WebReferenceBase class (in Microsoft.Dynamics.IntegrationFramework.dll). The class creates a new application domain for each web services, which allows – if nothing else – to load the app.config file, but the application domain border obviously cause the problem with the ReceivedFault instance.
I don’t see any way how to use AX-generated service references and avoid the serialization error in the same time. Service references in AX offer nice integrated configuration, but in my case the proper exception handling is more important. Therefore I created a separate .NET class library that references the web services, creates the proxy, sets a binding, an endpoint address and calls the service.
Leaving aside configuration and input validation, the whole implementation is really simple:
public static Object GetData(string input) { using (var client = new MyService_SoapClient( new BasicHttpBinding(), new EndpointAddress("http://somewhere/service.ws"))) { return client.GetData(input); } }
The ReceivedFault is correctly translated to FaultException, which is subsequently sent to AX and can be caught there without any problems.
Although I haven’t tried to use the same web service in AX2012, I don’t expect the same problem there. It’s because AX2012 handles web services very differently from AX2009.
Hello Martin,
This is appears to be the same problem I am seeing when attempting to consume a web service in AX 2009.
Where does this code need to be inserted?
public static Object GetData(string input)
{
using (var client = new MyService_SoapClient(
new BasicHttpBinding(),
new EndpointAddress(“http://somewhere/service.ws”)))
{
return client.GetData(input);
}
}
Thank you.
Herman
Hi Herman, you should use (roughly) these steps:
1) Create a new class library project in Visual Studio.
2) Add a service reference (this will generate the service client).
3) Create a new class and add a single static method (it may by more complex in reality, of course).
4) Call the web service in the method – that’s the part showed in GetData().
5) Build the library and place the DLL to server\bin (and usually to client\bin too, for development purposes).
6) Call the library (i.e. GetData() in my example) from X++ and catch CLR exceptions.
Does this help?
Hi, everybody!
I find out the solution for this problem, in my case the webmethod was returning “TIMEOUT”, and the AIF-AX don’t recognize exception handling correct, and so return the message: Type ‘System.ServiceModel.Channels.ReceivedFault’ in assembly ‘System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ is not marked as serializable.
I expect have helped!