{KnowHow} Execute Upsert request from client side in Dynamics CRM

Upsert request was introduced in Dynamics CRM 2015 Online Update 1 and on-premise customers got a flavour of it from CRM 2016 onwards. After this feature has been introduced, it has been used so much that writing anything on it is now hackneyed.

However just when you feel you have done it 100 times, you may still find that one scenario suddenly popping up which you might have not implemented in your previous projects and this was exactly one of those. My client wanted to fire an Upsert request from the client side. Basically the requirement was, there was a webresource where the user would fill the necessary information for a record and based on the field values entered, an Upsert request would create/ update the record accordingly.

So what do I need here? Well the first thing I need here is the XML request. And how do I get that?  Did you forget about the wonderful SOAP Logger tool that ships with SDK. Yeah and it still works great. Smile

By any chance you are not aware where you can find the SOAP Logger, you can find in your SDK Download in the following folder structure – SDK\SampleCode\CS\Client\SOAPLogger

Let’s take an example here. For account entity, first I create an alternate key with combination of Account Number + Account Name.

image

I open the SOAP logger and run the below code to get the corresponding XML request for Upsert request

SoapLoggerOrganizationService slos = new SoapLoggerOrganizationService(serverConfig.OrganizationUri, service, output);

                              //Add the code you want to test here:
                              // You must use the SoapLoggerOrganizationService ‘slos’ proxy rather than the IOrganizationService proxy you would normally use.

                              KeyAttributeCollection acckeys = new KeyAttributeCollection();

                              acckeys.Add("accountnumber", "ASH001");
                              acckeys.Add("name", "SOAP Logger for Test");
                              Entity account = new Entity("account", acckeys);
                              account["name"] = "SOAP Logger for Test";

                              UpsertRequest upsert = new UpsertRequest();
                              upsert.Target = account;
                              UpsertResponse response = (UpsertResponse)slos.Execute(upsert);

 

Once I run the above code, the below is the XML Request

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <Execute xmlns="
http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <request i:type="a:UpsertRequest" xmlns:a="
http://schemas.microsoft.com/xrm/2011/Contracts">
        <a:Parameters xmlns:b="
http://schemas.datacontract.org/2004/07/System.Collections.Generic">
          <a:KeyValuePairOfstringanyType>
            <b:key>Target</b:key>
            <b:value i:type="a:Entity">
              <a:Attributes>
                <a:KeyValuePairOfstringanyType>
                  <b:key>name</b:key>
                  <b:value i:type="c:string" xmlns:c="
http://www.w3.org/2001/XMLSchema">SOAP Logger for Test</b:value>
                </a:KeyValuePairOfstringanyType>
              </a:Attributes>
              <a:EntityState i:nil="true" />
              <a:FormattedValues />
              <a:Id>00000000-0000-0000-0000-000000000000</a:Id>
             <a:KeyAttributes xmlns:c="
http://schemas.microsoft.com/xrm/7.1/Contracts">
                <c:KeyValuePairOfstringanyType>
                  <b:key>accountnumber</b:key>
                  <b:value i:type="d:string" xmlns:d="
http://www.w3.org/2001/XMLSchema">ASH001</b:value>
                </c:KeyValuePairOfstringanyType>
                <c:KeyValuePairOfstringanyType>
                  <b:key>name</b:key>
                  <b:value i:type="d:string" xmlns:d="
http://www.w3.org/2001/XMLSchema">SOAP Logger for Test</b:value>
                </c:KeyValuePairOfstringanyType>
              </a:KeyAttributes>
              <a:LogicalName>account</a:LogicalName>
              <a:RelatedEntities />
              <a:RowVersion i:nil="true" />
            </b:value>
          </a:KeyValuePairOfstringanyType>
        </a:Parameters>
        <a:RequestId i:nil="true" />
        <a:RequestName>Upsert</a:RequestName>
      </request>
    </Execute>
  </s:Body>
</s:Envelope>

This request is just like any other request for Create/ Update except for the highlighted part. If you notice carefully, you could find a new tag in XML request name KeyAttributes. All you need to do is replace the values of the KeyAttributes

Here is the sample code for the same in javascript

var accountNumber = ‘ASH001’;
var accountName = ‘SOAP Logger for Test’;

var request = [‘<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">’,
  ‘<s:Body>’,
    ‘<Execute xmlns="
http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">’,
      ‘<request i:type="a:UpsertRequest" xmlns:a="
http://schemas.microsoft.com/xrm/2011/Contracts">’,
        ‘<a:Parameters xmlns:b="
http://schemas.datacontract.org/2004/07/System.Collections.Generic">’,
          ‘<a:KeyValuePairOfstringanyType>’,
            ‘<b:key>Target</b:key>’,
            ‘<b:value i:type="a:Entity">’,
              ‘<a:Attributes>’,
                ‘<a:KeyValuePairOfstringanyType>’,
                  ‘<b:key>name</b:key>’,
                  ‘<b:value i:type="c:string" xmlns:c="
http://www.w3.org/2001/XMLSchema">’, accountName, ‘</b:value>’,
                ‘</a:KeyValuePairOfstringanyType>’,
              ‘</a:Attributes>’,
              ‘<a:EntityState i:nil="true" />’,
              ‘<a:FormattedValues />’,
              ‘<a:Id>00000000-0000-0000-0000-000000000000</a:Id>’,
              ‘<a:KeyAttributes xmlns:c="
http://schemas.microsoft.com/xrm/7.1/Contracts">’,
                ‘<c:KeyValuePairOfstringanyType>’,
                  ‘<b:key>accountnumber</b:key>’,
                  ‘<b:value i:type="d:string" xmlns:d="
http://www.w3.org/2001/XMLSchema">’, accountNumber,'</b:value>’,
                ‘</c:KeyValuePairOfstringanyType>’,
                ‘<c:KeyValuePairOfstringanyType>’,
                  ‘<b:key>name</b:key>’,
                  ‘<b:value i:type="d:string" xmlns:d="
http://www.w3.org/2001/XMLSchema">’, accountName, ‘</b:value>’,
                ‘</c:KeyValuePairOfstringanyType>’,
              ‘</a:KeyAttributes>’,
              ‘<a:LogicalName>account</a:LogicalName>’,
              ‘<a:RelatedEntities />’,
              ‘<a:RowVersion i:nil="true" />’,
            ‘</b:value>’,
          ‘</a:KeyValuePairOfstringanyType>’,
        ‘</a:Parameters>’,
        ‘<a:RequestId i:nil="true" />’,
        ‘<a:RequestName>Upsert</a:RequestName>’,
      ‘</request>’,
    ‘</Execute>’,
  ‘</s:Body>’,
‘</s:Envelope>’].join(”);

var req = new XMLHttpRequest();

req.open("POST", Xrm.Page.context.getClientUrl() + "/XRMServices/2011/Organization.svc/web", false);
req.setRequestHeader("Accept", "application/xml, text/xml, */*");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("SOAPAction",
http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute);

req.send(request);

console.log(req.responseText);

 

The below is the response text.

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <ExecuteResponse xmlns="
http://schemas.microsoft.com/xrm/2011/Contracts/Services">
      <ExecuteResult i:type="a:UpsertResponse" xmlns:a="
http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:ResponseName>Upsert</a:ResponseName>
        <a:Results xmlns:b="
http://schemas.datacontract.org/2004/07/System.Collections.Generic">
          <a:KeyValuePairOfstringanyType>
      
     <b:key>RecordCreated</b:key>
            <b:value i:type="c:boolean" xmlns:c="
http://www.w3.org/2001/XMLSchema">false</b:value>
          </a:KeyValuePairOfstringanyType>
          <a:KeyValuePairOfstringanyType>
            <b:key>Target</b:key>
            <b:value i:type="a:EntityReference">
              <a:Id>138f7d7a-1f48-e611-80e9-5065f38be1c1</a:Id>
              <a:KeyAttributes xmlns:c="
http://schemas.microsoft.com/xrm/7.1/Contracts"/>
              <a:LogicalName>account</a:LogicalName>
              <a:Name i:nil="true"/>
              <a:RowVersion i:nil="true"/>
            </b:value>
          </a:KeyValuePairOfstringanyType>
        </a:Results>
      </ExecuteResult>
    </ExecuteResponse>
  </s:Body>
</s:Envelope>

 

In the response, you can find whether the record is created or updated. Please see the highlighted section. I already have an account with same accountnumber and name and hence RecordCreated value has been set to false

 

Hope this helps!

Advertisements

Author: 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