Click here to Skip to main content
Click here to Skip to main content

Microsoft Dynamics CRM 4.0 Plug-in Testing and Debugging

By , 23 Jul 2010
 

Introduction

This article discusses about a tool that helps to test and debug the Microsoft Dynamics CRM 4.0 (MSCRM4.0) plug-in. The tool can also help a MSCRM4.0 developer to explore the context a plug-in will receive for a message the developer has never worked before, thus giving the developer an idea of what is contained in the context for a particular message of a particular entity. The utility consists of a serializing plug-in and a plug-in test bed.

Background

Serialization plays an important role. We use serialization to capture the plug-in's context from the server. The serializing plug-in code has serialization logic to serialize the contents of the context provided by Microsoft Dynamics CRM 4.0 during plug-in execution.

Serializing Plug-in Code

The complete code of the serializing plug-in is given below. It serializes the context it receives. This plug-in has to be registered once.

public class SerializingPlugin : IPlugin
{
    public void Execute(IPluginExecutionContext context)
    {
        XmlSerializer formatter = new XmlSerializer
                (typeof(MyPluginContext), string.Empty);
        MyPluginContext myContext = new MyPluginContext();
        myContext.Copy(context);
        string filename = string.Format(@"C:\windows\temp\{0}-{1}", 
            context.PrimaryEntityName, context.MessageName);
        string suffix = string.Empty;
        int i = 0;
        while (File.Exists(filename + suffix))
        {
            suffix = i.ToString();
            i++;
        }
        FileStream file = File.Create(filename + suffix);
        formatter.Serialize(file, myContext);
        file.Flush();
        file.Close();
    }
}

How It Works

Let's assume we have to debug a plug-in which executes on "Post" "Create" of "account". The serializing plug-in has to be registered, and a step has to be created for the "Create" message of "account" entity. Then create an account with the desired values. The serializing plug-in executes and creates an XML file in C:\windows\temp which contains the context it received. Provide this file as an input to the TestPlugin application.

TestPlugin Application

Test Application

The TestPlugin application helps testing/debugging a plug-in using the Visual Studio debugger. The application takes the CRM user credentials of the same CRM instance where the serializing plug-in is deployed. The path of the serialized IPluginExecutionContext and the path of the plug-in DLL to be debugged have to be provided by clicking the LoadSearializedContext and LoadAssembly buttons, respectively. Finally, after providing the fully qualified class name (i.e., class name with namespace) of the plug-in class, click on the "Start" button to start the plug-in execution.

Set the breakpoint in the pluginClass.Execute(myPluginContext); line in the btnStart_Click event handler. When the debugger hits the location, step into the line. Make sure the .pdb file is also present in the same folder as the plugin DLL.

Sample Serialized IPluginExecutionContext

<MyPluginContext xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BusinessUnitId>bada4721-db0f-4318-8471-ed85981c94da</BusinessUnitId>
  <CallerOrigin xmlns:q1=http://schemas.microsoft.com/crm/2007/CoreTypes 
    xsi:type="q1:ApplicationOrigin" />
  <CorrelationId>0d9b8e39-7b1e-4590-a03e-535464362ebd</CorrelationId>
  <CorrelationUpdatedTime>2010-06-26T19:08:57Z</CorrelationUpdatedTime>
  <Depth>1</Depth>
  <InitiatingUserId>a6c3ac10-2fc6-41a8-b24e-3b9213cfcc56</InitiatingUserId>
  <InputParameters>
    <Properties>
      <PropertyBagEntry>
        <Name>Target</Name>
        <DynamicEntity Name="account">
          <Properties xmlns="http://schemas.microsoft.com/crm/2006/WebServices">
            <Property xsi:type="StringProperty" Name="name">
              <Value>TestAccount</Value>
            </Property>
            <Property xsi:type="LookupProperty" Name="transactioncurrencyid">
              <Value type="transactioncurrency">
                  0ad13e34-ad80-de11-a371-00155d625206</Value>
            </Property>
            <Property xsi:type="OwnerProperty" Name="ownerid">
              <Value type="systemuser">81c63db2-7bee-4483-aa8b-dc179af8ac1f</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="creditonhold">
              <Value>false</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="preferredcontactmethodcode">
              <Value name="Any">1</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotemail">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotbulkemail">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotphone">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotfax">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotpostalmail">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="donotsendmm">
              <Value>false</Value>
            </Property>            
            <Property xsi:type="CrmBooleanProperty" Name="donotbulkpostalmail">
              <Value>false</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="isprivate">
              <Value>false</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="shippingmethodcode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="address2_shippingmethodcode">
              <Value>1</Value>
            </Property>           
            <Property xsi:type="PicklistProperty" Name="address2_addresstypecode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="accountratingcode">
              <Value>1</Value>
            </Property>            
            <Property xsi:type="CrmBooleanProperty" Name="participatesinworkflow">
              <Value>false</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="territorycode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="customersizecode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="address2_freighttermscode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="CrmBooleanProperty" Name="merged">
              <Value>false</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="accountclassificationcode">
              <Value>1</Value>
            </Property>
            <Property xsi:type="PicklistProperty" Name="businesstypecode">
              <Value>1</Value>
            </Property>
          </Properties>
        </DynamicEntity>
      </PropertyBagEntry>
      <PropertyBagEntry>
        <Name>OptionalParameters</Name>
        <ArrayOfOptionalParameter>
          <OptionalParameter xmlns:q2=
        http://schemas.microsoft.com/crm/2007/WebServices 
        xsi:type="q2:CreateDuplicatesOptionalParameter">
            <q2:Value>false</q2:Value>
          </OptionalParameter>
        </ArrayOfOptionalParameter>
      </PropertyBagEntry>
    </Properties>
  </InputParameters>
  <InvocationSource>0</InvocationSource>
  <IsExecutingInOfflineMode>false</IsExecutingInOfflineMode>
  <MessageName>Create</MessageName>
  <Mode>0</Mode>
  <OrganizationId>10f25dce-ac80-de11-a371-00155d625206</OrganizationId>
  <OrganizationName>MSCRMORG</OrganizationName>
  <OutputParameters>
    <Properties>
      <PropertyBagEntry>
        <Name>id</Name>
        <anyType xmlns:q3=http://microsoft.com/wsdl/types/ 
    xsi:type="q3:guid">4785e644-5681-df11-a9e8-00155d625206</anyType>
      </PropertyBagEntry>
    </Properties>
  </OutputParameters>
  <PostEntityImages>
    <Properties />
  </PostEntityImages>
  <PreEntityImages>
    <Properties />
  </PreEntityImages>
  <PrimaryEntityName>account</PrimaryEntityName>
  <SecondaryEntityName>none</SecondaryEntityName>
  <SharedVariables>
    <Properties>
      <PropertyBagEntry>
        <Name>DefaultsAddedFlag</Name>
        <anyType xsi:type="xsd:boolean">true</anyType>
      </PropertyBagEntry>
      <PropertyBagEntry>
        <Name>ValidationOccurredFlag</Name>
        <anyType xsi:type="xsd:boolean">true</anyType>
      </PropertyBagEntry>
    </Properties>
  </SharedVariables>
  <Stage>50</Stage>
  <UserId>81c63db2-7bee-4483-aa8b-dc179af8ac1f</UserId>
</MyPluginContext>

Advantages

  1. Facilitates Test Driven Development of MSCRM4.0 plug-ins
  2. Production server plug-in issues can be simulated
  3. Production environment troubleshooting and debugging
  4. Developer need not maintain CRM instances for developing and testing plug-ins

Points of Interest

I learnt the importance of Interface and how an Interface hides the implementation details and supports extensibility. The IPluginExecutionContext is an excellent example. XmlSerialization is an amazing concept!

History

  • 26 June, 2010: Initial post
  • 28 June, 2010: Added MetadataService support
  • 16 July, 2010: Added TestPlugin application's fields save and restore for repeated testing
  • 23 July, 2010: Added TestPlugin application's fields save and restore for repeated testing - updated source code

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Dinesh Uthayakumar
Software Developer
India India
Member
I am currently working as a Microsoft Dynamics CRM 4.0 and .NET developer. Passionate about computers. Love to learn and share knowledge.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNot able to see the serialized plugin context XML file in the c:\windows\temp foldermemberMember 95642485 Nov '12 - 6:36 
AnswerRe: Not able to see the serialized plugin context XML file in the c:\windows\temp foldermemberDinesh Uthayakumar11 Nov '12 - 5:05 
GeneralCRM 2011 plansmemberAndrew Swerlick27 Oct '10 - 4:40 
GeneralRe: CRM 2011 plansmemberAndrew Swerlick30 Oct '10 - 7:03 
GeneralRe: CRM 2011 plansmemberDinesh Uthayakumar2 Nov '10 - 2:35 
GeneralRe: CRM 2011 plansmemberAndrew Swerlick8 Nov '10 - 4:16 
GeneralRe: CRM 2011 plansmemberAndrew Swerlick18 Nov '10 - 8:14 
GeneralRe: CRM 2011 plansmemberDinesh Uthayakumar18 Nov '10 - 17:55 
GeneralMy vote of 5memberasenthil9 Jul '10 - 2:49 
QuestionHow is it different than http://code.msdn.microsoft.com/crmpluginsamples ?membermaruf_d6 Jul '10 - 7:09 
AnswerRe: How is it different than http://code.msdn.microsoft.com/crmpluginsamples ?memberDinesh Uthayakumar8 Jul '10 - 4:30 
GeneralGood one manmemberGladson WiIlliam29 Jun '10 - 2:53 
GeneralMy vote of 4memberDiwakar Gupta27 Jun '10 - 23:16 
GeneralMy vote of 5memberpramodnair.m27 Jun '10 - 23:02 
GeneralMy vote of 5memberSaurabh_Agrawal27 Jun '10 - 21:48 
GeneralMy vote of 4memberMember 442415727 Jun '10 - 21:01 
GeneralMy vote of 4membervivek1488227 Jun '10 - 20:30 
GeneralMy vote of 4memberPratap Halder27 Jun '10 - 20:21 
GeneralMy vote of 4memberBaljeetSingh Sucharia27 Jun '10 - 20:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 23 Jul 2010
Article Copyright 2010 by Dinesh Uthayakumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid