Pre-Image vs Post-Image in Dynamics 365 Plug-ins

Pre-Image vs Post-Image in Dynamics 365 Plug-ins

Understanding Pre-Image and Post-Image in Dynamics 365 Plug-ins

When developing Microsoft Dynamics 365 / Dataverse Plug-ins, we often need more information than simply knowing that a record has been updated.

Sometimes our business logic needs to answer questions such as:

  • What was the value before the update?
  • What value did the user submit?
  • What does the record look like after the operation?
  • Has a specific value actually changed?
  • Can we get the required data without making another Retrieve request to Dataverse?

This is where Pre-Images and Post-Images become extremely useful.

In this article, we’ll look at what they are, how they differ from the Target, when to use each one, and why they can help us build more efficient Dynamics 365 Plug-ins.


A Simple Scenario

Imagine we have an Account with the following Credit Limit:

Credit Limit = 5,000

A user updates it to:

Credit Limit = 8,000

We want our Plug-in to detect that change and execute some business logic.

At first, this sounds simple.

We can access the Target from the Plug-in Execution Context.

But there is an important problem:

Where do we get the previous value of 5,000?

This is one of the situations where a Pre-Image is useful.


What Is the Target?

Before talking about Images, it’s important to understand the Target.

During an Update operation, Dynamics 365 provides information about the operation through the Plug-in Execution Context.

The Target can normally be accessed through:

context.InputParameters["Target"]

For an Update message, the Target generally contains the attributes that are part of the current update request.

For example, if the user changes only:

Credit Limit → 8,000

the Target may contain the new Credit Limit value, but it should not be treated as a complete snapshot of the entire Account record.

This distinction is extremely important.

A common mistake in Plug-in development is assuming that Target always contains every attribute of the record.

It doesn’t.


What Is a Pre-Image?

A Pre-Image is a snapshot of selected record attributes before the core operation takes place.

In our example:

Before Update:

Credit Limit = 5,000

The Pre-Image can provide that previous value to the Plug-in.

Conceptually:

Pre-Image
Credit Limit = 5,000

while the Target contains:

Target
Credit Limit = 8,000

Now our Plug-in can compare them:

Old Value = 5,000
New Value = 8,000

and determine that the Credit Limit has actually changed.


When Is Pre-Image Useful?

Pre-Images are particularly useful when your business logic depends on the previous state of a record.

Typical scenarios include:

Comparing old and new values

For example:

Old Status = Pending
New Status = Approved

The Plug-in can determine that a specific state transition has occurred.

Detecting meaningful changes

A field appearing in an update request and a meaningful business change are not always the same thing.

Having access to the previous value allows the Plug-in to make better decisions.

Validating a transition

Imagine that an Order should only move from:

Draft → Approved

but not directly from:

Draft → Completed

The previous state becomes essential for enforcing this rule.

Performing calculations based on previous data

Sometimes a calculation requires both the previous and new values.

Without the previous value, additional data retrieval might otherwise be required.


What Is a Post-Image?

A Post-Image is a snapshot of selected attributes after the core operation has taken place.

Returning to our Credit Limit example:

Before:

Credit Limit = 5,000

After:

Credit Limit = 8,000

The Post-Image represents the record state after the operation.

This can be useful when the Plug-in needs to work with the final state of the record, rather than only the fields included in the incoming Target.


Target vs Pre-Image vs Post-Image

The easiest way to understand the three concepts is:

SourceWhat does it represent?
Pre-ImageSelected record values before the operation
TargetValues supplied as part of the current request
Post-ImageSelected record values after the operation

Using our example:

PRE-IMAGE
Credit Limit = 5,000

       ↓

TARGET
Credit Limit = 8,000

       ↓

POST-IMAGE
Credit Limit = 8,000

This distinction becomes especially important during Update operations.

The Target should not automatically be considered the complete “after” version of the record.


Why Not Just Retrieve the Record?

You might ask:

Why don’t we simply use the Organization Service to retrieve the record whenever we need additional information?

Technically, there are situations where retrieving data is necessary.

However, if the information your Plug-in needs can already be supplied through a properly configured Image, performing another Retrieve introduces an additional request that may be unnecessary.

Instead of:

Plug-in executes
      ↓
Retrieve existing record
      ↓
Process business logic

we may be able to use:

Plug-in executes
      ↓
Read Pre/Post Image
      ↓
Process business logic

This can reduce unnecessary Dataverse calls and keep Plug-in logic cleaner.

The important point is not that Retrieve is always wrong.

It is that we shouldn’t retrieve data unnecessarily when the execution pipeline can already provide the required values.


Configuring Images

Pre-Images and Post-Images are configured when registering the Plug-in Step.

Using the Plug-in Registration Tool, an Image can be associated with the appropriate Plug-in Step.

When configuring an Image, we specify information such as:

  • Image type
  • Image name / alias
  • Attributes that should be included

The alias is important because our Plug-in uses it to access the Image.

For example:

Entity preImage =
    context.PreEntityImages["PreImage"];

The name PreImage must correspond to the alias configured during registration.

Similarly, a Post-Image can be accessed through:

Entity postImage =
    context.PostEntityImages["PostImage"];

Don’t Include Every Column

When configuring an Image, it may be tempting to include every attribute.

Usually, that’s unnecessary.

If your Plug-in only needs:

Credit Limit
Status
Customer Type

then configure the Image with those required attributes.

This makes the Plug-in’s dependencies clearer and avoids carrying data the logic doesn’t need.

A good rule is:

Include the attributes your Plug-in actually needs, not every attribute that exists on the table.


Example: Detecting a Credit Limit Change

Let’s imagine our Plug-in needs to react whenever an Account’s Credit Limit changes.

Conceptually, the logic looks like this:

Pre-Image
      ↓
Read previous Credit Limit

Target
      ↓
Read submitted Credit Limit

Compare
      ↓
Has the value changed?

YES → Execute business logic
NO  → Do nothing

A simplified C# example could look like:

var target = (Entity)context.InputParameters["Target"];

var preImage = context.PreEntityImages["PreImage"];

var oldLimit =
    preImage.GetAttributeValue<Money>("creditlimit");

var newLimit =
    target.GetAttributeValue<Money>("creditlimit");

if (oldLimit?.Value != newLimit?.Value)
{
    // Execute business logic
}

In production code, additional checks should be made to ensure the required parameters, Images, and attributes are available before accessing them.


Pre-Image and Filtering Attributes Work Well Together

There is another useful Plug-in concept related to this scenario: Filtering Attributes.

Suppose our Plug-in only needs to execute when creditlimit is included in an Update request.

Instead of allowing the Plug-in Step to execute for every Account update, we can configure:

Filtering Attribute:
creditlimit

Now we have two complementary concepts:

Filtering Attributes

Determine when the Plug-in Step should execute based on attributes included in the request.

Pre-Image

Provides the previous value needed by the Plug-in logic.

Together they can produce more focused and efficient Plug-in behavior.


Common Mistake #1: Assuming Target Is the Entire Record

Consider an Account containing:

Name
Credit Limit
Industry
Account Manager
Status

If the user only updates Credit Limit, the Target shouldn’t be assumed to contain all those other attributes.

Therefore, code that blindly expects unrelated fields to always exist in Target can fail or behave unexpectedly.

Always think of Target in the context of the current request.


Common Mistake #2: Retrieving Data Without Checking Images

Another common pattern is immediately performing a Retrieve whenever an old value is required.

Before doing that, ask:

Can the required value be provided through a Pre-Image?

If yes, the extra Retrieve may not be necessary.


Common Mistake #3: Registering Too Many Image Attributes

Selecting every attribute may seem convenient during development.

However, explicit configuration is generally easier to understand and maintain.

If a Plug-in needs three fields, configure those three fields.

This also makes it easier for another developer to understand the data dependencies of the Plug-in.


Common Mistake #4: Confusing Post-Image with Target

Target and Post-Image are not simply two names for the same thing.

During an Update:

Target represents the values submitted with the request.

Post-Image represents selected values from the record after the operation.

Understanding this difference prevents many confusing Plug-in bugs.


Which One Should I Use?

A simple decision guide:

I need the value before the operation

Use:

Pre-Image

I need to know what the current request is changing

Check:

Target

I need selected values representing the record after the operation

Use:

Post-Image

I need to compare before and after

Depending on the Plug-in design and pipeline stage, you may use:

Pre-Image + Target

or:

Pre-Image + Post-Image

The right choice depends on what exactly the Plug-in needs to know and when it executes.


Why Images Matter in Real Dynamics 365 Projects

Pre/Post Images may look like a small Plug-in concept, but they represent an important development principle:

Understand the Dynamics 365 execution pipeline before adding additional service calls.

A well-designed Plug-in shouldn’t only “work.”

It should also be:

  • Efficient
  • Predictable
  • Maintainable
  • Easy to debug
  • Explicit about the data it depends on

Knowing when to use Target, Pre-Image, Post-Image, Filtering Attributes, and Organization Service is part of building better Dynamics 365 Plug-ins.


Final Summary

If you remember only three things from this article, remember these:

Pre-Image → Before

Target → Current request

Post-Image → After

Pre/Post Images allow Plug-ins to work with record state at different points in the execution pipeline and can often eliminate unnecessary data retrieval.

When building an Update Plug-in, ask yourself:

Do I need the previous value?

Do I only need to know what is being changed?

Do I need the final record state?

The answers will usually tell you whether you need a Pre-Image, Target, Post-Image — or a combination of them.


Related topics: Dynamics 365 Plug-ins, Dataverse, Execution Context, Plug-in Pipeline, Filtering Attributes, Plug-in Performance

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *