In D365 V8, GrantAccessRequest message was not available for which we were using SOAP request in JavaScript to share a record with a user.
As part of upgrade activities, since SOAP requests are going to be deprecated, now we have replaced our SOAP request with Web API and calling custom action from Web API as we have GrantAccessRequest message in D365 V9. More details here.
Below are the steps we performed :
- Create a Global custom action which takes 3 input parameters and Activate it.
- EntityName: Schema name of entity
- RecordId: GUID of record to be shared
- UserId: GUID of user with which records will be shared
- Create a plugin for the custom action “sab_MAFFinanceSharePhoneCallorOfferDetailwithUser”
- For the corresponding plugin xml element in crmregister file, use PrimaryEntityName=”none” and MessageName=”sab_maffinancesharephonecallorofferdetailwithuser”
- Use below line of code in the constructor of the plugin
this.RegisteredEvents.Add(new Tuple(40, "sab_MAFFinanceSharePhoneCallorOfferDetailwithUser", "", new Action(this.ExecuteCrmPlugin)));
- Use the below block of code in the plugin created which reads the input parameters sent and shares the record(gives Read Access to the User Id passed to the Record Id passed)
protected override void ExecuteCrmPlugin(LocalPluginContext localContext) { if (localContext == null) { throw new InvalidPluginExecutionException("localContext"); } string entityName = string.Empty; Guid recordId = Guid.Empty; Guid userId = Guid.Empty; if (localContext.PluginExecutionContext.InputParameters.Contains("EntityName")) { entityName = (string)localContext.PluginExecutionContext.InputParameters["EntityName"]; } if (localContext.PluginExecutionContext.InputParameters.Contains("RecordId")) { recordId = new Guid((string)localContext.PluginExecutionContext.InputParameters["RecordId"]); } if (localContext.PluginExecutionContext.InputParameters.Contains("UserId")) { userId = new Guid((string)localContext.PluginExecutionContext.InputParameters["UserId"]); } if (!string.IsNullOrEmpty(entityName) && recordId != Guid.Empty && userId != Guid.Empty) { var userIdReference = new EntityReference("systemuser", userId); var grantAccessRequest = new GrantAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.ReadAccess, Principal = userIdReference }, Target = new EntityReference(entityName, recordId) }; localContext.OrganizationService.Execute(grantAccessRequest); } }
- In JavaScript, use the below code to call the custom action in Web API
TestSharePhoneCallRecord: function () { try { var parameters = {}; parameters.EntityName = "phonecall";// for testing purpose parameters.RecordId = "196ABB32-88D7-E811-A955-000D3AB5A6AE"; //GUID of an existing record parameters.UserId = "B0BBCE82-4541-E811-811E-5065F38B5691"; //GUID of a user var req = new XMLHttpRequest(); req.open("POST", Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.0/sab_MAFFinanceSharePhoneCallorOfferDetailwithUser", true); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "application/json; charset=utf-8"); req.onreadystatechange = function () { if (this.readyState === 4) { req.onreadystatechange = null; if (this.status === 204) { //Success - No Return Data - Do Something } else { //Xrm.Utility.alertDialog(this.statusText); } } }; req.send(JSON.stringify(parameters)); } catch (ex) { //Xrm.Utility.alertDialog('Exception: ' + ex); } }
- To test, call the above JavaScript code on Load of Phone Call form. Then Save the changes and Publish it.
- Next time, when we load the Phone call record, we can see that the phone call record has been shared with user.
Hope it helps !!