The Microsoft Dynamics Web API has a lot of promise, allowing users to authenticate using OAuth2, then granting your application access to their CRM data. Unfortunately, the documentation provided by Microsoft is misleading at best.
After bashing my head against the wall for about ten hours, I got a response back from a Microsoft developer with the following working solution, which I’ve padded-out and am sharing here to hopefully save somebody else the headache.
Here’s the working code sample, just drop in as a standard ActionResult
in your MVC project – no other code is required/involved.
public async Task<ActionResult> GetAccountsFromDynamics()
{
var azureTenantGuid = "***";
var clientID = "***";
var tokenRequestUrl = string.Format(@"https://login.microsoftonline.com/{0}/oauth2/token",
azureTenantGuid);
var crmUrl = "https://your_crm_url.dynamics.com";
var userName = "***";
var password = "***";
var request = (HttpWebRequest)WebRequest.Create(tokenRequestUrl);
request.Method = "POST";
using (var reqStream = await request.GetRequestStreamAsync())
{
var postData = string.Format(@"client_id={0}&resource={1}&username={2}&password={3}&grant_type=password",
clientID, crmUrl, userName, password);
var postBytes = new ASCIIEncoding().GetBytes(postData);
reqStream.Write(postBytes, 0, postBytes.Length);
reqStream.Close();
}
var accessToken = "";
using (var response = (HttpWebResponse)request.GetResponse())
{
var dataStream = response.GetResponseStream();
if (dataStream != null)
{
var reader = new StreamReader(dataStream);
var json = reader.ReadToEnd();
var tokenSummary = json.FromJson<TokenSummary>();
accessToken = tokenSummary.access_token;
}
}
var apiBaseUrl = "https://your_crm_url.dynamics.com/api/data/v8.1/";
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var result = await httpClient.GetAsync(apiBaseUrl + "accounts?$select=name&$top=3");
var accountInfoJson = await result.Content.ReadAsStringAsync();
return Content(accountInfoJson);
}