Click here to Skip to main content
Click here to Skip to main content
Go to top

Microsoft Dynamics CRM 4.0 Plug-in Testing and Debugging

, 23 Jul 2010
Rate this:
Please Sign up or sign in to vote.
A technique to test/debug the Microsoft Dynamics CRM 4.0 plug-in

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)

Share

About the Author

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

Comments and Discussions

 
QuestionNot able to see the serialized plugin context XML file in the c:\windows\temp folder PinmemberMember 95642485-Nov-12 6:36 
AnswerRe: Not able to see the serialized plugin context XML file in the c:\windows\temp folder PinmemberDinesh Uthayakumar11-Nov-12 5:05 
GeneralCRM 2011 plans PinmemberAndrew Swerlick27-Oct-10 4:40 
GeneralRe: CRM 2011 plans PinmemberAndrew Swerlick30-Oct-10 7:03 
GeneralRe: CRM 2011 plans PinmemberDinesh Uthayakumar2-Nov-10 2:35 
GeneralRe: CRM 2011 plans PinmemberAndrew Swerlick8-Nov-10 4:16 
GeneralRe: CRM 2011 plans PinmemberAndrew Swerlick18-Nov-10 8:14 
GeneralRe: CRM 2011 plans PinmemberDinesh Uthayakumar18-Nov-10 17:55 
GeneralMy vote of 5 Pinmemberasenthil9-Jul-10 2:49 
QuestionHow is it different than http://code.msdn.microsoft.com/crmpluginsamples ? Pinmembermaruf_d6-Jul-10 7:09 
AnswerRe: How is it different than http://code.msdn.microsoft.com/crmpluginsamples ? PinmemberDinesh Uthayakumar8-Jul-10 4:30 
GeneralGood one man PinmemberGladson WiIlliam29-Jun-10 2:53 
GeneralMy vote of 4 PinmemberDiwakar Gupta27-Jun-10 23:16 
GeneralMy vote of 5 Pinmemberpramodnair.m27-Jun-10 23:02 
GeneralMy vote of 5 PinmemberSaurabh_Agrawal27-Jun-10 21:48 
GeneralMy vote of 4 PinmemberMember 442415727-Jun-10 21:01 
GeneralMy vote of 4 Pinmembervivek1488227-Jun-10 20:30 
GeneralMy vote of 4 PinmemberPratap Halder27-Jun-10 20:21 
GeneralMy vote of 4 PinmemberBaljeetSingh Sucharia27-Jun-10 20:14 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 23 Jul 2010
Article Copyright 2010 by Dinesh Uthayakumar
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid