The post Parse JSON string that represents the Dynamics 365 plugin execution context received in Azure Function appeared first on Microsoft Dynamics 365 Blog.
]]>In our previous blogs of this Integrating Dynamics 365 with Azure Functions series, we have gone through a walkthrough with an example of creating an Azure Function and call the same through the following,
In this blog, we will illustrate how to parse the JSON data that we received in the Azure Function. Let’s consider that we have registered a plugin step on an update of Account record which invoke a WebHook (here in our case Azure Function).
When plugin triggers and invokes a WebHook, three types of data received in the request i.e. Query String, Header Data and Request Body. The Request body contains a string that represents the JSON value of the RemoteExecutionContext class. This class defines the contextual information sent to a remote service endpoint at run-time. Below code snippet reads the content from the HttpRequestMessage and converts the received JSON string to proper deserializable JSON string.
using System.Text; using System.Net; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { log.Info("C# HTTP trigger function processed a request"); string jsonContext = await req.Content.ReadAsStringAsync(); log.Info("Read context: " + jsonContext); jsonContext = FormatJson(jsonContext); log.Info("Formatted JSON Context string: " + jsonContext); return req.CreateResponse(HttpStatusCode.OK, "Success"); } /// <summary> /// Function to convert the unformatted Json string to formatted Json string /// </summary> /// <param name="unformattedJson"></param> /// <returns>string formattedJsonString</returns> public static string FormatJson(string unformattedJson) { string formattedJson = string.Empty; try { formattedJson = unformattedJson.Trim('"'); formattedJson = System.Text.RegularExpressions.Regex.Unescape(formattedJson); } catch (Exception ex) { throw new Exception(ex.Message); } return formattedJson; }
Remark: Add reference of System.Text so that we can use Regex expression.
Below is the sample JSON string.
{ "BusinessUnitId": "f0bf3c9a-8150-e811-a953-000d3af29fc0", "CorrelationId": "39499111-e689-42a1-ae8a-5b14a84514ce", "Depth": 1, "InitiatingUserId": "df010dad-f103-4589-ba66-76a5a04c2a11", "InputParameters": [ { "key": "Target", "value": { "__type": "Entity:http:\/\/schemas.microsoft.com\/xrm\/2011\/Contracts", "Attributes": [ { "key": "telephone1", "value": "1111" }, { "key": "accountid", "value": "ec4e2f7d-9d60-e811-a95a-000d3af24950" }, { "key": "modifiedon", "value": "\/Date(1527757524000)\/" }, { "key": "modifiedby", "value": { "__type": "EntityReference:http:\/\/schemas.microsoft.com\/xrm\/2011\/Contracts", "Id": "df010dad-f103-4589-ba66-76a5a04c2a11", "KeyAttributes": [], "LogicalName": "systemuser", "Name": null, "RowVersion": null } }, { "key": "modifiedonbehalfby", "value": null } ], "EntityState": null, "FormattedValues": [], "Id": "ec4e2f7d-9d60-e811-a95a-000d3af24950", "KeyAttributes": [], "LogicalName": "account", "RelatedEntities": [], "RowVersion": null } } ], "IsExecutingOffline": false, "IsInTransaction": true, "IsOfflinePlayback": false, "IsolationMode": 1, "MessageName": "Update", "Mode": 0, "OperationCreatedOn": "\/Date(1527757530151)\/", "OperationId": "08fec203-ec78-4f7a-a024-c96e329a64fe", "OrganizationId": "b0714265-8e72-4d3b-8239-ecf0970a3da6", "OrganizationName": "org94971a24", "OutputParameters": [], "OwningExtension": { "Id": "3db800fe-0963-e811-a95a-000d3af24324", "KeyAttributes": [], "LogicalName": "sdkmessageprocessingstep", "Name": "D365WebHookHttpTrigger: Update of account", "RowVersion": null }, "ParentContext": { "BusinessUnitId": "f0bf3c9a-8150-e811-a953-000d3af29fc0", "CorrelationId": "39499111-e689-42a1-ae8a-5b14a84514ce", "Depth": 1, "InitiatingUserId": "df010dad-f103-4589-ba66-76a5a04c2a11", "InputParameters": [ { "key": "Target", "value": { "__type": "Entity:http:\/\/schemas.microsoft.com\/xrm\/2011\/Contracts", "Attributes": [ { "key": "telephone1", "value": "1111" }, { "key": "accountid", "value": "ec4e2f7d-9d60-e811-a95a-000d3af24950" } ], "EntityState": null, "FormattedValues": [], "Id": "ec4e2f7d-9d60-e811-a95a-000d3af24950", "KeyAttributes": [], "LogicalName": "account", "RelatedEntities": [], "RowVersion": null } }, { "key": "SuppressDuplicateDetection", "value": false } ], "IsExecutingOffline": false, "IsInTransaction": true, "IsOfflinePlayback": false, "IsolationMode": 1, "MessageName": "Update", "Mode": 0, "OperationCreatedOn": "\/Date(1527757524631)\/", "OperationId": "08fec203-ec78-4f7a-a024-c96e329a64fe", "OrganizationId": "b0714265-8e72-4d3b-8239-ecf0970a3da6", "OrganizationName": "org94971a24", "OutputParameters": [], "OwningExtension": { "Id": "63cdbb1b-ea3e-db11-86a7-000a3a5473e8", "KeyAttributes": [], "LogicalName": "sdkmessageprocessingstep", "Name": "ObjectModel Implementation", "RowVersion": null }, "ParentContext": null, "PostEntityImages": [], "PreEntityImages": [], "PrimaryEntityId": "ec4e2f7d-9d60-e811-a95a-000d3af24950", "PrimaryEntityName": "account", "RequestId": "08fec203-ec78-4f7a-a024-c96e329a64fe", "SecondaryEntityName": "none", "SharedVariables": [ { "key": "ChangedEntityTypes", "value": [ { "__type": "KeyValuePairOfstringstring:#System.Collections.Generic", "key": "account", "value": "Update" } ] } ], "Stage": 30, "UserId": "df010dad-f103-4589-ba66-76a5a04c2a11" }, "PostEntityImages": [], "PreEntityImages": [], "PrimaryEntityId": "ec4e2f7d-9d60-e811-a95a-000d3af24950", "PrimaryEntityName": "account", "RequestId": "08fec203-ec78-4f7a-a024-c96e329a64fe", "SecondaryEntityName": "none", "SharedVariables": [], "Stage": 40, "UserId": "df010dad-f103-4589-ba66-76a5a04c2a11" }
Below code snippet deserialize the JSON string to dynamic ExpandoObject.
dynamic dynObj = Newtonsoft.Json.JsonConvert.DeserializeObject(jsonContext);
Simple string type,
log.Info(“BusinessUnitId: ” + dynObj[“BusinessUnitId”]);
or
log.Info(“BusinessUnitId: ” + dynObj.BusinessUnitId);
Complex ParameterCollection type,
log.Info(“InputParameters->Target->LogicalName: ” + dynObj[“InputParameters”][0][“value”][“LogicalName”].ToString());
Below code snippet deserialize the JSON string to RemoteExecutionContext object
#r "bin/Newtonsoft.Json.dll" #r "bin/Microsoft.Xrm.Sdk.dll" #r "bin/System.Runtime.Serialization.dll" using System.Net; using System.Dynamic; using System.Text; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { string jsonContext = await req.Content.ReadAsStringAsync(); log.Info("Read context: " + jsonContext); jsonContext = FormatJson(jsonContext); log.Info("Formatted JSON Context string: " + jsonContext); Microsoft.Xrm.Sdk.RemoteExecutionContext remoteExecutionContext = DeserializeJsonString<Microsoft.Xrm.Sdk.RemoteExecutionContext>(jsonContext); } /// <summary> /// Function to deserialize JSON string using DataContractJsonSerializer /// </summary> /// <typeparam name="RemoteContextType">RemoteContextType Generic Type</typeparam> /// <param name="jsonString">string jsonString</param> /// <returns>Generic RemoteContextType object</returns> public static RemoteContextType DeserializeJsonString<RemoteContextType>(string jsonString) { //create an instance of generic type object RemoteContextType obj = Activator.CreateInstance<RemoteContextType>(); MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)); System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType()); obj = (RemoteContextType)serializer.ReadObject(ms); ms.Close(); return obj; }
Remarks: Add reference of following dlls,
Below code snippet shows how to read values,
//read Plugin Message Name string messageName = remoteExecutionContext.MessageName; //read execution depth of plugin Int32 depth = remoteExecutionContext.Depth; //read BusinessUnitId Guid businessUnitid = remoteExecutionContext.BusinessUnitId; //read Target Entity Microsoft.Xrm.Sdk.Entity targetEntity = (Microsoft.Xrm.Sdk.Entity)remoteExecutionContext.InputParameters["Target"]; //read attribute from Target Entity string phoneNumber = targetEntity.Attributes["telephone1"].ToString(); log.Info("Message Name: " + messageName); log.Info("BusinessUnitId: " + businessUnitid); log.Info("Plugin Depth: " + depth); log.Info("TargetEntity Logical Name: " + targetEntity.LogicalName); log.Info("Phone Number: " + phoneNumber);
The steps given above describes how to Parse JSON string that represents the Dynamics 365 plugin execution context received in Azure Function. To read all blogs about Azure Functions visit: http://bit.ly/inogic-azurefunctions
The post Parse JSON string that represents the Dynamics 365 plugin execution context received in Azure Function appeared first on Microsoft Dynamics 365 Blog.
]]>