Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: How to use the Dynamics 365 Web API from 10.2 Tokyo


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 0
Andrew Hayes

Posts: 1
Registered: 9/23/16
How to use the Dynamics 365 Web API from 10.2 Tokyo  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Apr 9, 2018 1:50 PM
I've now spent several days trying to get some simple odata queries working against a D365 CRM system using Delphi 10.2 and the REST Client Library.

I went through the RESTDemos project and all the options that gave, and I ended up having to do federated access as I don't want to be showing the user the Azure Active Directory login web page, and my application is already configured for Azure, so now have an Access Token, but am having trouble using it properly to perform the odata queries.

https://msdn.microsoft.com/en-us/library/gg327838.aspx

Here's the code for authentication:

  RESTClient.BaseURL := 'https://login.microsoftonline.com/';
 
  RESTRequest.Method := TRESTRequestMethod.rmPOST;
  RESTRequest.Resource := ATenantID + '/oauth2/token';
 
  RESTRequest.Params.AddItem('grant_type', 'client_credentials', TRESTRequestParameterKind.pkGETorPOST);
  RESTRequest.Params.AddItem('client_id', AClientID, TRESTRequestParameterKind.pkGETorPOST);
  RESTRequest.Params.AddItem('client_secret', AClientSecret, TRESTRequestParameterKind.pkGETorPOST);
  RESTRequest.Params.AddItem('resource', AResourceURI, TRESTRequestParameterKind.pkGETorPOST);
 
  RESTRequest.Execute;
 
  if RESTRequest.Response.GetSimpleValue('access_token', AToken) then
    OAuth2_Dynamics365.AccessToken := AToken;


The Response.Content for the above looks like this:

{
"token_type":"Bearer",
"expires_in":"3599",
"ext_expires_in":"0",
"expires_on":"1523244938",
"not_before":"1523241038",
"resource":"https://myurl.crm.dynamics.com",
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyIsImtpZCI6IkZTaW11RnJGTm9DMHNKWEdtdjEzbk5aY2VEYyJ9.eyJhdWQiOiJodHRwczovL25tdGVzdC5jcm02LmR5bmFtaWNzLmNvbSIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzY2YWQ1YTJkLTRlNjctNDUyZS1iNmQzLTYwMmYxMGFiNGIyNi8iLCJpYXQiOjE1MjMyNDEwMzgsIm5iZiI6MTUyMzI0MTAzOCwiZXhwIjoxNTIzMjQ0OTM4LCJhaW8iOiJZMk5nWUhnbjkraHlncU9xK2lIZUw1OGpqdDdOQUFBPSIsImFwcGlkIjoiNDIyY2JkZmMtMjEyOC00YmFlLWEzM2EtOTliYzgxNmQ3NmVkIiwiYXBwaWRhY3IiOiIxIiwiaWRwIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvNjZhZDVhMmQtNGU2Ny00NTJlLWI2ZDMtNjAyZjEwYWI0YjI2LyIsIm9pZCI6IjMyMmEzOWVmLWZmZDctNDNjNi04ZjZhLTU5Zjc1ZjIzNDI1NyIsInN1YiI6IjMyMmEzOWVmLWZmZDctNDNjNi04ZjZhLTU5Zjc1ZjIzNDI1NyIsInRpZCI6IjY2YWQ1YTJkLTRlNjctNDUyZS1iNmQzLTYwMmYxMGFiNGIyNiIsInV0aSI6IjRFVE9fWm1GRTBtNTBIemJNb0lOQUEiLCJ2ZXIiOiIxLjAifQ.Ev0YcgjMvZ_XNudidd1Gi5WrcNRTYeZOwbTBiyZHsoVo5qOsF9tSfAWNiJNouEnfES8Z--tpGWT1TRgrmdF_xR1jtYR4Y9HFiMRXs5K2rkl_aw58kWL5Gxrc-4s3IUHHRU_340wNjKnRjF3n09Naxaj_fJ59zK45ywevop2Xz3waKgKf2_7_C9WRVORYqNLoYIBF9Z6IN5EsJGvvkokUsbTzwU1NaeJ3r9Q5-gGSgBo6SUIGt0PjopgqBqDYSDIQt7AD7uGFjsP_CAtTbFxMaK53_CauoPZdqHnzMqNoA1YRGTzAnWIJh35pqIsm-J1ZuT4FOp1vswoqnY6GhklTKw"
}

Then I want to get a basic list of system users from CRM, so I do this:

  RESTClient.BaseURL := AResourceURI; // has to be the same as the resource parameter from getting the token
 
  ARESTRequest.Resource := 'api/data/v8.2/bookableresources?$select=_userid_value';
 
  RESTRequest.Execute;


Which responds with 401 Unauthorized: Access is Denied.

Reading more details from the msdn website, I found that the HTTP message requests for Dynamics 365 need to have the Authorization header of the request set to the access token and use "Bearer", so I added this line to the code:

  RESTRequest.AddAuthParameter('Authorization', 'Bearer ' + AToken, TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]);


Now the call works, and I get JSON-like odata from Dynamics:

{
"@odata.context":"https://myurl.crm.dynamics.com/api/data/v8.0/$metadata#bookableresources(_userid_value)","value":[
{
"@odata.etag":"W/\"40599496\"","_userid_value":"1648251b-9bff-e611-8107-c4346bc50748","bookableresourceid":"83bf299a-ac3b-e811-8161-e0071b670e51"
},{
"@odata.etag":"W/\"40599510\"","_userid_value":"cbd8b90f-9cff-e611-8109-c4346bc5c21c","bookableresourceid":"0a29b027-ad3b-e811-8161-e0071b670e51"
},{
"@odata.etag":"W/\"40599533\"","_userid_value":"9e311d06-75a1-e711-8136-e0071b6898c1","bookableresourceid":"fc3174eb-ad3b-e811-8161-e0071b670e51"
}
]
}

However, the JSON readers and parsers in the RET Client Library cannot seem to handle the odata format. Is there an update that adds this functionality, where the library looks at the metadata URL to get the information about the fields being returned?
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02