If you download AX integration samples from GitHub, you’ll see (in JsonConsoleApplication project) that you can call JSON-based custom services by code like this:
var request = HttpWebRequest.Create(ClientConfiguration.Default.UriString + "api/services/UserSessionService/AifUserSessionService/GetUserSessionInfo"); request.Headers[OAuthHelper.OAuthHeader] = OAuthHelper.GetAuthenticationHeader(); request.Method = "POST"; request.GetResponse();
It will call the operation and return its return value as JSON:
{ "$id":"1", "AOSLocaleName":"en-US", "AXLanguage":"EN-US", "Company":"DAT", "CompanyTimeZone":58, "CurrencyInfo": { "$id":"2", "CurrencyCode":"USD", "Description":"US Dollar", "ExchangeRate":100.0, "ISOCurrencyCode":"USD", "Prefix":"","Suffix":"" }, "IsSysAdmin":true, "UserId":"wintermute", "UserPreferredCalendar":0, "UserPreferredTimeZone":18 }
This is what happens when you use the POST method of HTTP; if you switch to GET, you’ll actually get some information about the service.
Therefore if you merely change the value of request.Method:
var request = HttpWebRequest.Create(ClientConfiguration.Default.UriString + "api/services/UserSessionService/AifUserSessionService/GetUserSessionInfo"); request.Headers[OAuthHelper.OAuthHeader] = OAuthHelper.GetAuthenticationHeader(); request.Method = "GET"; request.GetResponse();
you’ll get a very different response:
{ "Parameters":[], "Return": { "Name":"return", "Type":"AifUserSessionInfo" } }
You can see that the operation doesn’t expect any parameters and it returns a single object of AifUserSessionInfo type. This gives you some limited information about how to use this service.
You can also use GET requests to discover existing services and their operations.
/api/services gives you a list of all service groups:
{"ServiceGroups":[{"Name":"AxClient"},…,{"Name":"UserSessionService"}…]}
/api/services/UserSessionService provides a list of services in the service group:
{"Services":[{"Name":"AifUserSessionService"}]}
/api/services/UserSessionService/AifUserSessionService shows all operations of the individual service:
{ "Operations": [ {"Name":"ApplyTimeZone"}, {"Name":"GetAccessRights"}, {"Name":"GetPartitionKey"}, {"Name":"GetPartitionKeysForUser"}, {"Name":"GetUserSessionInfo"}, {"Name":"IsSinglePartitionSystem"}, {"Name":"RemoveTimeZone"} ] }
Don’t forget than opening an URL in browser makes a GET request, therefore you don’t have to write any code to get this kind of information about custom services.
But maybe you would like something a bit more sophisticated, which is the topic of the next post: Open API for JSON-based custom services in AX 7.
I have a custom service in D365 I have created that takes a class and returns a boolean. The request signature when I hit the URL of the service looks like this:
{“Parameters”:[{“Name”:”response”,”Type”:”EmailApprovalResponse”}],”Return”:{“Name”:”return”,”Type”:”Boolean”}}
For some reason, I cannot seem to figure out a way to have it properly parse my request. It always returns a 500 error, and my breakpoint in the service class never seems to get hit. In the debug output window, I’m seeing this:
Exception thrown: ‘Microsoft.Dynamics.Platform.Integration.Services.Xpp.XppServicesParameterNotFoundDeserializationException’ in Microsoft.Dynamics.Platform.Integration.Services.Xpp.dll
The thread 0x1d48 has exited with code 0 (0x0).
The thread 0x79c has exited with code 0 (0x0).
Exception thrown: ‘Microsoft.Dynamics.Platform.Integration.Services.Xpp.XppServicesDeserializationException’ in Microsoft.Dynamics.Platform.Integration.Services.Xpp.dll
So, I’m apparently not calling it properly for it to know it got the proper JSON parameter data. Can you provide a simple example of how that should be done? Or some clues as to what I’m missing?
How can u call like the service UserSessionService/AifUserSessionSevice/RemoveTimeZone?
This service uses two parameters , how do use these parameters in your program who consumes the service?
This is covered in another blog post: http://dev.goshoom.net/en/2017/02/json-based-custom-service-with-parameters/.
How do we send failure response from AX to the caller.
The caller here is consuming D365 json based custom service.
Martin,
I had been struggling to find out a way to get exceptions to end client consuming custom services: Finally found this and this works like a charm – I am planning to write a complete step by step blog as well.
https://community.dynamics.com/365/financeandoperations/f/765/t/291274
Implement comment by Samira Mirza
var request = HttpWebRequest.Create(ClientConfiguration.Default.UriString + “api/services/UserSessionService/AifUserSessionService/GetUserSessionInfo”);
request.Headers[OAuthHelper.OAuthHeader] = OAuthHelper.GetAuthenticationHeader();
request.Method = “POST”;
I use this request but ı dont understand where we find company code in this main code.
same here, did figure it out?
There is nothing like that. If you want a parameter for the company, add it to your data contract and then use it (e.g. changeCompany()) inside the method.
Hi Martin,
Thanks for sharing this useful information. I am working on web services integration where the consumer of web services is BizTalk and when I am exposing my services for them they are having an issue consuming it because of the special character $ added to the response.
{
“$id”:”1″,
Is there any way to remove this $ character from the response.
Assuming that you’re using a data contract class, decorate the class with [Newtonsoft.Json.JsonObjectAttribute(IsReference = false)].
Hi Martin,
I am struggling of find out access “api/services/UserSessionService/AifUserSessionService/GetUserSessionInfo/”. Always facing 401 unauthorized error message. I can get the token without error and have tried also in postman and it was success. But for C# code (using code from github), no luck. In C# code, i am using HttpClient, HttpWebRequest, WebRequest, all of them show same error. Can you please help me, what is the step i missed ?
One more thing, i also follow some instruction in other article to put ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; before hit the request but unfortunately still error.
Thanks in advance, Martin.
Hi Martin, i think i can access my custom service succesfully.
Thanks,
do you mind to share the solution please,
i’m having the same issue here
Please create a thread in discussion forum (https://community.dynamics.com/365/financeandoperations/f/dynamics-365-for-finance-and-operations-forum or https://dynamicsuser.net/ax/), share your code and give us a detailed description of your problem.