{KnowHow} How to use Discovery Service Web API of Dynamics CRM 2016

Recently I posted in my blog on how to execute Web API queries from external ASP.NET web application to retrieve data. Details could be found here – https://debajmecrm.com/2016/02/29/knowhow-how-to-execute-web-api-calls-to-microsoft-dynamics-crm-from-an-external-asp-net-web-application/.

After this post, people has been asking me to how to leverage the Discovery service Web API with Dynamics CRM 2016. And the most common question being – “Why am I not getting any response when I query for instance data through the Web API?”

Well, let’s jump to an example here. The following is the code for a blog reader sent me. In a web-resource on a form, he simply invoked the webapi endpoint of the discovery service to get the instance details.

function getOrgs() {
    var req = new XMLHttpRequest();
    debugger;
    req.open("GET", “https://disco.crm.dynamics.com/api/discovery/v8.0/Instances”);

    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 /* complete */) {
            req.onreadystatechange = null;
            if (this.status == 200) {
                var discovery = JSON.parse(this.response);
                alert("User Id : " + discovery.Url);
            }
            else {
                var error = JSON.parse(this.response).error;
                alert(error.message);
            }
        }
    };
    req.send();
}

He informed and told that he is getting empty response and also not getting an error.  I took his code and when I inspected through fiddler, I found the following error at the connection level

“Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://xrmtr14.crm.dynamics.com’ is therefore not allowed access”

https://xrmtr14.crm.dynamics.com is my CRM online instance here .

So what is ‘Access-Control-Allow-Origin’ header?

Access-Control-Allow-Origin is a CORS (Cross-Origin Resource Sharing) header.

When Site A tries to fetch content from Site B, Site B can send an Access-Control-Allow-Origin response header to tell the browser that the content of this page is accessible to certain origins. (An origin is a domain, plus a scheme and port number.) By default, Site B’s pages are not accessible to any other origin; using the Access-Control-Allow-Origin header opens a door for cross-origin access by specific requesting origins.

So it’s clear that if you want to access the discovery service web api endpoint from within CRM, the discovery service endpoint would not allow you to do the same since Access-Control-Allow-Origin header is not present in the server response. Also if your really ask me, it makes sense as well. After all why do we need to query the instance in which we are already in.

The question now is why then how can we use the discovery service web Api. If you are well versed with the concept of OAuth, let me tell you the discovery service web api endpoints can also be accessed through OAuth 2.0.

So we will connect to discovery web API endpoint through asp.net web application. Please follow the link – https://debajmecrm.com/2016/02/29/knowhow-how-to-execute-web-api-calls-to-microsoft-dynamics-crm-from-an-external-asp-net-web-application/ as I am going to use the same example for this. The only difference is the code to access the instances.

So all the steps are the same except for the fact that I have added a new button called ‘Get Instance Details’ which when clicked would fetch me the instance details. Below is the code that I wrote in the button event Handler.

 

if (Session["AuthResult"] != null)
            {
                var authResult = (AuthenticationResult)Session["AuthResult"];
                var webRequest = (HttpWebRequest)WebRequest.Create(new Uri("https://disco.crm.dynamics.com/api/discovery/v8.0/Instances”));

                webRequest.Method = "GET";
                webRequest.ContentLength = 0;
                webRequest.Headers.Add("Authorization", String.Format("Bearer {0}", authResult.AccessToken));
                webRequest.Headers.Add("OData-MaxVersion", "4.0");
                webRequest.Headers.Add("OData-Version", "4.0");
                webRequest.ContentType = "application/json; charset=utf-8";

                using (var response = webRequest.GetResponse() as System.Net.HttpWebResponse)
                {
                    //Get reader from response stream
                    using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
                    {
                        var instances = new List<Instance>();
                        string responseContent = reader.ReadToEnd();

                        dynamic dynamicObj = JsonConvert.DeserializeObject(responseContent);

                        foreach (var data in dynamicObj.value)
                        {
                            var instance = new Instance
                            {
                                Url = data.Url,
                                Id = data.Id,
                                FriendlyName = data.FriendlyName,
                                UniqueName = data.UniqueName
                            };

                            instances.Add(instance);
                        }

                        InstanceGrid.DataSource = instances;
                        InstanceGrid.DataBind();
                    }
                }
            }

 

All I have done in the above code block is change the URL to point to the discovery service web API.

 

And this is final screenshot

image

 

Hope this helps!

Advertisements

About Debajit
I am a Dynamics CRM Most Valuable Professional (MVP) with 10 years of experience in Microsoft .NET Technologies and 7 years of dedicated experience in Microsoft Dynamics CRM. I have worked with companies like Microsoft, SanDisk, PwC, TMF Group and have extensive experience of implementing complex CRM solutions from both offshore and client side. Currently the face of XrmForYou.com with significant experience in delivering corporate training on Dynamics CRM and have already delivered multiple projects to client through XrmForYou.com Author of multiple tools on codeplex including the 'Role Based Views' and 'CRM-Sharepoint Metadata manager & Attachment Extractor' which are available for commercial use under XrmForYou.com For consulting/ training, drop me a note at info@xrmforyou.com or visit our website www.xrmforyou.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: