Sunday, June 5, 2011

Microsoft Dynamics CRM 2011 : Retrieve Entiy Record Data by Entity Id


While extending Dynamics CRM, retrieving entity information is a very common programming requirement whether we are working with Forms, SDK Plugins or Workflow Custom Assemblies or ASP.Net extensions. In the following sample code we will retrieve entity information by Entity Id via Jscript (can be used in Entity Forms, CRM HTML web resource etc.) and C # code (can be used with in SDK Plugins, Workflow Custom Assemblies, Asp.Net etc.)
Updated Code for Retrieving Lookup Attribute Values
[Jscript Code]

// Only make changes to this function; you may add this function to Form Onload Event,
// Field OnChange events etc.
function GetDetails() {

    var EntityName, EntityId, AccountNumber, AccountEmailAddress, LookupFieldObject;
    var PrimaryContactLookupId, PrimaryContactLookupName, PrimaryContactLookupType;
    var resultXml;

    LookupFieldObject = Xrm.Page.data.entity.attributes.get('parentcustomerid');

    // If lookup field has value then the code will only run
    if (LookupFieldObject.getValue() != null) {

        //Fetch and place Entity Id (GUID) and Name (String) form lookup field into local variables
        EntityId = LookupFieldObject.getValue()[0].id;
        EntityName = LookupFieldObject.getValue()[0].entityType;

        // Paramter explaination for function call
        // RetrieveEntityById('account', AccountId, 'accountnumber,emailaddress1');

        // 1st paramter requires entity name (not display or schema name) just pass it in a string
        // i.e. for Account entity use 'account' for opportunity entity use 'opportunity'

        // 2nd paramter requires entity Id (GUID Type) field which we have retrieved and stored in
        // AccountId local variable

        // 3rd paramter requires attributes to be retrieved schema name, if thrid attributed is
        // required to be retrieved then use like: i.e. 'accountnumber,emailaddress1,telephone2'

        resultXml = RetrieveEntityById(EntityName, EntityId, 'accountnumber,emailaddress1,primarycontactid');

        // In retrieved XML document check if it has accountnumber attribute
        if (resultXml != null && resultXml.selectSingleNode('//q1:accountnumber') != null) {

            // If XML document has account number attribute then assign to local variable AccountNumber
            AccountNumber = resultXml.selectSingleNode('//q1:accountnumber').nodeTypedValue;

            //Display Account Number Value in a Message Box
            alert("Account Number :" + AccountNumber);

            //If required then use the below code line to set value in field on form
            //Xrm.Page.data.entity.attributes.get('new_myaccountnumber').setValue(AccountNumber);
        }

        // In retrieved XML document check if it has emailaddress1 attribute
        if (resultXml != null && resultXml.selectSingleNode('//q1:emailaddress1') != null) {

            // If XML document has account number attribute then assign to local variable AccountEmailAddress
            AccountEmailAddress = resultXml.selectSingleNode('//q1:emailaddress1').nodeTypedValue;

            alert("Email Address :" + AccountEmailAddress);

            //If required then use the below code line to set value in field on form
            //Xrm.Page.data.entity.attributes.get('new_myemailaddress').setValue(AccountEmailAddress);
        }

          // In retrieved XML document check if it has primarycontactid lookup attribute
        if (resultXml != null && resultXml.selectSingleNode('//q1:primarycontactid') != null) {

            // If XML document has primarycontactid lookup attribute then assign to local variable
            PrimaryContactLookupId = resultXml.selectSingleNode('//q1:primarycontactid').nodeTypedValue;

            // If XML document has primarycontactid lookup attribute then assign to local variable
            PrimaryContactLookupName = resultXml.selectSingleNode('//q1:primarycontactid').getAttribute("name");

            // If XML document has primarycontactid lookup attribute then assign to local variable
            PrimaryContactLookupType = resultXml.selectSingleNode('//q1:primarycontactid').getAttribute("type") ;

            alert("Primary Contact Lookup Id :" + PrimaryContactLookupId);

            alert("Primary Contact Lookup Name :" + PrimaryContactLookupName);

            alert("Primary Contact Lookup Type :" + PrimaryContactLookupType);
           
        }      

    }
}

// Do not make any changes to this function
function RetrieveEntityById(prmEntityName, prmEntityId, prmEntityColumns) {

    var resultXml, errorCount, msg, xmlHttpRequest, arrayEntityColumns, xmlEntityColumns;

    arrayEntityColumns = prmEntityColumns.split(",");

    for (var i = 0; i < arrayEntityColumns.length; i++) {
        xmlEntityColumns += "<q1:Attribute>" + arrayEntityColumns[i] + "</q1:Attribute>";
    }

    var authenticationHeader = Xrm.Page.context.getAuthenticationHeader();

    //Prepare the SOAP message.
    var xml = "<?xml version='1.0' encoding='utf-8'?>" +
    "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'" +
    " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
    " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
    authenticationHeader +
    "<soap:Body>" +
    "<Retrieve xmlns='http://schemas.microsoft.com/crm/2007/WebServices'>" +
    "<entityName>" + prmEntityName + "</entityName>" +
    "<id>" + prmEntityId + "</id>" +
    "<columnSet xmlns:q1='http://schemas.microsoft.com/crm/2006/Query' xsi:type='q1:ColumnSet'>" +
    "<q1:Attributes>" +
    xmlEntityColumns +
   "</q1:Attributes>" +
    "</columnSet>" +
    "</Retrieve></soap:Body></soap:Envelope>";

    //call function to create Soap Request to ms crm webservice
    xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
    xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/Retrieve");
    xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
    xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
    xmlHttpRequest.send(xml);

    resultXml = xmlHttpRequest.responseXML;

    var errorCount = resultXml.selectNodes('//error').length;

    if (errorCount != 0) {
        var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
        alert("Error Message : " + msg);
    }
    else {
        return resultXml;
    }
}



14 comments:

  1. very useful article, thank you for posting it.

    I do have a question though.
    On Line 27, you have the code:
    Xrm.Page.data.entity.attributes.get('new_myaccountnumber').setValue(AccountNumber);
    for updating fields on the page - which works very well. However, how would I update a field that is a lookup?

    Example: if I use this code on the QUOTE entity and get the GUID from the Account for OwnerID, how can I update the OwnerID on the QUOTE form with the returned data from the account.

    I am looking online for the solution but if you have time to answer, it would be appreciated.

    Thanks
    Matt
    themattpod@gmail.com

    ReplyDelete
  2. Hi,

    You set the value in Owner Field using the following code below:

    var lookupData = new Array();

    //Create an Object add to the array.

    var lookupItem = new Object();

    //Set the id, typename, and name properties to the object.

    // Make sure to replace UserId variable with User GUID value or assign User GUID to it
    lookupItem.id = UserId;

    lookupItem.typename = "systemuser";

    // Make sure to replace UserName variable with User Name value or assign User Name to it
    lookupItem.name = UserName;

    // Add the object to the array.

    lookupData[0] = lookupItem;

    // Set the value of the lookup field to the value of the array.

    Xrm.Page.getAttribute("ownerid").setValue(lookupData);

    ReplyDelete
  3. Hi, It's really helpful article thanks for posting . However wanted to ask you that i want to retrieve the values tax on invoice entity by selecting the price list from look up view and on price list there is another look up view which will give me the rate of tax on invoice entity. So i am a little confused on retrieving values from double look up view. so please can you guide me? thanks

    ReplyDelete
  4. I think I'm in love with you. This has helped me soooo much !

    ReplyDelete
  5. Hi,

    instead of parsing the responce xml "by hand" you could use one of the following libraries:

    - CrmRestKit.js (OData)[http://crmrestkit.codeplex.com/]
    - CrmFetchKit.js (SOAP) [http://crmfetchkit.codeplex.com/]

    Daniel

    ReplyDelete
  6. Hi Daniel,

    Thank you for posting the links to the kits :), this post is little older, was published on June, 2011 and the purpose was to help understanding the SOAP Retrieve request.

    ReplyDelete
  7. Thank you very much , the code works like cream and excellent explantion.

    Query-
    I created a custome entity new_contact on Lead form in order to fetch required field value(Email,telephone) from Contact to Lead.
    I am tryiing to get the values of a Parent Customer(lookup) from Contact entity to Lead Entity in Company Name(Text).
    The Schema name for Parent Customer is parentcustomerid, which is a guid value. How can we get the Value in Text?

    Thanks in Advance.

    ReplyDelete
  8. Thank you very much for the post, it works fine.
    If i have optionset, then i am getting its' value not the lable.
    could you please show me how to display optionset label.

    Thanks

    ReplyDelete
  9. Hello Jehanzeb Javeed ,
    Thank you very much for your post .Saved me a ton of work .However ,this seems to be working on IE only .Other browsers seem not to support this .Any modifications that could assist ?

    Regards,
    Patrick Mwangi

    ReplyDelete
  10. good post but dont work in cross browser

    ReplyDelete


  11. I am new to CRM and I have a question on how to auto populate text from lookup value.

    I went through many forum, and got solution for 2 entites, but i am looking for 4 entities mentioned below:



    In our CRM instance, there are 4 entities mentioned below:

    Case

    Location

    Finance Region Location

    Finance Region

    Case has N:1 Relationship with Location and Finance Region.

    Location has 1:N relationship with Finance Region Location.

    Finance Region Location has N:1 relationship with Finance Region.

    When user select one value in Location lookup in case form, Finance Region should be auto populate

    for example: if user enter asia as location, in finance region field(Read only text box) APAC as finance Region should be autopopulate.



    Could you please let me know help to write javascript code to autopopulate Finance Region text box Please help me out
    Thanks in advance

    ReplyDelete
  12. good post but don't work with CRM 2013

    ReplyDelete
  13. good post but don't work with CRM 2013

    ReplyDelete