CRM 2013 – Step by Step Update Plugin Tutorial using the CRM 2013 Development Toolkit


CRM 2013 – Create a simple plugin in CRM 2013 using the CRM Development Toolkit

 I would recommend looking at the CRM 2013 SDK because it is very useful and documents what all the options available.   The reason I made this blog post and Hosk’s CRM Dev YouTube channel is The CRM 2013 SDK is a great resource but can be a little bit difficult to get started with but hopefully with the blog post and the video I will make it easier for you.

This video will a bit of plugin theory (the blog will just contain the steps to create and deploy the plugin) and I will try and explain what we are doing and practical because I will go through the process of creating and deploying the plugin, step by step.

You should have already watched these videos and are at the stage where you have CRM 2013 Developer Toolkit setup and pointing at your CRM 2013 organisation.  If not watch the videos below

Created your CRM 2013 Trial

Blog Setup the CRM 2013 Developer Toolkit

Video step by step guide to setting up the CRM 2013 Developer Toolkit

Blog – Setup and understand Solutions

Video - CRM 2013 – Understanding Solutions and how they work in CRM 2013 

Now it’s time to create a very simple plugin

Open Visual studio, you should have already setup the Visual Studio Developer toolkit, I created a package as shown in the picture below

setup CRM dev toolkit 1

This will Create a package, I removed the workflow project so I am just left with CrmPackage and Plugins projects

Create Plugin 7

The important files above are the


This RegisterFile.crmregister is a file which holds the plugin registration data any plugins created in your CrmPackage.  The details are then used to deploy plugins to CRM


This is a default file created by the CRM 2013 Development Toolkit.  When you create a plugin, it will extend the Plugin class and use it as a base.   The Plugin class uses the IPlugin interface and has the important Execute methods which all CRM plugins must have and this is the main method called.

CRM Solution

Make sure you connected to the correct CRM organisation and you have specified the correct Solution, so when you deploy your plugin it will be included in the correct solution.

You can check this by going to

Tools –> Connect to Dynamics CRM Server

Press the Log on button and then you will be able to select an organisation value and a solution

Create Plugin 0


To create a plugin open the CRM Explorer


Select Account

Right click and choose Create Plugin 

Create Plugin 4

The Create plugin screen will be displayed.

Below I am creating a plugin to run on the update of the account entity

Create Plugin 1

The Create Plug-in dialog box appears with the fields in the following table.  This information was taken from the CRM 2013 SDK

  1. Field Description
    Project The plug-in library project in your Visual Studio solution.
    Class A recommended class name based on the selected pipeline stage and message.
    Primary Entity The entity that must be processed by the execution pipeline for the plug-in to execute.
    Secondary Entity Some messages require a secondary entity. See the documentation on the specific message for more information.
    Message The message that must be processed by the Microsoft Dynamics CRM execution pipeline for the plug-in to execute.
    Filtering Attributes A list of entity attributes that cause the plug-in to execute when it is changed. A value of null causes the plug-in to execute if any of the attributes change. When you specify a message that supports filtering attributes, for example Update, an ellipsis (…) button is displayed that lets you select attributes from a list.
    Run in Context Specify the system account that owns any data changes the plug-in makes. The Calling User is the logged on user who initiated the message to be processed. For more information, see Impersonation in Plug-Ins.
    Execution Order Specifies the order, also known as rank, that plug-ins are executed in a pipeline stage. Plug-ins registered by using an order value of 1 are executed first, followed by plug-ins registered by using an order of 2, and so on. However, if there is more than one plug-in in a stage with the same order value, the plug-in with the earliest compilation date is called first.
    Pipeline Stage Specifies when you want the plug-in to execute: before (Pre) or after (Post) the core operation that processes the message. For more information, seeEvent Execution Pipeline.
    Deployment Specify where you want the plug-in deployed: on the server, on Microsoft Dynamics CRM for Outlook with Offline Access, or both.
    Execution Mode For plug-ins registered to execute in a post stage, specify if you want them to execute immediately (synchronous) or queued to execute later (asynchronous). For post operations, specifying asynchronous execution gives you improved system performance compared to synchronous execution.
    Description A description of the step. Typically, you can describe the purpose of the step for other developers or administrators who might run the registration tool at a later date.
    Unsecure Configuration If you have written a constructor for the plug-in that takes one or two string arguments, any string values that you specify in these fields are passed to the plug-in constructor at run-time. For more information, see Write a Plug-In.
    Secure Configuration
    Pre Image Alias A pre-image is a snapshot of the entity’s attributes before the core operation. The entity alias value that you specify is used by your plug-in code as the key into the image collection.
    Parameters The list of attributes to be include in the pre-image.
    Post Image Alias A post-image is a snapshot of the entity’s attribute after the core operation. The entity alias value that you specify is used by your plug-in code as the key into the image collection.
    Parameters The list of attributes to be include in the post-image.

After you have finished selecting the choices for the plugin and press the OK button, a  new file called PreAccountUpdate.cs will be created in the Plugin project.  This will extend the Plugin class (a class created by the CRM 2013 Development Toolkit) and there will be a section for you to put in the code you want to execute in the plugin.

The Development Toolkit will also update the RegisterFile.crmregister adding a new line for the account plugin you have added.  Warning if you have this file checked into source control it might not editable and you will get an error because the Development Toolkit will try to update the RegisterFile.crmregister but won’t be able to because it’s read only.

You will notice the guid values in the RegisterFile.crmregister are all 0000, this because proper guid values will be created when you register the plugin in CRM, at the moment the plugin does not exist in CRM yet. Below is the RegisterFile with the plugin that has been deployed so the guids have values.

<?xml version="1.0" encoding="utf-8"?>
<Solution Assembly="HoskCRMDev2013.Plugins.dll" Id="df794508-c1ba-e311-9d03-d89d6765d360" IsolationMode="Sandbox" SourceType="Database">
<Plugin Description="Plug-in to PreAccountUpdate" FriendlyName="PreAccountUpdate" Name="HoskCRMDev2013.Plugins.PreAccountUpdate" Id="e2794508-c1ba-e311-9d03-d89d6765d360" TypeName="HoskCRMDev2013.Plugins.PreAccountUpdate">
<clear />
<Step CustomConfiguration="" Name="PreAccountUpdate" Description="Pre-Operation of Account Update" Id="d507df0f-c2ba-e311-bb7d-d89d6763fc38" MessageName="Update" Mode="Synchronous" PrimaryEntityName="account" Rank="1" SecureConfiguration="" Stage="PreInsideTransaction" SupportedDeployment="ServerOnly">
<Images />
<XamlWorkflows />

Sign the Plugin

All plugins in CRM 2013 must be signed.  You do this by

Right Clicking the Plugin Project

Go to the Signing Tab

tick the Sign Assembly checkbox

look up an existing Key or create a new one 

You don’t need to set a password if you don’t want to

save the changes and close the Plugin Properties page

Create Plugin 2

Create the Plugin Code

I am creating a very simple plugin, all it does it update the Description field on the account form when the account update is triggered, which will be 30 seconds because this will be triggered by the CRM 2013 autosave feature.

If the Description has been changed we overwrite it and if it hasn’t we add the description field

I am going to write this value


Create Plugin 3

namespace HoskCRMDev2013.Plugins
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;

/// <summary>
/// PreAccountUpdate Plugin.
/// Fires when the following attributes are updated:
/// All Attributes
/// </summary>
public class PreAccountUpdate: Plugin
/// <summary>
/// Initializes a new instance of the <see cref=”PreAccountUpdate”/> class.
/// </summary>
public PreAccountUpdate()
: base(typeof(PreAccountUpdate))
base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(20, „Update”, „account”, new Action<LocalPluginContext>(ExecutePreAccountUpdate)));

// Note : you can register for more events here if this plugin is not specific to an individual entity and message combination.
// You may also need to update your RegisterFile.crmregister plug-in registration file to reflect any change.

/// <summary>
/// Executes the plug-in.
/// </summary>
/// <param name=”localContext”>The <see cref=”LocalPluginContext”/> which contains the
/// <see cref=”IPluginExecutionContext”/>,
/// <see cref=”IOrganizationService”/>
/// and <see cref=”ITracingService”/>
/// </param>
/// <remarks>
/// For improved performance, Microsoft Dynamics CRM caches plug-in instances.
/// The plug-in’s Execute method should be written to be stateless as the constructor
/// is not called for every invocation of the plug-in. Also, multiple system threads
/// could execute the plug-in at the same time. All per invocation state information
/// is stored in the context. This means that you should not use global variables in plug-ins.
/// </remarks>
protected void ExecutePreAccountUpdate(LocalPluginContext localContext)
if (localContext == null)
throw new ArgumentNullException(„localContext”);

// TODO: Implement your custom Plug-in business logic.
// Obtain the execution context from the service provider.
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains(„Target”) &&
context.InputParameters["Target"] is Entity)
// Obtain the target entity from the input parmameters.
Entity entity = (Entity)context.InputParameters["Target"];

if (entity.LogicalName == „account”)
if (entity.Attributes.Contains(„description”))
//string entityDescription = (string)entity.Attributes["description"];
entity.Attributes["description"] = entityDescription;
entity.Attributes.Add(„description”, entityDescription);

catch (FaultException ex)
throw new InvalidPluginExecutionException(„An error occurred in the plug-in.”, ex);


Now you have finished writing the code, it’s time to deploy the plugin in CRM.  Your user will need to be a CRM Administrator.  If you are deploying plugins which are not in sandbox Isolation mode then you will also need to be a Deployment Administator.

As I am deploying to CRM 2013 online then the plugin has to be only a CRM Administrator because the plugin has to be in sandbox isolation mode.

Right Click on CrmPackage

Press the Deploy button

You will either get an error or it will have worked.  Often when it has worked it will inform you the RegisterFile.crmregister file has changed, this is CRM 2013 Developer Toolkit updating the file with Guid’s for the plugins.

Create Plugin 8

Check the plugin has been registered in the CRM organisation\database by looking at the CRM Explorer and checking in the Plug-in Assemblies section, you should see your new plugin highlighted in green

Create Plugin 5

You can also check by opening your Solution and looking in the plugin assembles section.

Create Plugin 6

I hope you subscribe to Hosk’s CRM Dev youtube channel where I will be going through the lots of different ares of CRM 2013 Development, this is useful for people who are starting out CRM Development, Developers who haven’t used CRM 2013 yet or just CRM Developers.

I am also studying for the MB2-703 – CRM 2013 Customization and Configuration exam and have a playlist with those videos

CRM 2011 – Setting an OptionSetValue in a plugin

I had to set an OptionSetValue in a plugin this week and for some reason I totally forgot how to do it, which kept causing my plugin to crash.

Like all things in CRM, once you have done it you wonder what all the fuss was about and how simple it seems but before you have cracked it, it can be very frustrating.

The other unusual thing I found was I couldn’t Google any examples, so I thought I would show an example on this blog so if I can’t do it in the future at least I would know where to look.

I will briskly take you through the basics.  OptionSetValue is a drop down list in CRM.  The OptionSetValue is a list of int values linked with a metadata list of text values.  I think it is done like this so you can store the OptionSets in a database and you have to split them up.

If  you want to find the text value you have to lookup the value in the metadata, I have blogged about that before, go here if you want to know how to look up the metadata value of an optionSet

The main thing which was confusing me is firstly OptionSetValue is a class and to then get the actual OptionSetValue you have to put you class name and then Value.  For some reason I was then trying to set just the value, which is stupid when I think about it but it was late on a Friday and my brain had clearly stopped working for the week.

OptionSetValue is a class and it has two constructors, click here for the api

Name Description
OptionSetValue () Initializes a new instance of the OptionSetValue class
OptionSetValue (Int32) Initializes a new instance of the OptionSetValue class

Now you can see that one of the constructors takes an int32 value.  Most of the time if you are creating an OptionSetValue which you want to write to a CRM object then you will pass in the int value of the optionset.  This is a common Gotcha, people will often set this value to a value which isn’t in the OptionSet values in CRM.  To find the values, you need to open the entity going through solutions (basically as if you are going to edit it) with the optionset you want the values for.

Selected the optionSet in the fields, open the optionSet until you have a list of the Options.  When you select one of the options you will see on the right it shows you the optionset Label and below that is the value (which is an int)

So from the above you can see the int number you want to assign to the optionSetValue is 143570000.

so to create and set an OptionSetValue you would do this

    OptionSetValue op = new OptionSetValue(143570000);
                shortlist.new_StatusSelectedCheckbox = op;

In the example shortlist is an entity object and new_StatusSelectedCheckbox is the field.  To get the value from an optionSetValue you would do this


the number below is the value.

As I have said before one of the most common problems people will experience is they will try and set an OptionSetValue to an int number not in the list of dropdown values.

The OptionSetValue class api is here but it really only has the Value method to set and get int value of the OptionSetValue class

CRM 2011 – Importing/exporting data between organisations

Transferring Data from One CRM Organization to Other Organization

Many a times you would have the need to transfer data from one Microsoft Dynamics CRMorganization to another for some record type. This blog covers the steps you can follow to move data from one organization to another using Import Wizard. Let us take example that you want to move data for Account and Contact record types.

1. Create a view of all fields for the record type Account.

a. Go to accounts Grid and click on Create personal view


  • Click Edit Columns in the dialog that pops up and then click Add Columns.


  • Click the checkbox in the header to select all columns. (This will export data for all columns, some of which may not be importable)


  • Click ‘ok’ and then Click ‘Save’ on the Ribbon in Advanced find dialog. It will prompt you for name of the view .Provide the name for the view.

2. Navigate to view (Account) and Export the data in Static Excel format.

a) Go to Accounts Grid.

b) Navigate to Accounts view.

c) Click Export to Excel.


d) Select “Static worksheet with records from all pages in current view”.


e) Click Export and save the file. (Account.xls)(The records that are exported will be based on the record for which you had privileges).

f) Save the file in CSV /XMLSS format from Excel. (Account.csv)

Note: Do not check make this data available for reimport checkbox as this feature is meant to export and update data in the same organization and not for cross organization data migration.

2: Similarly export the data for Contact record type and save as CSV/XMLSS file.(Contact.csv).

3: Zip the two files in a single Zip file (

4: Use Import Wizard to Import the file

  • Launch Import Wizard and Upload the zip file in Import Wizard.
  • Select Default (Auto mapping) as shown in the screenshot below.


As the file names match with the Record type display name in this example so files will be automatically mapped. (Map the files with respective record types if they are not auto mapped.)

  • At Map field page, fields whose name matches will automatically will be mapped. Check the mappings and if there are fields which are not mapped then map those. If there are customizations (e.g. some custom fields) that you want to do you can do it from Import Wizard itself. You can create new field from Import Wizard and do the mappings. If you want to ignore all unmapped fields, click Next. All unmapped fields will be ignored.


  • Finish the Import Wizard and Wait for Import jobs to finish. You can check their status in Imports grid. That is it you are done Importing data for these record types.

CRM 2011 – Using Javascript to identifying if a form is in Create or Update Contect

Here is a quick tip to tell if a form is being created or updated in Javascript, this can be very useful for form load events and creating code which needs to be run when a form is being created, like setting the values of variables when a form is created.

var  formType= Xrm.Page.ui.getFormType();
getFormType() function returns a number
If the return value is 1 –  Form context is Create
If the return value is 2 –  Form context is Update

Disable Field In Microsoft CRM 2011

Przykład funkcji Disabled Field
function DisabledField(picklistName, fieldName) {
    if (Xrm.Page.getAttribute(picklistName).getSelectedOption() != null) {
        var selectedGenderValue = Xrm.Page.getAttribute(picklistName).getSelectedOption().value;
        if (selectedGenderValue == 1)


CRM 2011 – Javascript and Subgrids code example


Kilka fajnych przykładów związanych z Subgrids

You can inspect the subgrid values on save by doing the following:

var gridControl = document.getElementById('subgrid_id').control; 
var ids = gridControl.get_allRecordIds(); 
 for(i = 0; i < ids.length; i++) 

 var cellValue = gridControl.getCellValue('column_name', ids[i]); 
 // logic 

Doing this on load is a bit more challenging since subgrids are loaded asynchronously and aren’t likely to be done loading when the form onload event fires. You can check the grid periodically though to see when it’s done loading by calling a function like the following in your form onload:

function subGridOnload() 

var grid = document.getElementById('grid_identifications'); 
 if (grid.readyState!="complete") 

 // delay one second and try again. 
 setTimeout(subGridOnload, 1000); 

// logic 

I then also found a forum post on attaching events to a subgrid, which you can read here

For CRM 2011, your code should look like this:

if (Xrm.Page.ui.getFormType() != 1) {

  Xrm.Page.ui.controls.get("IFRAME_OpportunityLines").onreadystatechange = function oppLineTotals() {
    if (Xrm.Page.ui.controls.get("IFRAME_OpportunityLines").readyState == 'complete') {
      var iFrame = frames[];
      iFrame.document.all.crmGrid.attachEvent("onrefresh", GridRefresh);

Funny thing, the sdk recomended function did not work for me (i.e.Xrm.Page.ui.controls.get(“GridName”) ), and yet the following works (tested!)

var grid = document.getElementById("GridName");
grid.attachEvent("onrefresh", EventHandlerFunction);

because the (Html Component) actually includes a public event “onrefresh”… And this event can be handled with any function. We dont need to dive into the eventManager and scriptEvents.

Microsoft Dynamics CRM 2011 – JavaScript Development

Xrm.Page.context Methods

  • getAuthenticationHeader: Returns the encoded SOAP header for MSCRM 4.0 style Web service calls
  • getCurrentTheme: Returns the current user’s Outlook theme
  • getOrgLcid: Returns the LCID value for the base language of the organization
  • getOrgUniqueName: Returns the unique organizations name
  • getQueryStringParameters: Returns an array of key-value pairs representing the query strings
  • getServerUrl: Returns the base server URL
  • getUserId: Returns the current user’s SystemUser id
  • getUserLcid: Returns the LCID value representing the user’s preferred language
  • getUserRoles: Returns an array of GUID values of the security roles the user is associated with
  • isOutlookClient: Returns a Boolean value indicating if the user is using Outlook client
  • isOutlookOnline: Returns a Boolean value indicating if the user is connected to the server while using MSCRM for Outlook with Offline Access
  • prependOrgName: Prepends the organization name to the specified path attribute Methods 

  • addOnChange: (Applicable: All) Sets a function to be called when the value is changed
  • fireOnChange: (Applicable: All) Causes the OnChange event to occur on the attribute
  • getAttributeType: (Applicable: All) Returns the type of attribute (string)
  • getFormat: (Applicable: All) Returns formatting options for the attribute (string)
  • getInitialValue: (Applicable: boolean, optionset) Returns the initial value for Boolean or optionset attributes
  • getIsDirty: (Applicable: All) Returns a Boolean value indicating if there are unsaved changes to the attribute value.
  • getMax: (Applicable: money, decimal, integer, double) Returns the maximum allowed value for an attribute (number)
  • getMaxLength: (Applicable: string, memo) Returns the maximum length of an attribute (number)
  • getMin: (Applicable: money, decimal, integer, double) Returns the minimum allowed value for an attribute (number)
  • getName: (Applicable: All) Returns the logical name of the attribute
  • getOption: (Applicable: optionset) Returns an option object by matching its name
  • getOptions: (Applicable: optionset) Returns an array of options for an optionset attribute
  • getParent: (Applicable: All) Returns the parent object to the attribute
  • getPrecision: (Applicable: money, decimal, double, integer) Returns the number of digits allowed after the decimal point
  • getRequiredLevel: (Applicable: All) Returns a string indicating whether the attribute is required or recommended
  • getSelectedOption: (Applicable: optionset) Returns the option selected in an optionset attribute.
  • getSubmitMode: (Applicable: All) Returns a string indicating if the attribute will be submitted when the record is saved
  • getText: (Applicable: optionset) Returns the selected option for an optionset attribute
  • getUserPrivilege: (Applicable: All) Returns an array of Boolean values indicating if the user can create/read/update an attribute’s values
  • getValue: (Applicable: All) Retrieves the data value for an attribute
  • removeOnChange: (Applicable: All) Removes a function from the OnChange event handler
  • setRequiredLevel: (Applicable: All) Sets whether the attribute is required or recommended
  • setSubmitMode: (Applicable: All) Sets whether the attribute’s data will be submitted
  • setValue: (Applicable: All) Sets the data value for an attribute.

Form Event Handler Execution Context Reference 

  • getContext: Returns the Xrm.Page.context object
  • getDepth: Returns a value indicating the order in which this handler is executed
  • getEventArgs: Returns an object with methods to manage the Save event
  • getEventSource: Returns a reference to the object that the event occurred on
  • getSharedVariable: Retrieves a variable set using setSharedVariable
  • setSharedVariable: Sets the value of a variable to be used by a hander after the current handler completes

Xrm.Page.ui control methods

  • addCustomView: (Lookup) Adds a new view for the lookup dialog
  • addOption: (Option Set) Adds an option to an Option set control
  • clearOptions: (Option Set) Clears all options for an Option Set control
  • getAttribute: (Standard, Lookup, Option Set) Returns the attribute that the control is bound to
  • getControlType: (All) Returns a value that categorizes controls
  • getData: (Silverlight Web resources) Returns the data query string parameter passed to a Silverlight Web resource
  • getDefaultView: (Lookup) Returns the ID value of the default lookup dialog view
  • getDisabled: (All) Returns a value indicating whether the control is disabled
  • getLabel: (All) Returns the label for the control
  • getName: (All) Returns the name assigned to the control.
  • getParent: (All) Returns a reference to the section object that contains the control.
  • getSrc: (IFrame, Web Resource) Returns the current URL being displayed in an IFRAME.
  • getInitialUrl: (IFrame) Returns the default URL of an IFrame control
  • getObject: (IFrame, Web resource) Returns the object in the form representing an IFrame or Web resource
  • getVisible: (All) Returns a value indicating if the control is visible
  • refresh: (SubGrid) Refreshes the data displayed in a Sub-Grid
  • removeOption: (Option Sets) Removes an option from an Option Set control
  • setData: (Silverlight Web resources) Sets the data query string parameter passed to a Silverlight Web resource.
  • setDefaultView: (Lookup) Sets the default view for the lookup dialog
  • setDisabled: (All except Web Resources) Sets a value indicating whether the control is disabled.
  • setFocus: (All) Sets the focus on the control.
  • setLabel: (All) Sets the label for the control.
  • setSrc: (IFrame and Web Resource) Sets the URL to be displayed in an IFrame.
  • setVisible: (All) Sets a value indicating if the control is visible Methods 

  • addOnSave: Sets a function to be called when the record is saved
  • getDataXml: Returns the xml string to be sent to the server when the record is saved
  • getEntityName: Returns the logical name of the entity for the record
  • getId: Returns GUID id value for the record
  • getIsDirty: Returns a Boolean value indicating if any fields in the form have been modified
  • removeOnSave: Removes a function from the OnSave event hander
  • save: Saves the record

Xrm.Page.ui Methods

  • close: Closes the form.
  • getCurrentControl: Returns the control that currently has focus
  • getFormType: Indicates the form context for the record
  • getViewPortHeight: Returns the height of the viewport in pixels
  • getViewPortWidth: Returns the width of the viewport in pixels
  • refreshRibbon: Causes the ribbon to refresh

Xrm.Page.ui.controls Collection Methods

  • forEach: Applies the action contained within a delegate function
  • get: Returns one or more controls
  • getLength: Returns the number of controls in the collection.

Xrm.Page.ui.navigation.items Collection Methods

  • forEach: Applies the action contained within a delegate function
  • get: Returns one or more navigation items
  • getLength: Returns the number of navigation items in the collection.

Xrm.Page.ui.formSelector members

  • items: (Collection) A collection of all accessible form items
  • getCurrentItem: (Method) Returns the form currently being shown.

Xrm.Page.ui.formSelector.items Collection Methods

  • forEach: Applies the action contained within a delegate function.
  • get: Returns one or more roleForms
  • getLength: Returns the number of roleForms in the collection.

Xrm.Page.ui.tabs Collection Methods

  • forEach: Applies the action contained within a delegate function
  • get: Returns one or more tabs
  • getLength: Returns the number of tabs in the collection. Collection Methods

  • forEach: Applies the action contained within a delegate function
  • get: Returns one or more attributes
  • getLength: Returns the number of items in the collection.

Shortcut methods

  • Xrm.Page.getAttribute:
  • Xrm.Page.getControl: Xrm.Page.ui.controls.get
  • GetGlobalContext (Web Resources): Xrm.Page.context (within forms)