API enhancement – Service.Update Message in CRM 2015 Update 1

By | May 11, 2015

Introduction:

For updating an existing record in Dynamics CRM, we have always had the Service.Update message. Pass in the entity object and it would update the corresponding record back in CRM. This message however only allowed you to update regular fields. CRM has always had some special fields like Status, Owner etc that could not be updated using the Update Message. These had special messages in the SDK to update the values.

To update Owner, use Assign request

To update Status, use the SetState request.

In this current release, the API has been update, to remove the need to execute special messages for Status and Owner and instead we can now update these by setting these fields and passing them as a part of the Update request to CRM.

Code Sample differences:

Updating the rating, the Owner and the status of the contact record in Dynamics CRM

Entity contact = new Entity();

 

//specify the entity logical name

contact.LogicalName = “contact”;

 

//specify the contact that need to be updated

contact.Id = new Guid(“A925C42D-CFE4-E411-80E8-C4346BAD5414”);

 

//Set the fax field

contact[“fax”] = “412”;

 

//Call the update message

service.Update(contact);

//Call the Assign to change the owner

AssignRequest assign = new AssignRequest

{

Assignee = new EntityReference(SystemUser.EntityLogicalName, _otherUserId),

Target = new EntityReference(Contact.EntityLogicalName,new Guid(“A925C42D-CFE4-E411-80E8-C4346BAD5414”))

};

// Execute the Request

_service.Execute(assign);

//Now change the status

// Create the Request Object

SetStateRequest state = new SetStateRequest();

EntityReference contactReference = new EntityReference()

{

LogicalName = Contact.EntityLogicalName,

Id = new Guid(“A925C42D-CFE4-E411-80E8-C4346BAD5414”)

};

state.EntityMoniker = contactReference

// Set the Request Object’s Properties

state.State = new OptionSetValue(1);

state.Status = new OptionSetValue(2);

 

// Execute the Request

_service.Execute(state);

 

As you can see, it took 3 separate request to get these 3 fields updated.

With the new API you can simply perform all of these three with a single Update request

Entity contact = new Entity();

 

//specify the entity logical name

contact.LogicalName = “contact”;

 

//specify the contact that need to be updated

contact.Id = new Guid(“A925C42D-CFE4-E411-80E8-C4346BAD5414”);

 

//set the fax

contact[“fax”] = “412”;

//change the owner of the contact

contact[“ownerid”] = new EntityReference(“systemuser”, new Guid(“FB8C44BF-B0E9-E411-80ED-C4346BAD5414”));

 

//change the status to inactive

contact[“statecode”] = new OptionSetValue(1);

 

//change the state to inactive

contact[“statuscode”] = new OptionSetValue(2);

 

//update the contact

service.Update(contact);

 

Impact on Plugins:

The SetState and Assign request have always called the Update request also internally. This means, if you had a plugin registered on SetState, Assign and Update message of the “Contact” entity. The sample code above would have executed the SetState and Update, both plugins for just the SetState request. Similarly the Assign would have executed the plugin registered on both Assign as well as Update message. So it was the Update message that was executed irrespective of which fields or through which message a record was updated in Dynamics CRM.

The new API Update message, will not internally execute the SetState or Assign request if you were to execute the above sample code to update the owner and the status. So any previous plugins registered on the SetState or the Assign request will be have to re-registered on the Update message, should you plan to start using the new Update message to update the owner and status as well.

When you change the owner or the state of the record from CRM UI, it still executes the SetState and Assign Plugin, so it does not impact there.

The new API would not execute the SetState or Assign message plugin, BUT, it will call an UPDATE request for each of these messages i.e the sample code above would result in the UPDATE plugin being executed thrice.

1st time for the updating Fax – This time, the target would receive only the Fax field (non-owner/non-status fields)

2nd time for the Owner – only the owner field is available in Target

3rd time for the state – This time only status fields are passed in Target.

The following sample plugin code, would help you understand how to identify for which field the plugin has been triggered.

// Check if plugin context contains the Target

if (context.InputParameters.ContainsKey(“Target”))

{

Entity targetContactEntity = (Entity)context.InputParameters[“Target”];

string desc = “”;

if (targetContactEntity!= null)

{

// When fired for owner change

if (targetContactEntity.Attributes.ContainsKey(“ownerid”))

{

desc = “Owner changed”;

}

// When fired for status change

if (targetContactEntity.Attributes.ContainsKey(“statecode”))

{

desc = “Status Changed”;

}

// Create Task activity

Entity task = new Entity(“task”);

task[“subject”] = “Task from plugin : ” + desc;

_service.Create(task);

}

}

 

  1. Once for all non -owner / non-status fields i.e. “fax” – When fired for rest of these fields the target entity attribute does not contain “owner” and “statecode”. Hence the “Task” which we are creating in this plug-in is created with subject – “Task from plug-in”.
  2. Once for owner field change – When fired for owner field the target entity attribute will only contain updated owner field. So here we can find out if the plug-in has been fired for owner field change by checking for if the target entity attribute contains “ownerid” as done in above plug-in code. Hence the “Task” is created with subject – “Task from plug-in : Owner changed”.
  3. Once for Status field change – When fired for status field the target entity attribute will only contain updated status field. So here we can find out if the plug-in has been fired for status field change by checking for if the target entity attribute contains “statecode” as done in above plug-in code. Hence the “Task” is created with subject – “Task from plug-in : Status changed”.

     

So total 3 tasks will be created on single update request executed in the sample code above. The depth each time would be 1.

Impact on Workflow:

  1. Workflows registered for the Assign message by users continue to be triggered by updates to owner fields.
  2. Workflows containing the Change Status step continue to be triggered by updates to state/status fields.

For example:

If you have a workflow registered to execute when a record is assigned, updating the owner of the record using “Update” operation would trigger the workflow. Similarly for the Status changes workflow, they are triggered as well when the state is changed using the new Update message.

Conclusion:

  • Allows to change the Status, State, Owner, Business Unit and Manager using a single Update operation.
  • Reduces the code complexity.
  • Additional service calls to the CRM are reduced thereby improving performance.