Skip to main content

Notifications

Announcements

No record found.

Dynamics 365 general forum
Answered

How to correctly get an entity in Plugin, when called from custom action?

Posted on by 45

Hi Experts, 

Here is what I am doing

I have a custom action which is global, not tied to any entity. I have created a ribbon button on 'Order From'. This ribbon button has a js command which calls the actions. I have registered my plugin and added a step to call my action (as message).

My code blocks are as follows:

Plugin block

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Activities;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Crm.Sdk.Messages;

namespace TaxPlugin
{
    public class MyTaxActionClass : IPlugin
    {
        #region Secure/Unsecure Configuration Setup
        private string _secureConfig = null;
        private string _unsecureConfig = null;

        public TaxActionClass(string unsecureConfig, string secureConfig)
        {
            _secureConfig = secureConfig;
            _unsecureConfig = unsecureConfig;
        }
        #endregion
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            try
            {
                tracer.Trace("getting entity reference");
                Entity order = (Entity)context.InputParameters["Target"]; <-- fails at this stage
                tracer.Trace("Setting tax");
                order["totaltax"] = new Money(new decimal(10.54));
                service.Update(order);
                tracer.Trace("Updated order entity");
            }
            catch (Exception e)
            {
                throw new InvalidPluginExecutionException(e.Message);
            }
        }
    }
}

JS Block

function callSureTax() {
    var req = new XMLHttpRequest();
    req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/wkstx_suretaxWSCallAction", true);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 204) {
                Xrm.Utility.alertDialog(this.statusText);
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send();
}

Here is the snapshot of custom action. This action is just a place holder so I can call a plugin from a ribbon button. 

4314.Capture.PNG

Everything gets called correctly, but I get exception on the line mentioned above in red. 

this is what I get in exception

The given key was not present in the dictionary.Detail: 


I don't know any way to get Order entity in the plugin code. When I trace 

tracer.Trace(context.MessageName);


I get following name: "sdkmessageprocessingstep"

Is there a way to get an entity, am I doing anything wrong in this process. 

  • newtomsworld Profile Picture
    newtomsworld 45 on at
    RE: How to correctly get an entity in Plugin, when called from custom action?

    Thanks Ben and Christian. I used Ben's method to params in ribbon button. Christians method to receive those params using context.InputParametes["paramName"];

    public class TaxActionParams : IPlugin
        {
            #region Secure/Unsecure Configuration Setup
            private string _secureConfig = null;
            private string _unsecureConfig = null;
    
            public TaxActionParams(string unsecureConfig, string secureConfig)
            {
                _secureConfig = secureConfig;
                _unsecureConfig = unsecureConfig;
            }
            #endregion
            public void Execute(IServiceProvider serviceProvider)
            {
                ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = factory.CreateOrganizationService(context.UserId);
    
                try
                {
                    tracer.Trace("Getting input entity");
                    string entityId = (string)context.InputParameters["entityId"];
                    Guid gEntityId = new Guid(entityId);
                    string entityName = (string)context.InputParameters["entityName"];
                    tracer.Trace("EntityName = " + entityName + " Entity Id = " + entityId);
                    Entity order = (Entity)service.Retrieve(entityName, gEntityId, new ColumnSet(true));
    
                    //TODO: Do stuff
                }
                catch (Exception e)
                {
                    throw new InvalidPluginExecutionException(e.Message);
                }
            }
        }


    Js Code:

    function callSureTaxParams(entityName, entityId) {
        var parameters = {};
        parameters.entityId = entityId;
        parameters.entityName = entityName;
    
        var req = new XMLHttpRequest();
        req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/wkstx_sureAction2", true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.onreadystatechange = function () {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 204) {
                    //Success - No Return Data - Do Something
                } else {
                    Xrm.Utility.alertDialog(this.statusText);
                }
            }
        };
        req.send(JSON.stringify(parameters));
    }

    Here in Ribbon I added the params to be passed to the JS
    2260.Capture.PNG

    Here is a the procedure:

    Create a global custom action with two input params

    Create Ribbon button.

    Create a JS with two input params

    Add JS command with js and function to the above created button

    Create plugin code as shown above and get input params.  

  • Verified answer
    C. Jensen Profile Picture
    C. Jensen 384 on at
    RE: How to correctly get an entity in Plugin, when called from custom action?

    Hi

    Try using context.PrimaryEntityId and PrimaryEntityName instead of InputParameter. Then you can retrieve the record.

    /Christian

  • Verified answer
    Ben Thompson Profile Picture
    Ben Thompson 6,350 on at
    RE: How to correctly get an entity in Plugin, when called from custom action?

    A global custom action isn't expecting any inputs so doesn't have a target input parameters - it's designed to provide global information such as number of open cases.

    As you wish to update an actual entity you can't use a global action you need an action with an input parameter . community.dynamics.com/.../sample-code-to-call-action-using-web-api-in-crm has a good explanation of the code you need but I should point some of the code (Xrm.Page) is deprecated -  you really should get the ribbon button to pass both context and the id of the entity to you.

Helpful resources

Quick Links

Dynamics 365 Community Update – Sep 16th

Welcome to the next edition of the Community Platform Update. This is a weekly…

Announcing Our 2024 Season 2 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 290,353 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 228,251 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,148

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans