Describe the bug
The "Expand [Plugin] attribute and add [Step] and [Image] attributes" refactoring (Plugin Registration Refactoring Action) silently drops images when a single step has more than one image registered in Dataverse. For a step that has both a Pre-Image and a Post-Image, only one [Image] attribute is generated instead
of two.
Example: a step (Update / PostOperation / Asynchronous) has two images registered on the same sdkmessageprocessingstepid:
- a PreImage (imagetype = 0)
- a PostImage (imagetype = 1)
Only the first image is generated:
[Plugin]
[Step("Update", "account", "field1,field2", Stages.PreOperation, ExecutionMode.Synchronous)]
[Step("Update", "account", "field1,field2", Stages.PostOperation, ExecutionMode.Asynchronous)]
[Image(ImageTypes.PreImage, "field1,field2")]
// <-- the PostImage on the PostOperation step is missing
Likely root cause: In WebApiServiceHelper.GetPluginDefinitionAsync, the plugin definition is retrieved with a hard-coded page size:
var response = await webApi.RetrieveMultipleAsync(odataQuery, 2); // maxPageSize = 2
The query uses a two-level nested $expand (plugintype → step → image). With maxPageSize = 2 and no handling of @odata.nextLink for the nested expanded collections, the Images collection of a step appears to be truncated, so SdkMessageProcessingStep.Images is incomplete before the code generator
(PluginRefactoringProvider.ApplyPluginFixAsync) iterates over it. The generator itself is fine — it emits every image in step.Images — so the data is lost during retrieval, not during generation.
To Reproduce
Steps to reproduce the behavior:
- In Dataverse, register a plugin step that has two images on the same step (one Pre-Image and one Post-Image), for example on an Update / PostOperation / Asynchronous step.
- In Visual Studio, on the corresponding plugin class, add the [Plugin] attribute.
- Select an environment in Xrm Tools, then trigger the light bulb / Ctrl + . → "Expand [Plugin] attribute and add [Step] and [Image] attributes".
- Observe the generated attributes: only one [Image] is produced for the step, the second image is silently missing.
Expected behavior
Both images should be generated for the step, e.g.:
[Step("Update", "account", "field1,field2", Stages.PostOperation, ExecutionMode.Asynchronous)]
[Image(ImageTypes.PreImage, "field1,field2")]
[Image(ImageTypes.PostImage, "field1,field2,field3")]
More generally, the retrofit should retrieve and generate all steps and all images regardless of count, by following @odata.nextLink on nested expanded collections (or by not constraining maxPageSize so aggressively for this query).
Setup (please complete the following information):
- OS: Win11
- Visual Studio Version 18.7.2
- Xrm Tools Version 1.6.0.95
Describe the bug
The "Expand [Plugin] attribute and add [Step] and [Image] attributes" refactoring (Plugin Registration Refactoring Action) silently drops images when a single step has more than one image registered in Dataverse. For a step that has both a Pre-Image and a Post-Image, only one [Image] attribute is generated instead
of two.
Example: a step (Update / PostOperation / Asynchronous) has two images registered on the same sdkmessageprocessingstepid:
Only the first image is generated:
[Plugin]
[Step("Update", "account", "field1,field2", Stages.PreOperation, ExecutionMode.Synchronous)]
[Step("Update", "account", "field1,field2", Stages.PostOperation, ExecutionMode.Asynchronous)]
[Image(ImageTypes.PreImage, "field1,field2")]
// <-- the PostImage on the PostOperation step is missing
Likely root cause: In WebApiServiceHelper.GetPluginDefinitionAsync, the plugin definition is retrieved with a hard-coded page size:
var response = await webApi.RetrieveMultipleAsync(odataQuery, 2); // maxPageSize = 2
The query uses a two-level nested $expand (plugintype → step → image). With maxPageSize = 2 and no handling of @odata.nextLink for the nested expanded collections, the Images collection of a step appears to be truncated, so SdkMessageProcessingStep.Images is incomplete before the code generator
(PluginRefactoringProvider.ApplyPluginFixAsync) iterates over it. The generator itself is fine — it emits every image in step.Images — so the data is lost during retrieval, not during generation.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Both images should be generated for the step, e.g.:
[Step("Update", "account", "field1,field2", Stages.PostOperation, ExecutionMode.Asynchronous)]
[Image(ImageTypes.PreImage, "field1,field2")]
[Image(ImageTypes.PostImage, "field1,field2,field3")]
More generally, the retrofit should retrieve and generate all steps and all images regardless of count, by following @odata.nextLink on nested expanded collections (or by not constraining maxPageSize so aggressively for this query).
Setup (please complete the following information):