Nov 17, 2013

Plug-in – Check context in Early bound & Late bound approaches

I previously provided a nice descriptive article on developing plug-ins using Dynamics CRM toolkit. I tried the same approach for CRM 2013 online in both early bound and late bound approaches which worked fine. New SDK\Tools\DeveloperToolkit provides the latest toolkit you can install. Then you get the project templates for CRM 2013 in Visual Studio.


Here I am coding to create a task when opportunity is updated.

Early Bound Sample code;

protected void ExecutePostOpportunityUpdate(LocalPluginContext localContext)
{
if (localContext == null)
{
    throw new ArgumentNullException("localContext");
}

IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
    Opportunity _Opportunity = ((Entity)context.InputParameters["Target"]).ToEntity<Opportunity>();
    try
    {
        // Create Task
        Task _task = new Task();
        _task.Subject = "opportunity changed";
        _task.RegardingObjectId = new EntityReference(Opportunity.EntityLogicalName, _Opportunity.Id);
        _task.Description = "Please look into this opportunity changes";
        service.Create(_task);
    }
    catch (FaultException ex)
    {
        throw new InvalidPluginExecutionException("Plug-in error : ", ex);
    }

    finally
    {
        _Opportunity = null;
    }
}
}

Late Bound Sample code;

protected void ExecutePostOpportunityUpdate(LocalPluginContext localContext)
 {
  if (localContext == null)
  {
      throw new ArgumentNullException("localContext");
  }

  IPluginExecutionContext context = localContext.PluginExecutionContext;
  IOrganizationService service = localContext.OrganizationService;

  if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
  {
      Entity entity = (Entity)context.InputParameters["Target"];
     try
      {
          // Create Task
          Entity task = new Entity("task");
          task["subject"] = "opportunity changed (Late)";
          task["regardingobjectid"] = new EntityReference("opportunity", (Guid)entity.Attributes["opportunityid"]);
          task["description"] = "Please look into this opportunity changes";
          service.Create(task);
      }
      catch (FaultException ex)
      {
          throw new InvalidPluginExecutionException("Plug-in error : ", ex);
      }
      finally
      {
          entity = null;
      }
  }
}

Late Bound – Early Bound argument could be as meaningless as Cannon-Nikon argument in photography!

Whatever you do, if you can do it wiser, it matters. Anyway, I am happy to illustrate one simple mistake one could do if not understood clearly, when coding with early bound approach.

When coding plug-ins one of the crucial things is to identify if an attribute exists in the context. Typically, in update message, we need to know if a field is changed by inspecting the context. In late bound, we do it this way and it works fine;

Entity entity = (Entity)context.InputParameters["Target"];
if (entity.Contains("currentsituation"))
{
    //Code
}

In early bound, we usually cast the context in to our entity type.


After casting we see all the fields in intelligence, yet it doesn’t say they are available. They are available only if they exist in the context.

This can be misleading. In other words below is NOT the way to do something if currentsituation field is changed.

Opportunity _Opportunity = ((Entity)context.InputParameters["Target"]).ToEntity<Opportunity>();
if (_Opportunity.CurrentSituation != null)
{
    // Code
}

So, checking the context has to be done in the late bound manner (as shown, using Contains keyword). Keep in mind, when we say field exist in the context, that means “its presence”. Still its value can be NULL or NOT NULL, which has to be checked as next step, depending on your requirement.

Nov 10, 2013

Dynamics CRM toolkit for CRM online

This is an amazing step by Microsoft to leverage the development effort especially in online department. From here you can download the needful stuff.

Also check this article for one of the clear explanations on how to get started;

http://mscrmshop.blogspot.com.au/2012/01/step-by-step-plugin-tutorial-using.html

Workflow that waits till a date in the record

This is something cool. If I elaborate this a bit; this will allow you to trigger something on an important day like contract end date or etc. This can actually replace the need of a windows service that checks something periodically.

Of course I wrote something similar sometimes back, but it is practically bad. It could make new instance again and again till the exact date reaches.

Now it is just one line waiting statement that does the magic.

Typical example I tried is to put a flag for insurance records when they reach expiry date.
 
In CRM 2011, it will be like this;
 
 
In CRM 2011 online it will be like this;

 
In CRM 2013 online
 
 
If you check the record after creation you will see the waiting statement in the workflow tab.
 
 
Since expiry date can be changed later on, it is also advisable to trigger on Update as well as on Create. If a user changes the expiry date later on, you will see an extra waiting record.
 
 
Anyway, as I tested, it worked for the correct expiry date.