Archive

Archive for the ‘Plugin’ Category

Unit Testing CRM 2011 Plugin

January 23, 2012 4 comments

As we all know the criticality of developing and deploying plugins in CRM. Let’s think the scenario of having 20 plugins in our project but we need to change one plugin. When we deploy this with Plugin registration tool, we are going on an assumption that other 19 are working properly and the one which is updated still needs to be tested on UAT/Production server. If we have a chance to test all 20 plugins without registering them on to server then that would be a great opportunity 🙂

Normally to test plugins we must register the plugin to CRM server before testing. This is a fairly lengthy process, making quick testing of changes, and well as automated unit testing is a difficult process.

There is a solution to this problem which was developed by Andrew Swerlick based on Dinesh’s Solution and is available at http://crm2011plugintest.codeplex.com/ Source files are available here, we can download and compile them. To make the solution work we need to look into patches and make the changes in code then compile.

or simply download the working dlls from here

By serializing the objects that the CRM server passes to a plugin on execution and then by using a library that allows us to de-serialize those objects and pass them to the plugin on our local machine we can simulate actually having the plugin registered against the server but without having to go through the process of registering it for each and every change.

I will be using a plugin which will add Business Phone to newly created contacts.

 Code of the plugin looks like

public class UpdateContactPhonePlugin : IPlugin
{
IOrganizationService service;
public void Execute(IServiceProvider serviceProvider)
{
Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

IOrganizationServiceFactory factory =(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

service = factory.CreateOrganizationService(context.UserId);

if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = (Entity)context.InputParameters["Target"];
try
{
if (entity.LogicalName == "contact")
{
entity.Attributes.Add("telephone1", "123456");
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.Message.ToString());
}
}
}
}

Once we sign and build the plugin project and ready with it we need to do the following to test.

Create a new project of type ClassLibrary and add Libraries folder which is having

  1. SerializePluginContext.dll
  2. TestPlugin.dll

 

 

Serializing the Plugin Context

 

  1. Register the SerializePluginContext plugin on the CRM server using the plugin registration tool. When registering the plugin, register it exactly as if we were registering the plugin we are testing, including setting up appropriate Pre-Images and Post-Images.
  2. Manually create Contact to fire off the plugin. Validate that it functioned without error by checking the system jobs entity for a successful record of plugin execution
  3. On the server go to C:\windows\temp\ and look for a file with a named [Primary Entity] – [Message], where primary entity is the primary entity we registered the plugin against, and the message is the CRM 2011 plugin message. In our case contact-Create-001.xml
  4. Copy this file back to local development machine and into solution folders.

 

Testing Plugin

 

Go to Program.cs file and add the code like

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;
using CRM2011.Plugin; //Reference to Plugin project

using Engage.Util.PluginTester; //Test Plugin
namespace CRM2011.UnitTestingPlugin

{

class Program{

static void Main(string[] args)

{

//Service Provider object with the context information of the file

//which got created by serializing the objects passed to SerializePluginContext

MyServiceProvider provider = new MyServiceProvider(

"domain\username",

"pwd",

"http://servername/orgname/XRMServices/2011/Organization.svc",

@"contact-Create-001.xml");
//Create object to Plugin class which we are going to test

UpdateContactPhonePlugin plugin = new UpdateContactPhonePlugin();
//Call the execute method by passing the provider with context information

plugin.Execute(provider);

}

}

}

Set this project as the StartUp project and add the debugging point before running. There we are, got the break point…

 

 

When we are running this project this will be using the existing file as the context so this will not going to create records. This way we can test it for any number of times without creating/updating the records.

That’s it we are done.. Hope this helps 🙂

CRM 2011 Restrict Duplicate Personal View

November 22, 2011 Leave a comment

Recently we got a request from one of our user to restrict the personal view with same name. Having my previous blog in mind, thought that we can do something with User Query entity but when I am trying to register a plugin on User Query entity User Query is not listed.

I am stuck. Then I took the help of CRM Development Forum to solve this, thanks to Mahender and Gayan Perera.

As mentioned by Gayan, I updated the SdkMessageFilter & SdkMessageFilterasifPublished tables and set IsCustomProcessingStepAllowed to 1 on the userquery entity. Then I was able to see the userquery entity in the plugin registration list.

Used the below code to restrict the duplicates in the personal views

EntityCollection listrecords = new EntityCollection();
FilterExpression filterExp = new FilterExpression();
filterExp = new FilterExpression()
{
Conditions =
{
new ConditionExpression ("name", ConditionOperator.Equal, name)
}
};
QueryExpression query = new QueryExpression()
{
EntityName = "userquery",
ColumnSet = new ColumnSet(new string[] { "name" }),
Criteria = filterExp
};

listrecords = service.RetrieveMultiple(query);

if (listrecords.Entities.Count > 0)
throw new InvalidPluginExecutionException("Personel View with this name already exists.");

This has given us a way to solve this in an unsupported way. My manager agreed to go with unsupported way so I did. Hope this will help somebody…