The following plug-in code is based on the requirement that the records of myapp_myentity CRM entity can only be used to be assigned to the users who have "Schedule Manager" role.
using System; using System.Xml; using Microsoft.Crm.Sdk; namespace MyEntity { /// <summary> /// CRM Plugin to demonstrate how to use Assign message. /// /// The Plugin should be registered as : /// /// Primary Entity: myapp_myentity /// Message: Assign /// Stage: Pre Stage /// Mode: Synchronous /// </summary> public class PreAssign : IPlugin { const string entityName = "myapp_myentity"; const string allowedCrmRole = "Schedule Manager"; public void Execute(IPluginExecutionContext context) { // Verify the message context if (context.InputParameters.Properties.Contains("Target") || context.InputParameters.Properties["Target"] is Moniker == false || context.PrimaryEntityName != entityName) { return; } // Retrieve the new assignee from plug-in context SecurityPrincipal assignee = (SecurityPrincipal) context.InputParameters.Properties["Assignee"]; // Ensure the new assignee has the specified role using (ICrmService crmService = context.CreateCrmService(true)) { EnsureNewAssigneeIsInRole(crmService, assignee, allowedCrmRole); } } private void EnsureNewAssigneeIsInRole(ICrmService crmService, SecurityPrincipal assignee, string role) { // Query to check if the user is in the role. string fetchXml = string.Format(@" <fetch mapping='logical' aggregate='true'> <entity name='systemuser'> <attribute name='systemuserid' aggregate='count' alias='count' /> <filter> <condition attribute='systemuserid' operator='eq' value='{0}' /> </filter> <link-entity name='systemuserroles' from='systemuserid' to='systemuserid' link-type='inner'> <link-entity name='role' from='roleid' to='roleid' link-type='inner'> <filter> <condition attribute='name' operator='eq' value='{1}' /> </filter> </link-entity> </link-entity> </entity> </fetch> ", assignee.PrincipalId, role); string fetchResult = crmService.Fetch(fetchXml); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(fetchResult); XmlNode xn = xmlDoc.SelectSingleNode("//resultset/result/count"); if (Convert.ToDecimal(xn.InnerText) == 0) { string exceptionMsg = string.Format("The CRM record can only be assiged to a user with \"{0}\" role. ", role); throw new InvalidPluginExecutionException(exceptionMsg); } } } }The key to work with Assign message is to retrieve the Assignee secruity principal from the plug-in execution context object by using Assignee property of the input parameters, as shown below:
SecurityPrincipal assignee = (SecurityPrincipal) context.InputParameters.Properties["Assignee"];An additional note, if you need to get the record's ID, you can use the following code:
Moniker moniker = (Moniker)context.InputParameters.Properties["Target"]; Guid id = moniker.Id;As you can tell from the code, the plug-in has to be registered with the target entity's Assign message of Pre Stage using Synchronous execution mode.
Hope this helps.
Hi,
ReplyDeleteI have the same code,
just i'm trying to update custom entity,here is my code
thank you for any help:
//Create an instance of TargetOwnedDynamic class.
TargetOwnedDynamic target = new TargetOwnedDynamic();
//Create an instance of SecurityPrincipal class also to specify the SecurityPrincipalType (user type user/team)
//and to pass the Owner(user) Guid.
SecurityPrincipal assignee = new SecurityPrincipal();
assignee.Type = SecurityPrincipalType.User;
assignee.PrincipalId = GetcurrentUser(service);
// pass the account Guid to EntityId and the Entity name.
Guid oitraffick = ((Key)oi.Properties["datasurf_oi_traffickid"]).Value;
//Guid idTraffick = getEntity.GetGuid(oi, service, metaservice);
target.EntityId = oitraffick;
target.EntityName = "datasurf_oi_traffick";
//Create an instance of AssignRequest class and pass the TargetOwnedDynamic and SecurityPrincipal objects to it.
AssignRequest req = new AssignRequest();
req.Assignee = assignee;
req.Target = target;
//Execute the AssignRequest object.
AssignResponse res = (AssignResponse)service.Execute(req);