A common request amongst our Dynamics CRM Portals customers is the ability to execute custom actions and serverside logic in CRM. There are several ways of communicating with the Dynamics 365 platform:
- entity lists
- entity forms
- liquid fetch queries
- web forms
- …
But it’s still not possible to directly call a custom action from within CRM Portals. Or at least… it wasn’t. We came up with a solution that allows us to call Custom Actions through Liquid.
Calling Custom Actions
When communication with Dynamics 365 through Liquid, we’re limited to retrieval only. This is because Liquid only supports Fetch XML. However, we can work around this by creating a new entity, writing a Fetch XML towards that new entity and creating a plugin on the RetrieveMultiple Message of that plugin. While I’m usually very weary of plugins on Retrieve / RetrieveMultiple, in this case it’s absolutely justifiable by the fact that we create a new entity that will solely be used for this purpose.
- Create a new entity called ADX Action.
- Register a plugin on RetrieveMultiple of this entity.
- Write a Liquid Fetch XML for this entity.
1. Creating the new entity
There’s a couple of things we want to achieve in calling Custom Actions through CRM Portals. We want to send information to CRM, let CRM work with that information and provide us a response, based on the actions it executed. Therefore, there are two important fields that we need to provide in this entity:
- Parameters. Type: text. Allows us to pass information to Dynamics 365.
- Response. Type: text. Allows us to send information from Dynamics 365 back to the CRM Portal.
Our entity looks like this:
2. Register a plugin on RetrieveMultiple of this entity
This is the engine of our CRM Portals Custom Action solution. Within the plugin we do a couple of things:
- Extract the parameters from the incoming query’s filter criteria.
- Decide what to do and exute that logic based on the query’s filter criteria.
- Assign a response value by setting a result in the EntityCollection.
The tricky part here is to parse the filter criteria of the incoming query. We are doing this in the plugin as you can see in the screenshot below.
In the “DoStuff” method you can apply your own logic like triggering Custom Actions, workflows, etc. Afterwards we send a result back to the Portals. We do this by adding a dummy entity to the EntityCollection that is returned in the RetrieveMultiple message. In doing so, the Fetch XML always results in one single result, containing our response message.
3. Write a Liquid Fetch XML for this entity
This is how our Fetch looks like in Liquid. Of course you can modify this to pass along you own parameters like userid,etc …
notice that we add an additional filter on the date of creation. In this filter we pass the current timestamp. Although this will not impact our results, it ensures that our request will not be cached. We’ve noticed that CRM Portals tend to cache the results of previously executed Liquid queries, which could result in your action not being triggered.
And the response we’re getting (printscreen taken from the XML FetchBuilder):
Ultimately that’s all there is to it. With these three simpel components, we’ve made it possible to trigger custom actions from within CRM Portals.
Do you have a business in mind and need a beautiful and functional website for it? If yes, there is no need to search here and there. Promanage IT Solutions is one of the leading website development services on the web. Check out the huge portfolio of visually appealing and feature-rich websites we have made for our clients in diverse industries. https://www.promanageitsolution.com
this blog is beneficial and great information to share with us. Iqra Technology is an IT Solutions and Services Company more information visit to our web site iqratechnology
[…] Call a Dynamics 365 Custom Action from CRM Portals – Thrives […]
[…] 1. Call a Dynamics 365 Custom Action from CRM Portals – Thrives […]
Hello nathan, thank you for the Post works. I'm having some issue when using fetch XML. When I use XRM tool box and run the query the plugin gets triggered (I can debug and see the parameters and all), but when I run the same fetchXML from the Portal the plugin doesn't get triggered. Also, when the plugin is TRIGGERED, I don't get any response back. My code is exactly replica of the code that you have. did something get changed after this post was published? Any help will be APPRECIATED. :) Thanks,
Hi, I think what's happening here is caching on Portal side. If you execute the exact same fetchxml, Portals will not directly go to CRM, but will return a cached result, therefore not executing the action. To solve this, I add a bogus parameter to the request (like created ge {{now}}), to ensure that the query is refreshed regularly. Hope this helps?
for some reason the fetchXML query got dropped, but here is the link for the query. https://powerusers.microsoft.com/t5/Power-Apps-Portals/FetchXML-RetrieveMultple-Plugin-Not-Firing/m-p/540482#M1311
Hello Nathan, I do have the bogus parameter like you have above. The weird part is that from the xrm tool box (using FetchXML builder) under Options -> Results view, if I select View or the Serialized view the plugin gets triggered, but If I choose Raw fetch result the plugin does not get fired on Retrieve multiple (it does on Execute). Below is my liquid fetchXML query. % fetchxml create-order-query %} {% endfetchxml %} Thanks for your help. Shiva
This is something I really could use. In your code for section 2, could you provide me function Getqueryexpression? Or am I missing a reference?
Hi Mitchel, In the GetQueryExpression we take the inputparameter and convert it to a QueryExpression if needed. This would look something like this: private static QueryExpression GetQueryExpression(IPluginExecutionContext context, IOrganizationService service) { QueryExpression query = null; if (context.InputParameters["Query"] is QueryExpression) { query = (QueryExpression)context.InputParameters["Query"]; } if (context.InputParameters["Query"] is FetchExpression) { //Get the FetchExpression and convert to a QueryExpression FetchExpression fetchExpression = (FetchExpression)context.InputParameters["Query"]; FetchXmlToQueryExpressionRequest req = new FetchXmlToQueryExpressionRequest() { FetchXml = fetchExpression.Query }; FetchXmlToQueryExpressionResponse response = (FetchXmlToQueryExpressionResponse)service.Execute(req); if (response != null) { query = response.Query; } } return query; } Hope this helps!
Thanks Nathan!
How to call an azure function from the Portal? woud that be a possible follow-up blog post?
Sounds like a great idea, thanks for the inspiration!
[…] bericht Call a Dynamics 365 Custom Action from CRM Portals verscheen eerst op […]