Having spent most of today trying out a failed plugin experiment, I discovered a feature of Plugin Registration tool that I never used before. It it not very clear from the SDK documentation, what keys are there in the InputParameters and OutputParameters and often I refer the appropriate request/response class, to find out what key I should be using on the InputParameter e.g. for UpdateRequest use Target key on the InputParameter for a pre-operation plugin.
There seems to be a easier way to capture the plugin state right after the plugin fires. This can be done using the Plugin Registration tool. This is the plugin command bar:
Replay Plug-in Execution button is used when you want to debug the plugin in Visual Studio. This process is well documented in multiple blogs and SDK documentation. View Plug-in profile functionality is what we want to use during the initial plugin development stage. After registering a plugin, right click on the desired step and choose Start Profiling.
Persist the profile to entity, instead of throwing an exception.
Once this is done, perform the action that triggers the plugin. This creates a profile record, that we can use to dump the plugin state. After the plugin has finished executing, click the view plugin profile button in the command bar. It brings up this window.
Next, click the downarrow button and choose the appropriate trace record.
After clicking the View button, you can see the entire plugin state. The below is the xml I got for a plugin firing on Retrieve message on SavedQuery.
As you can see, this file is quite useful in trying to understand the plugin execution context and can be beneficial in the initial development stage. This feature has been in PluginRegistration tool since CRM2011, and I felt like an idiot for having just discovered it, but happy that I finally discovered this. I will definitely be using this a lot in the coming days.
There seems to be a easier way to capture the plugin state right after the plugin fires. This can be done using the Plugin Registration tool. This is the plugin command bar:
Replay Plug-in Execution button is used when you want to debug the plugin in Visual Studio. This process is well documented in multiple blogs and SDK documentation. View Plug-in profile functionality is what we want to use during the initial plugin development stage. After registering a plugin, right click on the desired step and choose Start Profiling.
Persist the profile to entity, instead of throwing an exception.
Once this is done, perform the action that triggers the plugin. This creates a profile record, that we can use to dump the plugin state. After the plugin has finished executing, click the view plugin profile button in the command bar. It brings up this window.
Next, click the downarrow button and choose the appropriate trace record.
After clicking the View button, you can see the entire plugin state. The below is the xml I got for a plugin firing on Retrieve message on SavedQuery.
<Profile> <Configuration i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" /> <ConstructorDurationInMilliseconds>2</ConstructorDurationInMilliseconds> <ConstructorException i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" /> <ConstructorStartTime>2015-05-06T01:46:45.5675566Z</ConstructorStartTime> <Context> <z:anyType i:type="PluginExecutionContext" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <BusinessUnitId>1f06daae-de79-e411-80bd-00155dc6799a</BusinessUnitId> <CorrelationId>09993a86-41c8-40b7-bc4c-2717057b5408</CorrelationId> <Depth>1</Depth> <InitiatingUserId>af20daae-de79-e411-80bd-00155dc6799a</InitiatingUserId> <InputParameters xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <a:KeyValuePairOfstringanyType> <b:key>Target</b:key> <b:value i:type="a:EntityReference"> <a:Id>00000000-0000-0000-00aa-000010001001</a:Id> <a:LogicalName>savedquery</a:LogicalName> <a:Name i:nil="true" /> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>ColumnSet</b:key> <b:value i:type="a:ColumnSet"> <a:AllColumns>false</a:AllColumns> <a:Columns xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays"> <c:string>fetchxml</c:string> <c:string>name</c:string> <c:string>description</c:string> <c:string>returnedtypecode</c:string> <c:string>layoutxml</c:string> <c:string>savedqueryid</c:string> <c:string>name</c:string> <c:string>statecode</c:string> <c:string>statuscode</c:string> <c:string>ismanaged</c:string> <c:string>iscustomizable</c:string> </a:Columns> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>ReturnNotifications</b:key> <b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">true</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>RelatedEntitiesQuery</b:key> <b:value i:nil="true" /> </a:KeyValuePairOfstringanyType> </InputParameters> <IsExecutingOffline>false</IsExecutingOffline> <IsInTransaction>false</IsInTransaction> <IsOfflinePlayback>false</IsOfflinePlayback> <IsolationMode>2</IsolationMode> <MessageName>Retrieve</MessageName> <Mode>0</Mode> <OperationCreatedOn>2015-05-06T01:46:45.5206856Z</OperationCreatedOn> <OperationId>00000000-0000-0000-0000-000000000000</OperationId> <OrganizationId>a240c2fd-16a0-4ab5-9ecb-a43a6afdcc8c</OrganizationId> <OrganizationName>Contoso</OrganizationName> <OutputParameters xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <a:KeyValuePairOfstringanyType> <b:key>BusinessEntity</b:key> <b:value i:type="a:Entity"> <a:Attributes> <a:KeyValuePairOfstringanyType> <b:key>savedqueryid</b:key> <b:value i:type="z:guid">00000000-0000-0000-00aa-000010001001</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>fetchxml</b:key> <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema"><fetch version="1.0" output-format="xml-platform" mapping="logical"><entity name="account"><attribute name="name" /><attribute name="address1_city" /><order attribute="name" descending="false" /><filter type="and"><condition attribute="ownerid" operator="eq-userid" /><condition attribute="statecode" operator="eq" value="0" /></filter><attribute name="primarycontactid" /><attribute name="telephone1" /><attribute name="accountid" /><link-entity alias="accountprimarycontactidcontactcontactid" name="contact" from="contactid" to="primarycontactid" link-type="outer" visible="false"><attribute name="emailaddress1" /></link-entity></entity></fetch></b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>returnedtypecode</b:key> <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">account</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>name</b:key> <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema">My Active Accounts</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>statuscode</b:key> <b:value i:type="a:OptionSetValue"> <a:Value>1</a:Value> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>iscustomizable</b:key> <b:value i:type="a:BooleanManagedProperty"> <a:CanBeChanged>true</a:CanBeChanged> <a:ManagedPropertyLogicalName>iscustomizableanddeletable</a:ManagedPropertyLogicalName> <a:Value>true</a:Value> </b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>layoutxml</b:key> <b:value i:type="c:string" xmlns:c="http://www.w3.org/2001/XMLSchema"><grid name="resultset" object="1" jump="name" select="1" icon="1" preview="1"><row name="result" id="accountid"><cell name="name" width="300" /><cell name="telephone1" width="100" /><cell name="address1_city" width="100" /><cell name="primarycontactid" width="150" /><cell name="accountprimarycontactidcontactcontactid.emailaddress1" width="150" disableSorting="1" /></row></grid></b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>ismanaged</b:key> <b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">true</b:value> </a:KeyValuePairOfstringanyType> <a:KeyValuePairOfstringanyType> <b:key>statecode</b:key> <b:value i:type="a:OptionSetValue"> <a:Value>0</a:Value> </b:value> </a:KeyValuePairOfstringanyType> </a:Attributes> <a:EntityState i:nil="true" /> <a:FormattedValues> <a:KeyValuePairOfstringstring> <b:key>returnedtypecode</b:key> <b:value>Account</b:value> </a:KeyValuePairOfstringstring> <a:KeyValuePairOfstringstring> <b:key>statuscode</b:key> <b:value>Active</b:value> </a:KeyValuePairOfstringstring> <a:KeyValuePairOfstringstring> <b:key>iscustomizable</b:key> <b:value>True</b:value> </a:KeyValuePairOfstringstring> <a:KeyValuePairOfstringstring> <b:key>ismanaged</b:key> <b:value>Managed</b:value> </a:KeyValuePairOfstringstring> <a:KeyValuePairOfstringstring> <b:key>statecode</b:key> <b:value>Active</b:value> </a:KeyValuePairOfstringstring> </a:FormattedValues> <a:Id>00000000-0000-0000-00aa-000010001001</a:Id> <a:LogicalName>savedquery</a:LogicalName> <a:RelatedEntities /> </b:value> </a:KeyValuePairOfstringanyType> </OutputParameters> <OwningExtension xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts"> <a:Id>517294bb-91f3-e411-80d0-00155dc6799a</a:Id> <a:LogicalName>sdkmessageprocessingstep</a:LogicalName> <a:Name>RYR.VirtualViews.SavedQueryOnRetrieveMultiplePlugin: Retrieve of savedquery (Profiler)</a:Name> </OwningExtension> <PostEntityImages xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> <PreEntityImages xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> <PrimaryEntityId>00000000-0000-0000-00aa-000010001001</PrimaryEntityId> <PrimaryEntityName>savedquery</PrimaryEntityName> <RequestId i:nil="true" /> <SecondaryEntityName>none</SecondaryEntityName> <SharedVariables xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic" /> <UserId>af20daae-de79-e411-80bd-00155dc6799a</UserId> <ParentContext i:nil="true" /> <Stage>40</Stage> </z:anyType> </Context> <ExecutionDurationInMilliseconds>8</ExecutionDurationInMilliseconds> <ExecutionException i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" /> <ExecutionStartTime>2015-05-06T01:46:45.5675566Z</ExecutionStartTime> <HasServiceEndpointNotificationService>true</HasServiceEndpointNotificationService> <IsContextReplay>false</IsContextReplay> <IsolationMode>2</IsolationMode> <OperationType>Plugin</OperationType> <ProfileVersion>1.1</ProfileVersion> <ReplayEvents xmlns:a="http://schemas.datacontract.org/2004/07/PluginProfiler.Plugins" /> <SecureConfiguration i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" /> <TypeName>RYR.VirtualViews.SavedQueryOnRetrieveMultiplePlugin</TypeName> <WorkflowInputParameters xmlns:a="http://schemas.datacontract.org/2004/07/PluginProfiler.Plugins" /> <WorkflowOutputParameters xmlns:a="http://schemas.datacontract.org/2004/07/PluginProfiler.Plugins" /> <WorkflowStepId i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" /> </Profile>
As you can see, this file is quite useful in trying to understand the plugin execution context and can be beneficial in the initial development stage. This feature has been in PluginRegistration tool since CRM2011, and I felt like an idiot for having just discovered it, but happy that I finally discovered this. I will definitely be using this a lot in the coming days.
No comments:
Post a Comment