Connecting Dynamics 365 Web api using external HTML page


Here we are discussing on how we can connect Dynamics 365 Web Api using external application. Below are the steps we need to follow in order to achieve our goal.
Note: if the HTML page is not giving any result or not able to load browser cache (CRM user token) then your need to clear Brower cache and try to load HTML again.



 1.       Login in to https://portal.azure.com
2.       Provide your CRM username and password to log in into azure. Once you login create an application as below screen shot
Azure Active DirectoryàApp RegistrationàClick on New application registration

3.       Provide Name, select Application Type as “Web App / API” and provide Sing –on URL as CRM URL as below.


4.       Open the newly created application and click on Settings.

5.       Click on Keys and provide “Description” as key name and “Expires” as Never expires. Once you click on Save it generates a key. make sure you copy the key otherwise it will be hidden for the next time.


6.       Open the same application and click on settings. Click on Reply URL’s and provide the complete URL from where you are calling (your client application URL).



7.       Copy the Appicaiton ID/Client ID, your application URL paste in html code.


    After every set up done copy below HTML code and try to run on your browser.

<!DOCTYPE html>
<html>
<head>
<title>Simple SPA</title>
<meta charset="utf-8" />
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.0/js/adal.min.js"></script>

<!--<script src="adal.js"></script>-->
<script>
"use strict";
//Set these variables to match your environment
var organizationURI = "https://agsfstrainings.crm8.dynamics.com"; //The URL to connect to CRM Online
var tenant = "agsfstrainings.onmicrosoft.com"; //The name of the Azure AD organization you use
var clientId = "c58b9636-71ea-4588-be48-39538d6488a1"; //The ClientId you got when you registered the application
var pageUrl = "http://localhost:60347//HtmlPage1.html"; //The URL of this page in your development environment when debugging.
var user, authContext, message, errorMessage, loginButton, logoutButton, getAccountsButton, accountsTable, accountsTableBody;
var accountsQuery = "/api/data/v8.0/accounts?$select=name,address1_city&$top=10";
var apiVersion = "/api/data/v8.0/";
//Configuration data for AuthenticationContext
var endpoints = {
orgUri: organizationURI
};
window.config = {
tenant: tenant,
clientId: clientId,
postLogoutRedirectUri: pageUrl,
endpoints: endpoints,
cacheLocation: 'localStorage', // enable this for IE, as sessionStorage does not work for localhost.
};
document.onreadystatechange = function () {

if (document.readyState == "complete") {
//Set DOM elements referenced by scripts
message = document.getElementById("message");
errorMessage = document.getElementById("errorMessage");
loginButton = document.getElementById("login");
logoutButton = document.getElementById("logout");
//getAccountsButton = document.getElementById("getAccounts");
accountsTable = document.getElementById("accountsTable");
accountsTableBody = document.getElementById("accountsTableBody");
//Event handlers on DOM elements
loginButton.addEventListener("click", login);
logoutButton.addEventListener("click", logout);
//getAccountsButton.addEventListener("click", getAccounts);
//call authentication function
authenticate();
if (user) {

loginButton.style.display = "none";
logoutButton.style.display = "block";
//getAccountsButton.style.display = "block";
var helloMessage = document.createElement("p");
helloMessage.textContent = "Hello " + user.profile.name;
message.appendChild(helloMessage)
}
else {
loginButton.style.display = "block";
logoutButton.style.display = "none";
//getAccountsButton.style.display = "none";
}
}
}
// Function that manages authentication
function authenticate() {
//OAuth context
authContext = new AuthenticationContext(config);
// Check For & Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash);
if (isCallback) {
authContext.handleWindowCallback();
}
var loginError = authContext.getLoginError();
if (isCallback && !loginError) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
else {
errorMessage.textContent = loginError;
}
user = authContext.getCachedUser();
}
//function that logs in the user
function login() {
authContext.login();
}
//function that logs out the user
function logout() {
authContext.logOut();
accountsTable.style.display = "none";
accountsTableBody.innerHTML = "";
}
//function that initiates retrieval of accounts
function getAccounts() {

//getAccountsButton.disabled = true;
var retrievingAccountsMessage = document.createElement("p");
retrievingAccountsMessage.textContent = "Retrieving 10 accounts from " + organizationURI + "/api/data/v8.0/accounts";
message.appendChild(retrievingAccountsMessage)
// Function to perform operation is passed as a parameter to the aquireToken method
authContext.acquireToken(organizationURI, retrieveAccounts)
}
//function that initiates retrieval of accounts
function getAccounts() {

//getAccountsButton.disabled = true;
var retrievingAccountsMessage = document.createElement("p");
retrievingAccountsMessage.textContent = "Retrieving 10 accounts from " + organizationURI + "/api/data/v8.0/accounts";
message.appendChild(retrievingAccountsMessage)
// Function to perform operation is passed as a parameter to the aquireToken method
authContext.acquireToken(organizationURI, retrieveAccounts)
}
function createContacts() {

var retrievingAccountsMessage = document.createElement("p");
retrievingAccountsMessage.textContent = "Creating contact record....!";
//getAccountsButton.disabled = true;

message.appendChild(retrievingAccountsMessage)
// Function to perform operation is passed as a parameter to the aquireToken method
authContext.acquireToken(organizationURI, createContactRecords)
}
function createContactRecords(error, token) {

// Handle ADAL Errors.
if (error || !token) {
errorMessage.textContent = 'ADAL error occurred: ' + error;
return;
}
var contactObj = {};
contactObj["firstname"] = "Bangar";
contactObj["lastname"] = "Raju";
contactObj["parentcustomerid_account@odata.bind"] = "/accounts(475B158C-541C-E511-80D3-3863BB347BA8)";
var req = new XMLHttpRequest()
//"/api/data/v8.2/" + entityPlurarName, false
req.open("POST", encodeURI(organizationURI + apiVersion + "contacts"), true);
//Set Bearer token
req.setRequestHeader("Authorization", "Bearer " + token);
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.send(JSON.stringify(contactObj));
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {

req.onreadystatechange = null;
if (req.status === 204) {

var uri = req.getResponseHeader("OData-EntityId");
var regExp = /\(([^)]+)\)/;
var matches = regExp.exec(uri);
var contactId = matches[1];
var retrievingAccountsMessage = document.createElement("p");
retrievingAccountsMessage.textContent = "Contact record created successfully with ID:" + contactId;
message.appendChild(retrievingAccountsMessage)
}
else {
var error = JSON.parse(this.response).error;
console.log(error.message);
errorMessage.textContent = error.message;
}
}
};
}
//Function that actually retrieves the accounts
function retrieveAccounts(error, token) {

// Handle ADAL Errors.
if (error || !token) {
errorMessage.textContent = 'ADAL error occurred: ' + error;
return;
}
var req = new XMLHttpRequest()
req.open("GET", encodeURI(organizationURI + accountsQuery), true);
//Set Bearer token
req.setRequestHeader("Authorization", "Bearer " + token);
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 accounts = JSON.parse(this.response).value;
renderAccounts(accounts);
}
else {
var error = JSON.parse(this.response).error;
console.log(error.message);
errorMessage.textContent = error.message;
}
}
};
req.send();
}
//Function that writes account data to the accountsTable
function renderAccounts(accounts) {
accounts.forEach(function (account) {
var name = account.name;
var city = account.address1_city;
var nameCell = document.createElement("td");
nameCell.textContent = name;
var cityCell = document.createElement("td");
cityCell.textContent = city;
var row = document.createElement("tr");
row.appendChild(nameCell);
row.appendChild(cityCell);
accountsTableBody.appendChild(row);
});
accountsTable.style.display = "block";
}

function doOperationOnCRM() {
var e = document.getElementById("crmOperation")
var typeOfOperation = e.options[e.selectedIndex].value
var retrievingAccountsMessage = document.createElement("p");
retrievingAccountsMessage.textContent = '';
switch (typeOfOperation) {
case "1": getAccounts();
break;
case "2": //To Do
break;
case "3": createContacts(); break;
case "4": break;//To Do
default:
}
}
</script>
<style>
body {
font-family: 'Segoe UI';
}

table {
border-collapse: collapse;
}

td, th {
border: 1px solid black;
}

#errorMessage {
color: red;
}

#message {
color: green;
}
</style>
</head>
<body>
<button id="login">Login</button>
<button id="logout" style="display:none;">Logout</button>
<br />
<select id="crmOperation" onchange="doOperationOnCRM()">
<option value="0">---Select---</option>
<option value="1">Retrieve Accounts</option>
<option value="2">Execute Fetch to get Accounts</option>
<option value="3">Create Contacts</option>
<option value="4">Create Task</option>
</select>
<button id="getAccounts" style="display:none;">Get Accounts</button>
<table id="accountsTable" style="display:none;"> <thead><tr><th>Name</th><th>City</th></tr></thead> <tbody id="accountsTableBody"></tbody> </table>
<div id="errorMessage"></div>
<div id="message"></div>
</body>
</html>


If you are already logged in to your browser with CRM credentials then automatically it reads user token from your local browser and "Logout" button will appear other wise "Login" button will appear.

Once you click on "Retrieve Accounts" then it will display as below.


Comments

  1. I am actually getting ready to across this information, is very helpful my friend. Also great blog here with all of the valuable information you have. Keep up the good work you are doing here.
    CRM Software in Dubai
    CRM Software
    CRM Software in UAE
    Best CRM Software in Dubai

    ReplyDelete
  2. I looked on the internet for the difficulty and found most individuals will associate with along with your website.Keep update more excellent posts.
    CRM Software In India
    CRM Software In Chennai
    CRM Software
    CRM Software In Bangalore
    Best CRM Software

    ReplyDelete
  3. This blog sheds light on the significance of an HR and payroll management system in the UAE. With businesses striving for streamlined HR processes and accurate payroll management, this software is undoubtedly a game-changer. As a reliable Microsoft partner, we understand the importance of efficient HR solutions.

    ReplyDelete

Post a Comment

Popular posts from this blog

Get azure blob files inside Sub Directories

Interview questions on MS CRM