If the Team has no users in it, Case should be assigned to the default queue of Team.
If the Team has users, the Case should be assigned to the user with the least number of cases.
- If more than one user in the Team have the same number of cases, then the case should be randomly assigned to one of them.
Section 1
Step 1
Create a new project in Visual Studio of type Class Library and give the name. I have given the name as AssignPlugin and don't forget to set the framework version to 4.5.2.

Step 2
Add the required references to project from CRM SDK.
Step 3
Remove the existing class from the project and add a new class to the project with some name like AssignTeamToUser.cs.
Open this class, make it public, add namespace “Microsoft.Xrm.Sdk” and inherit “IPlugin” interface, which is required for the plugin.
IPlugin requires Execute method to be implemented, so add it to our class.
Now, the code should look, as shown below.- using Microsoft.Xrm.Sdk;
- using System;
- namespace AssignPlugin
- {
- public class AssignTeamToUser : IPlugin
- {
- public void Execute(IServiceProvider serviceProvider)
- {
- }
- }
- }
Now, we need to add some boilerplate code for some null checks and obtain plugin context and organization Service reference. It's a good idea to maintain business logic separately, so BusinessLogic method in it will contain our Business Logic.
- using Microsoft.Xrm.Sdk;
- using System;
- namespace AssignPlugin
- {
- public class AssignTeamToUser : IPlugin
- {
- public void Execute(IServiceProvider serviceProvider)
- {
- if (serviceProvider == null) return;
- // Obtain the Plugin Execution Context
- var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
- // Obtain the organization service reference.
- var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
- var service = serviceFactory.CreateOrganizationService(context.UserId);
- // To check depth
- if (context.Depth > 2) return;
- // The InputParameters collection contains all the data passed in the message request.
- if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
- {
- // Business logic goes here
- new AssignTeamToUser().BusinessLogic(service, context);
- }
- }
- private void BusinessLogic(IOrganizationService service, IExecutionContext context)
- {
- // Business Logic
- }
- }
- }
While registering plugin in Assign step, it will have two Input parameters in context with the name Target & Assignee, we will pick them in the variable for further use. See the code given below.
- private void BusinessLogic(IOrganizationService service, IExecutionContext context)
- {
- // We are hitting Assign button on a Case record so Target will be a Case record
- var caseEntityReference = (EntityReference)context.InputParameters["Target"];
- // Assignee could be a User or Team
- var teamEntityReference = (EntityReference)context.InputParameters["Assignee"];
- // In our requirement it should be a Team, otherwise return
- if (teamEntityReference.LogicalName != "team") return;
- }
Step 6
Now, let’s jump into the main game. We will retrieve all the users in the given team, using fetchXml. Add namespace Microsoft.Xrm.Sdk.Query in our class, so FetchExpression will be available for the user.- private void BusinessLogic(IOrganizationService service, IExecutionContext context)
- {
- // We are hitting Assign button on a Case record so Target will be a Case record
- var caseEntityReference = (EntityReference)context.InputParameters["Target"];
- // Assignee could be a User or Team
- var teamEntityReference = (EntityReference)context.InputParameters["Assignee"];
- // In our requirement it should be a Team, if user it should return
- if (teamEntityReference.LogicalName != "team") return;
- // fetchXml to retrieve all the users in a given Team
- var fetchXmlLoggedUserInTeam = @"
- <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
- <entity name='systemuser'>
- <attribute name='systemuserid' />
- <link-entity name='teammembership' from='systemuserid' to='systemuserid' visible='false' intersect='true'>
- <link-entity name='team' from='teamid' to='teamid' alias='ac'>
- <filter type='and'>
- <condition attribute='teamid' operator='eq' uitype='team' value='{0}' />
- </filter>
- </link-entity>
- </link-entity>
- </entity>
- </fetch>";
- // Passing current Team is fetchXml and retrieving Team's user
- var users = service.RetrieveMultiple(new FetchExpression(string.Format(
- fetchXmlLoggedUserInTeam,
- teamEntityReference.Id))).Entities;
- }
Step 7
If FetchExpression` in the last step returns no users, then we will assign case record for the default queue of the Team, using AddToQueueRequest, add namespace Microsoft.Crm.Sdk.Messages in order to use the same.
Here, we are retrieving Id of default Queue of Team, which is used in DestinationQueueId parameter of AddToQueueRequest and in Target parameter, our case record is given.
Now, complete the code for the given condition and it should look, as shown below.- using Microsoft.Crm.Sdk.Messages;
- using Microsoft.Xrm.Sdk;
- using Microsoft.Xrm.Sdk.Query;
- using System;
- namespace AssignPlugin
- {
- public class AssignTeamToUser : IPlugin
- {
- public void Execute(IServiceProvider serviceProvider)
- {
- if (serviceProvider == null) return;
- // Obtain the Plugin Execution Context
- var context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
- // Obtain the organization service reference.
- var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
- var service = serviceFactory.CreateOrganizationService(context.UserId);
- // To check depth
- if (context.Depth > 2) return;
- // The InputParameters collection contains all the data passed in the message request.
- if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)
- {
- // Business logic goes here
- new AssignTeamToUser().BusinessLogic(service, context);
- }
- }
- private void BusinessLogic(IOrganizationService service, IExecutionContext context)
- {
- // We are hitting Assign button on a Case record so Target will be a Case record
- var caseEntityReference = (EntityReference)context.InputParameters["Target"];
- // Assignee could be a User or Team
- var teamEntityReference = (EntityReference)context.InputParameters["Assignee"];
- // In our requirement it should be a Team, if user it should return
- if (teamEntityReference.LogicalName != "team") return;
- // fetchXml to retrieve all the users in a given Team
- var fetchXmlLoggedUserInTeam = @"
- <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
- <entity name='systemuser'>
- <attribute name='systemuserid' />
- <link-entity name='teammembership' from='systemuserid' to='systemuserid' visible='false' intersect='true'>
- <link-entity name='team' from='teamid' to='teamid' alias='ac'>
- <filter type='and'>
- <condition attribute='teamid' operator='eq' uitype='team' value='{0}' />
- </filter>
- </link-entity>
- </link-entity>
- </entity>
- </fetch>";
- // Passing current Team is fetchXml and retrieving Team's user
- var users = service.RetrieveMultiple(new FetchExpression(string.Format(
- fetchXmlLoggedUserInTeam,
- teamEntityReference.Id))).Entities;
- // Condition 1
- // If user count is zero case should be assigned to Team's default Queue
- if (users.Count == 0)
- {
- var team = service.Retrieve("team", teamEntityReference.Id, new ColumnSet("queueid"));
- var addToQueueRequest = new AddToQueueRequest
- {
- Target = caseEntityReference,
- DestinationQueueId = team.GetAttributeValue<EntityReference>("queueid").Id
- };
- service.Execute(addToQueueRequest);
- }
- } }
- }
Step 8







AJIT AGARWALPosted Nov 20, 2018, 9:04 AM
//contact -->description //incident--description Entity entity = (Entity)context.InputParameters["Target"]; if (entity.LogicalName.ToLower() =="contact") { if (entity.Attributes.Contains("contactid") == true) { try { Entity incidentEntity = new Entity("incident"); if (entity.Attributes["contactid"].ToString() == incidentEntity.Attributes["contactid"].ToString()) { incidentEntity.Attributes["description"] = entity.Attributes["description"].ToString(); client.Update(incidentEntity); } else { throw new InvalidPluginExecutionException("Contactid and indent id not same"); } } catch (FaultException ex) { throw new InvalidPluginExecutionException("An error occured in update plugin: " + ex.ToString()); } catch (Exception ex) { throw new InvalidPluginExecutionException("An error occured in update plugin:" + ex.ToString()); }
AJIT AGARWALPosted Nov 20, 2018, 9:03 AM
I m new in dynamic crm. I want contact description in incident note value on post image..
lipsita priyadarshiniPosted Nov 16, 2018, 12:20 AM
Hey It's very helpful. Can u please provide me the fetch Xml To get the number of active cases assigned, i am facing problem "XML not well formed" if i am giving my own fetch Xml.It's urgent My mail id - [email protected]
Komalpreet KaurPosted Aug 13, 2018, 3:47 AM
Great Help. In my case i m getting this exception "Download the details and load with Plug-in Profiler". Tried lot of options but unable to resolve the issue
Razim KhanPosted Jul 26, 2017, 4:03 AM
This is very helpfull for me , i was given a task the same. in my case team is specified.where i will give static team GUID ? plz guide me
Bhargav BennalliPosted Apr 6, 2017, 2:28 AM
Its very helpfull Ashish.. can u please explain more plugins like this? with different scenariaos.. using images etc
Vivek KumarPosted Mar 16, 2017, 12:52 AM
Very informatic article