Getting Started with Web API – Tips, tricks to troubleshoot your code.
WebAPI is now part of Dynamics 365 since a long time. I will try to present some scenarios through the series including Jscript and C#. Today I will be covering an example to code using WebAPI (with Jscript) and troubleshoot at the same time.
Let’s take an example of searching an account in Dynamics 365. Bring up your VS code Editor and starting writing below code:
function SearchAccounts() { var strSearch = document.getElementById("txtAccountName").value; var clientUrl = Xrm.Page.context.getClientUrl(); var req = new XMLHttpRequest(); req.open("GET", encodeURI(clientUrl + "/api/data/v8.2/accounts?$select=name&$filter=contains(name,'" + strSearch + "')")); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.onreadystatechange = function () { if (this.readyState == 4) { req.onreadystatechange = null; if (this.status == 200) { var data = JSON.parse(this.response); var intDataCount = data.value.length; alert(intDataCount + " account(s) found with the string " + strSearch); if (intDataCount > 0) { if (data && data.value) { for (var accountCount = 0; accountCount < data.value.length; accountCount++) { var accountName = data.value[accountCount].name; var eTag = data.value[accountCount]['@odata.etag']; } } else { var error = JSON.parse(this.response).error; Xrm.Utility.alertDialog("An Error Occurred"); } } else { //if the account does not exist then call create function CreateIfNotAvailable(strSearch); } } } }; req.send(null); }
Note: The below was written in HTML WebResource and not on the form load. The program has been distributed *as is* to help the community members and do not certify to be used for Production Use.
Most often the first thing which comes to mind in troubleshooting any breaking-code change is using IE Developer Tools or Firebug (Firefox). There are many things you can do to perfect your code.
- Use Browser to build your ODATA Queries:
You can use your organization endpoint to build the queries you want to use in your code, here are few examples:
- List all accounts:
https://demo.crm.dynamics.com/api/data/v8.2/accounts
- List all account which is equal to ‘Demo Account 1’
- List all account which contains name as ‘Demo’
https://demo.crm.dynamics.com/api/data/v8.2/accounts?$select=name&$filter=contains(name,%27Demo%27)
Here’s the sample of the result you will see on your browser:
{ "@odata.context":"https://demo.crm.dynamics.com/api/data/v8.2/$metadata#accounts(name)","value":[ { "@odata.etag":"W/\"645937\"","name":"Demo Account 1","accountid":"86808a4f-3aa4-e611-80d7-c4346bac4304" },{ "@odata.etag":"W/\"645907\"","name":"Demo Account","accountid":"5159ffca-30a4-e611-80d7-c4346bad526c" } ] }
You will notice the (‘) single quotes are converted into ASCII format over the browser and then the result is presented. This is the reason why we use “Encode” function when using in JScript.
req.open("POST", encodeURI(clientUrl + "/api/data/v8.2/accounts"), true); req.open("GET", encodeURI(clientUrl + "/api/data/v8.2/accounts?$select=name&$filter=contains(name,'" + strSearch + "')"));
Dynamics 365 uses OData standard and most of them are supported. You can see the complete list of operations on this article.
Note: This is a subset of the system query options described in the “11.2.4.2.1 Expand Options” section of OData Version 4.0 Part 1: Protocol Plus Errata 02. The options $skip, $count, $search, $expand and $levels aren’t supported for the Web API.
- Use Fiddler to understand your request
When executing your scripts, you can capture Fiddler to dissect your requests and understand what’s going on. The following request will demonstrate the retrieval of account:
Request Header
GET https://demo.crm.dynamics.com/api/data/v8.2/accounts?$select=name&$filter=contains(name,%27Demo%20Account%201%27) HTTP/1.1 Host: demo.crm.dynamics.com Connection: keep-alive Accept: application/json OData-Version: 4.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.87 Safari/537.36 OData-MaxVersion: 4.0 Content-Type: application/json; charset=utf-8 Referer: https://demo.crm.dynamics.com/%7B636140407360000561%7D/WebResources/new_webapidemo.html Accept-Encoding: gzip, deflate, sdch, br Accept-Language: en-US,en;q=0.8
Response Header
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; odata.metadata=minimal Expires: -1 Vary: Accept-Encoding Server: Microsoft-IIS/8.5 REQ_ID: 31a1c587-72ca-4336-abdf-3e440605ed82 OData-Version: 4.0 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Sun, 06 Nov 2016 16:14:32 GMT Content-Length: 239 Strict-Transport-Security: max-age=31536000; includeSubDomains { "@odata.context":"https://demo.crm.dynamics.com/api/data/v8.2/$metadata#accounts(name)","value":[ { "@odata.etag":"W/\"645937\"","name":"Demo Account 1","accountid":"86808a4f-3aa4-e611-80d7-c4346bac4304" } ] }
You can use these fiddler request(s) to map your requirement to these MSDN examples and use them appropriately to meet your business need. The most important part to understand is what HTTP method you need to use when writing samples. I’ve added a list below:
GET - Retrieve
PATCH - Update
POST - Create
I would like to highlight some related documentations that support recommends:
1) Microsoft Dynamics 365 Web API Limitations
3) WebAPI Basic Operations Sample
4) Deprecation announcements with Dynamics CRM Online 2016 Update 1 and Microsoft Dynamics CRM 2016 Service Pack 1
5) WebAPI Samples Blog Announcement.
Hope you enjoyed reading this. Let me know what you think :)
Happy WebAPI’ing.
Thanks
*This post is locked for comments