Follow my blog for more interesting topics on Dynamics 365, Portals and Power Platform. For training and consulting, write to us at info@xrmforyou.com
In that blog I explicitly mentioned on the problem of using EntityCollection as output parameter and suggested a possible solution to that. After multiple request from my blog readers, I am writing this blog on how you can use EntityCollection as output parameter of your action that you are invoking through flow. Well may not be exact EntityCollection output parameter but you can accomplish the same purpose.
So first – What’s all the problem with EntityCollection as output parameter? This is because when you set output parameter of type EntityCollection, the action would need an output of type Array. If you use EntityCollection as output parameter, you would get an error similar to the one below.
The API operation ‘PerformUnboundAction’ requires the property ‘body’ to be of type ‘Array’ but is of type ‘Object’.
Well Entity Collection contains the list of entity but after all in CRM it is not an array whereas in Flow it is expected as array.
So what is the other option. Well there can be many different ways but the easiest is to get the JSON representation of your entity collection and then parse in back in the flow. So without wasting more time, let’s jump inside the flow.
First of all, I create an action in Dynamics 365 and use and Output parameter named – EntCollString of type string. Observe I am not using the parameter of type EntityCollection but string.
For this demo, I have written a plugin on Post-operation of this plugin. Below is plugin sample code.
var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
var sf = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); var s = sf.CreateOrganizationService(context.UserId);
QueryExpression exp = new QueryExpression
{
EntityName = "account",
TopCount = 10,
ColumnSet = new ColumnSet("name")
};
var results = s.RetrieveMultiple(exp);
var entResults = new List<Tuple<string, Guid>>();
results.Entities.ToList().ForEach(x =>
{
entResults.Add(new Tuple<string, Guid>(x.GetAttributeValue<string>("name"), x.Id));
});
var memoryStream = new MemoryStream();
DataContractJsonSerializer dataContractSerializer = new DataContractJsonSerializer(typeof(List<Tuple<string,Guid>>));
dataContractSerializer.WriteObject(memoryStream, results.Entities.ToList());
memoryStream.Position = 0;
var sr = new StreamReader(memoryStream);
context.OutputParameters["EntCollString"] = sr.ReadToEnd();
If you observe the code, I am taking a list of 10 account, getting their name and id and then passing it back as the output parameter of the action by serializing them into JSON.
Nothing much in that. Offcourse we have less attributes here but you can apply the same with more attributes.
Now comes the important part here. That is the follow. I invoke the action, I get the data in output collection and then parse the JSON.
To parse the JSON, I am using the ParseJSON data operation. For the schema you would need a sample data which you can easily get by doing a test run of your code, getting the JSON result and then generating the schema using “Generate from sample” button.
And then iterating through each item of the JSON array. In the code I have used C# Tuples. And hence the property names came as m_item1 and m_Item2. However if you use a strongly typed class, you shall get the names with the exact property names you have specified in the class.
And that’s all. Now you have same stuff that would you have done using entitycollection as output parameter. Yes a little bit of workaround but certainly worth it.
Hope this helps!
Debajit Dutta
(Microsoft MVP)
Discover more from Debajit's Power Apps & Dynamics 365 Blog
Subscribe to get the latest posts sent to your email.