Prompt & Platform
Connect
HomeTopicsSnippetsDev toolsArticles
Theme
Pro-codeIntermediate

Plugin pre and post images explained

What entity images are, which ones are available for each message and stage, and how to use them to compare old and new values in a plugin.

Prerequisites

  • Visual Studio with the Dataverse SDK
  • Plugin Registration Tool

What you'll learn

  • Why Target isn't enough on Update
  • Which images exist for each message and stage
  • Register an image with only the columns you need
  • Compare old and new values safely
On this page
  1. Pre and post images
  2. What's available where
  3. Register the image
  4. Use it in code
  5. A handy merge pattern

On an Update, the Target entity only contains the columns that changed. If your logic needs the value before the change — or a column that didn't change — you need entity images.

Pre and post images

  • A pre-image is a snapshot of the record before the operation.
  • A post-image is a snapshot after the operation.

You register them on a plugin step and choose which columns they include.

What's available where

MessagePre-imagePost-image
CreateNoYes (post-operation only)
UpdateYesYes (post-operation only)
DeleteYesNo

Register the image

In the Plugin Registration Tool, select your Update step and choose Register New Image:

  • Image type: Pre Image
  • Name and Entity Alias: PreImage (you'll use the alias in code)
  • Parameters: select only the columns you need, for example statuscode and ownerid

Selecting all attributes works, but it makes every update heavier. Pick only what you use.

Use it in code

This plugin blocks reopening a case that was already Resolved:

C#
public void Execute(IServiceProvider serviceProvider)
{
    var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

    if (!context.PreEntityImages.TryGetValue("PreImage", out Entity pre)) return; 
    var target = (Entity)context.InputParameters["Target"];

    if (!target.Contains("statuscode")) return;

    var oldStatus = pre.GetAttributeValue<OptionSetValue>("statuscode")?.Value;
    var newStatus = target.GetAttributeValue<OptionSetValue>("statuscode")?.Value;

    const int Resolved = 5;
    if (oldStatus == Resolved && newStatus != Resolved)
    {
        throw new InvalidPluginExecutionException("Resolved cases can't be reopened. Create a new case instead.");
    }
}

A handy merge pattern

When you need the full picture after an update, combine the pre-image with the changed values from Target:

C#
var current = new Entity(pre.LogicalName, pre.Id);
foreach (var attr in pre.Attributes) current[attr.Key] = attr.Value;
foreach (var attr in target.Attributes) current[attr.Key] = attr.Value; // changes win

This avoids an extra Retrieve call — faster and fewer API requests.

J / K next or previous article

Jagadeesan P

Found this useful? I share new guides on LinkedIn.

Follow