web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id :
Customer experience | Sales, Customer Insights,...
Suggested answer

How to Stop Message from firing via plugin

(1) ShareShare
ReportReport
Posted on by 3,083
Hi All
I'm using Calculate Price message in one plugin A  to update quotedetail and quote . There is another plugin B where I update quote totals and I want to prevent to Calculate Price message firing. Is there a way to code Plugin B to stop firing Calculate Price message so after updating totals from B Calculate Price message will not fire?
I have the same question (0)
  • Suggested answer
    Daivat Vartak (v-9davar) Profile Picture
    7,827 Super User 2025 Season 2 on at
    How to Stop Message from firing via plugin
    Hello Samantha73,
     

    Yes, there are a few ways you can attempt to prevent the CalculatePrice message from firing in Plugin B after you've updated the quote totals. However, it's important to understand the limitations and potential side effects of each approach.

    Here are the common strategies:

    1. Using SharedVariables to Control Execution Flow (Recommended):

    This is generally the cleanest and most controlled approach. You can set a flag in SharedVariables within Plugin B to indicate that the price calculation has already been handled or should be skipped. Plugin A can then check this flag before executing its price calculation logic.

     

    Plugin B (Updating Totals):

    public class UpdateQuoteTotals : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (context.PrimaryEntityName == "quote" && context.MessageName == "Update" && context.Stage == 40) // Post-Operation Update
            {
                try
                {
                    // Your logic to update quote totals
                    // Set a shared variable to indicate that price calculation is handled
                    context.SharedVariables["SuppressCalculatePrice"] = true;
                    tracingService.Trace("Plugin B: Suppressed CalculatePrice via SharedVariable.");
                }
                catch (Exception ex)
                {
                    tracingService.Trace($"Plugin B Error: {ex.ToString()}");
                    throw;
                }
            }
        }
    }

     

    Plugin A (Calculating Price):

    public class CalculateQuotePrice : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            if (context.PrimaryEntityName == "quotedetail" || context.PrimaryEntityName == "quote")
            {
                if (context.MessageName == "CalculatePrice" && context.Stage == 40) // Post-Operation CalculatePrice
                {
                    if (context.SharedVariables.ContainsKey("SuppressCalculatePrice") && (bool)context.SharedVariables["SuppressCalculatePrice"])
                    {
                        tracingService.Trace("Plugin A: CalculatePrice suppressed by Plugin B.");
                        return; // Exit the plugin execution
                    }
                    try
                    {
                        // Your logic to calculate and update quote detail and quote prices
                        tracingService.Trace("Plugin A: CalculatePrice executed.");
                    }
                    catch (Exception ex)
                    {
                        tracingService.Trace($"Plugin A Error: {ex.ToString()}");
                        throw;
                    }
                }
            }
        }
    }

     

    Explanation:

    • Plugin B, after updating the quote totals, sets a boolean value to true in the context.SharedVariables dictionary with the key SuppressCalculatePrice.

    • Plugin A, at the beginning of its CalculatePrice execution, checks if this key exists in SharedVariables and if its value is true.

    • If the flag is set, Plugin A simply returns, effectively preventing its price calculation logic from running.


    •  

    Important Considerations for SharedVariables:

    • SharedVariables are only available within the same transaction pipeline. If Plugin B and the subsequent CalculatePrice execution happen in separate transactions (which is less likely for immediate post-operation events but possible in asynchronous scenarios), this method won't work.

    • Ensure the execution order of your plugins is correctly set. Plugin B (updating totals) should execute before the instance of Plugin A that you want to suppress.


    •  

    2. Using a Custom Flag Field on the Quote Entity (Less Ideal for System Messages):

    You could add a custom boolean field (e.g., new_suppresspricecalculation) to the Quote entity. Plugin B would set this field to true after updating the totals. Plugin A would then check the value of this field before proceeding with the price calculation.

     

    Plugin B:

    // ... (rest of Plugin B code)
    service.Update(new Entity("quote", context.PrimaryEntityId) { ["new_suppresspricecalculation"] = true });

     

    Plugin A:

    // ... (rest of Plugin A code)
    Entity quote = service.Retrieve("quote", context.PrimaryEntityId, new ColumnSet("new_suppresspricecalculation"));
    if (quote.Contains("new_suppresspricecalculation") && (bool)quote["new_suppresspricecalculation"])
    {
        tracingService.Trace("Plugin A: CalculatePrice suppressed by custom flag.");
        return;
    }
    // ... (rest of Plugin A's price calculation logic)

     

    Important Considerations for Custom Flag Field:

    • This approach involves an extra database update in Plugin B.

    • You need to ensure Plugin A resets this flag if the price calculation should run again later (e.g., on other quote updates).

    • It tightly couples the logic of the two plugins to a specific field on the entity.


    •  

    3. Modifying the Execution Context (Less Recommended and Potentially Unreliable):

    While technically possible to manipulate the execution context (e.g., by setting the OperationCanceled property), this is generally not recommended for suppressing system messages like CalculatePrice. It can lead to unexpected behavior and might not be reliably supported.

    Why Modifying Execution Context is Discouraged:

    • It can interfere with the platform's internal processes and potentially cause instability.

    • The behavior might change with future updates.

    • It makes your code harder to understand and maintain.


    •  

    Which Method to Choose:

    The SharedVariables approach (Method 1) is generally the preferred and most robust way to control the execution flow between plugins within the same transaction. It avoids extra database updates and keeps the suppression logic within the plugin execution pipeline.

    The custom flag field approach (Method 2) can work but introduces coupling and requires careful management of the flag's value.

    Modifying the execution context (Method 3) should be avoided for suppressing standard system messages.

     

    To implement the SharedVariables approach:

    1. Ensure your Plugin B (updating totals) executes before the instance of Plugin A that you want to suppress for that specific quote update. You can control this through the plugin registration tool by setting the execution order.

    2. Implement the code snippets provided above in your respective plugins.

    3. Thoroughly test the scenario to ensure that the CalculatePrice message is suppressed as expected after Plugin B updates the totals.


    4.  

    By using SharedVariables, you can achieve your goal of preventing the CalculatePrice message from firing after your custom logic in Plugin B has updated the quote totals, leading to a more controlled and efficient process. Remember to prioritize the execution order of your plugins.

     
    If my answer was helpful, please click Like, and if it solved your problem, please mark it as verified to help other community members find more. If you have further questions, please feel free to contact me.
     
    My response was crafted with AI assistance and tailored to provide detailed and actionable guidance for your Microsoft Dynamics 365 query.
     
    Regards,
    Daivat Vartak
  • Suggested answer
    Inogic Profile Picture
    639 on at
    How to Stop Message from firing via plugin
    Hi,
     
    You can go with one among the two options below :-
     
    Option 1: Use SharedVariables between plugins (if executed in the same pipeline)
     
    1. If both plugins are in the same pipeline (e.g., synchronous and part of the same message processing), you can do this:
    2. In Plugin B, before triggering CalculatePrice, set a shared flag
    3. Then in Plugin A (the one triggered by CalculatePrice), check for this flag
    Note : 🔸 This only works within the same message pipeline, so if the plugins are triggered by separate operations, this won’t apply.

                  Option 2: Use a custom field as a control flag
    If the plugins run separately or in different transactions, use a hidden field like new_skippricecalculation on the quote entity:
    1. In Plugin B, before updating totals, set this field to true.
    2. In Plugin A, at the start of execution, check if the quote record has this flag set to true, and skip processing if so.
    3. (Optional) Reset the flag after Plugin B is done.
    Thanks!
    Inogic

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Mansi Soni – Community Spotlight

We are honored to recognize Mansi Soni as our August 2025 Community…

Congratulations to the July Top 10 Community Leaders!

These are the community rock stars!

Leaderboard > Customer experience | Sales, Customer Insights, CRM

#1
Hamza H Profile Picture

Hamza H 141

#2
Daniyal Khaleel Profile Picture

Daniyal Khaleel 132

#3
DAnny3211 Profile Picture

DAnny3211 130

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans