On an Update message, the Target in InputParameters only contains the fields that actually changed — not the whole record. If your plugin needs to know a field's old value, or needs the complete record after the save, you need an image.
- An image is a snapshot of a record's attributes, registered against a plugin step
- A pre-image captures values before the core operation runs
- A post-image captures values after the operation completes
- Images are registered per step, not automatic — you choose which attributes to include
Before and after photos
Think of a pre-image and post-image as a "before" and "after" photo. The before photo shows you what changed. The after photo shows you the finished result — including anything the platform itself filled in, like a newly generated ID or a calculated field.
Pre-image: what changed?
A pre-image is a snapshot taken before the operation runs. It's the only way to compare an old value against a new one inside an Update plugin, since Target won't contain a field the caller didn't touch.
Target, then compares the two.
Post-image: the final state
A post-image is a snapshot taken after the operation completes and the write has happened. It's most useful in post-operation plugins that need the full, final record — including system-calculated values that don't exist until the platform generates them, like a new record's ID on Create.
| Captured | Typical use | |
|---|---|---|
| Pre-image | Before the core operation | Comparing an old value to a new one on Update |
| Post-image | After the operation completes | Reading the final record, including system-generated fields |
Registering an image
Images are set up per plugin step, in the Plugin Registration Tool (covered in the next chapter but two): you name the image, pick pre- or post-, and choose which attributes to include. Only request the attributes you actually need — a smaller image is a smaller, faster payload.
// Inside the plugin, an image is read like this:
Entity preImage = context.PreEntityImages.Contains("PreImage")
? context.PreEntityImages["PreImage"]
: null;
if (preImage != null && preImage.Contains("statuscode"))
{
var oldStatus = ((OptionSetValue)preImage["statuscode"]).Value;
// compare oldStatus against the new value in Target
}
Target only has what changed), and a post-image to see the complete record after the write, including anything the platform generated. Register only the attributes you need.