Sunday, July 17, 2016

Open Dynamics CRM Form Using Alternative Key

The introduction of alternative keys in Dynamics CRM 2015 give us the ability to add unique identifier fields to entities in CRM. This is particularity useful when you need to store an unique identifier from an external system against a CRM record. At the same time the Upsert command was added to the SDK to facilitate updating records in Dynamics CRM from external applications using alternative keys. You no longer needed to store or lookup the Dynamics CRM Id when the accessing CRM data using the SDK.

Another typical requirement when integrating Dynamics CRM with external systems is to create a hyper link in the external system to open the corresponding record in CRM.  In this post I am going show how you can do this using the alternative key rather than the CRM Id.
This is accomplished by opening a HTML web resource page in CRM passing the alternative key as a parameter and using this to retrieve the CRM Id which is then used to open the form.

In this example I created a HTML web resource page called OpenFormAltKey and added a hyperlink in my external system that opens this page and passes the alterative key of the current record. HTML web resource can only accept a single custom parameter called data so the alternative key need to be encoded in the data parameter,

When the page loads it runs a Javascript function called GetDataParameters to decode the parameters and extract the alternative key. It then calls the function openformWithAlternativeKey which does a Web Api call to get the CRM ID for the account record with the alternative key. It then calls the openEntityForm method to open the account form for the CRM Id. 


    document.onreadystatechange = function () {  
      if (document.readyState == "complete") {  
        var params = getDataParameters();  
        openFormWithAlternativeKey(params["altkey"]);  
      }  
    }  

You take this example and expand it so the entity name and form name could also be passed as parameters making it much more generic and flexible. more code below
   function openFormWithAlternativeKey(altKey) {  
      var req = new XMLHttpRequest();  
      req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/accounts?$select=accountid&$filter=new_externalreference eq '" + altKey + "'", true);  
      req.setRequestHeader("OData-MaxVersion", "4.0");  
      req.setRequestHeader("OData-Version", "4.0");  
      req.setRequestHeader("Accept", "application/json");  
      req.setRequestHeader("Content-Type", "application/json; charset=utf-8");  
      req.setRequestHeader("Prefer", "odata.include-annotations=\"OData.Community.Display.V1.FormattedValue\"");  
      req.onreadystatechange = function () {  
        if (this.readyState === 4) {  
          req.onreadystatechange = null;  
          if (this.status === 200) {  
            var results = JSON.parse(this.response);  
            for (var i = 0; i < results.value.length; i++) {  
              var accountid = results.value[i]["accountid"];  
              Xrm.Utility.openEntityForm("account", accountid);  
            }  
          }  
        }  
      };  
      req.send();  
    }  
    function getDataParameters() {  
      var dict = new Object();  
      var vals = new Array();  
      if (location.search != "") {  
        vals = location.search.substr(1).split("&");  
        for (var i in vals) {  
          vals[i] = vals[i].replace(/\+/g, " ").split("=");  
        }  
        for (var i in vals) {  
          if (vals[i][0].toLowerCase() == "data") {  
            vals = decodeURIComponent(vals[i][1]).split("&");  
            for (var i in vals) {  
              vals[i] = vals[i].replace(/\+/g, " ").split("=");  
              dict[vals[i][0]] = vals[i][1];  
            }  
            break;  
          }  
        }  
      }  
      return dict;  
    }  

2 comments:

  1. What the difference if a used a regular custom string field to store this alternate key?
    There is no some built in function to open record whth this new "id field".. in any case i need to query the main "accountid".. so - i dont see any any diferences here..

    ReplyDelete
  2. Hi Michael,

    From MSDN "Alternate keys use database indexes to enforce uniqueness and optimize lookup performance" you cannot enforce uniqueness with a regular field. Also you can use the Upsert command which will insert or update a record based on the Alt Key. AltKeys were a great addition to Dynamics CRM for system integration.

    You are right you could use this technique with a regular field

    ReplyDelete