Ahmed ilyas
Ahmed ilyas

Reputation: 5832

On Create entity, set a property value from an external source so it persists

Using Dynamics 365 and I am doing lots of jumping hoops to get what I need to get done.

Basically for a create contact, I have a plugin which deserializes the Entity object into XML and then posts that XML to a webhook. The webhook does some stuff to another system and gets back an ID. This ID is then returned back to the plugin.

I have set the attribute I want to set this ID in the plugin as such:

 var response = webClient.UploadString(serviceUrl, serializedStr);
                            postMessageImage["po_ContactCRPID"] = response.ToString();

No errors happen, the contact does get created but the field I am interested in updating does not show the value in CRM.

I cannot use the regular webhook function in D365 on post create because the JSON that gets posted does not allow you to serialize back to an object to then be able to nicely pull out the values to then insert into other systems in the backend, so I am trying to use as much of the strongly typed classes as possible.

Any ideas on how to accomplish this? On post operation pipeline, I want to be able to set a property on a contact object (which has custom fields) based on a value returned from some web service so then CRM can create the contact WITH the value I set.

This is my plugin code:

 if (context.PostEntityImages.Contains("CreateContactImage") && context.PostEntityImages["CreateContactImage"] is Entity)
                {
                    tracingService.Trace("AccountSync: CreateContactImage.");

                    Entity postMessageImage = (Entity)context.PostEntityImages["CreateContactImage"];
 using (var client = new WebClient())
                    {
                        var webClient = new WebClient();
                        webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";

                        var code = "CodeFromPlugin";
                        var serviceUrl = this.CRPSyncServiceUrl + "?code=" + code;

                        var entitySeri = new EntitySerializer();
                        var serializedStr = entitySeri.SerializeObject(postMessageImage);
try
                        {
                            // upload the data using Post mehtod
                             //var response = webClient.UploadData(serviceUrl, entityBytes);
                            var response = webClient.UploadString(serviceUrl, serializedStr);
                            postMessageImage["po_ContactCRPID"] = response.ToString();
                            postMessageImage.Attributes["po_ContactCRPID"] = response.ToString();
                            tracingService.Trace("Set postMessageImage po_ContactCRPID to: {0}", response.ToString());
                        }
                        catch (Exception ex)
                        {
                            tracingService.Trace("WebEX Error: {0}", ex.ToString());
                            throw;
                        }
                    }

                }

Upvotes: 2

Views: 1046

Answers (2)

James Wood
James Wood

Reputation: 17562

The image is not the target of the create operation.

The image just gives you a read only snapshot of record values pre or post particular event.

The target gets passed through the event pipeline. The target represents an editable object that gets saved into the database.

For example; if you consider a CreateRequest, it has a target property. This request is basically what happens when the user saves a record.

Entity contact = new Entity("contact");
contact["firstname"] = "James";

CreateRequest cr = new CreateRequest
{
    Target = contact
};

You can access that target in your plugin like so:

Entity target = (Entity)context.InputParameters["Target"];
target.GetAttributeValue<string>("firstname"); //James

You can set values on the target like so:

target["lastname"] = "Wood";

"Wood" will passed along the event pipeline and into the database, if your plugin is registered for sychronous and pre-event. Otherwise (e.g. post-event, asynchronous) when you set the target it's too late - the data has already been saved into the database.

If you can meet those conditions switch to using the target. Otherwise you will need to issue a seperate UpdateRequest.

Entity update = new Entity("contact");
update.Id = target.Id;
update["lastname"] = "Wood";

Service.Update(update);

Upvotes: 2

In asynchronous post-create plugin you will have EntityId in target which is just created Contact.

Get the ID from webhook response, then compose a new Contact object, set the attribute & service.Update will save it.

Entity contact = new Entity(“contact”);
contact.Id = target.Id;
contact[“webhook_Idfield”] = ID;
service.Update(contact);

Upvotes: 4

Related Questions