Sample: Share records using GrantAccess, ModifyAccess and RevokeAccess messages
Dynamics CRM 2016
Updated: November 29, 2016
Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online
This sample code is for Microsoft Dynamics 365 (online & on-premises). Download the Microsoft Dynamics CRM SDK package. It can be found in the following location in the download package:
SampleCode\CS\GeneralProgramming\EarlyBound\UserAccess.cs
Requirements
For more information about the requirements for running the sample code provided in this SDK, see Use the sample and helper code.
Demonstrates
This sample shows how to share a record using the following messages:
Example
using System; using System.Collections.Generic; using System.ServiceModel; using Microsoft.Crm.Sdk.Messages; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Query; namespace Microsoft.Crm.Sdk.Samples { public class UserAccess { #region Class Level Members private OrganizationServiceProxy _serviceProxy; private Guid _currentUserId; private List<Guid> _systemUserIds; private Guid _teamId; private Guid _leadId; private Guid _taskId; #endregion #region How To Sample Code public void Run(ServerConnection.Configuration serverConfig, bool promptforDelete) { using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials)) { // This statement is required to enable early bound type support. _serviceProxy.EnableProxyTypes(); CreateRequiredRecords(); // Retrieve and display the access that the calling user has to the // created lead. var leadReference = new EntityReference(Lead.EntityLogicalName, _leadId); var currentUserReference = new EntityReference( SystemUser.EntityLogicalName, _currentUserId); RetrieveAndDisplayPrincipalAccess(leadReference, currentUserReference, "Current User"); // Retrieve and display the access that the first user has to the // created lead. var systemUser1Ref = new EntityReference(SystemUser.EntityLogicalName, _systemUserIds[0]); RetrieveAndDisplayPrincipalAccess(leadReference, systemUser1Ref, "System User 1"); // Grant the first user read access to the created lead. var grantAccessRequest1 = new GrantAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.ReadAccess, Principal = systemUser1Ref }, Target = leadReference }; Console.WriteLine("Granting {0} to {1} ({2}) on the lead...\r\n", AccessRights.ReadAccess, GetEntityReferenceString(systemUser1Ref), "System User 1"); _serviceProxy.Execute(grantAccessRequest1); // Retrieve and display access information for the lead. RetrieveAndDisplayPrincipalAccess(leadReference, systemUser1Ref, "System User 1"); RetrieveAndDisplayLeadAccess(leadReference); // Grant the team read/write access to the lead. var teamReference = new EntityReference(Team.EntityLogicalName, _teamId); var grantAccessRequest = new GrantAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.ReadAccess | AccessRights.WriteAccess, Principal = teamReference }, Target = leadReference }; Console.WriteLine("Granting {0} to {1} ({2}) on the lead...\r\n", AccessRights.ReadAccess | AccessRights.WriteAccess, GetEntityReferenceString(teamReference), "Team"); _serviceProxy.Execute(grantAccessRequest); var systemUser2Ref = new EntityReference(SystemUser.EntityLogicalName, _systemUserIds[1]); // Retrieve and display access information for the lead and system user 2. RetrieveAndDisplayPrincipalAccess(leadReference, systemUser2Ref, "System User 2"); RetrieveAndDisplayLeadAccess(leadReference); // Grant the first user delete access to the lead. var modifyUser1AccessReq = new ModifyAccessRequest { PrincipalAccess = new PrincipalAccess { AccessMask = AccessRights.DeleteAccess, Principal = systemUser1Ref }, Target = leadReference }; Console.WriteLine("Granting delete access to {0} on the lead...\r\n", GetEntityReferenceString(systemUser1Ref)); _serviceProxy.Execute(modifyUser1AccessReq); // Retrieve and display access information for the lead. RetrieveAndDisplayLeadAccess(leadReference); // Revoke access to the lead for the second user. var revokeUser2AccessReq = new RevokeAccessRequest { Revokee = systemUser2Ref, Target = leadReference }; Console.WriteLine("Revoking access to the lead for {0}...\r\n", GetEntityReferenceString(systemUser2Ref)); _serviceProxy.Execute(revokeUser2AccessReq); // Retrieve and display access information for the lead. RetrieveAndDisplayPrincipalAccess(leadReference, systemUser2Ref, "System User 2"); RetrieveAndDisplayLeadAccess(leadReference); DeleteRequiredRecords(promptforDelete); } } private void RetrieveAndDisplayPrincipalAccess(EntityReference leadReference, EntityReference principal, String additionalIdentifier) { var principalAccessReq = new RetrievePrincipalAccessRequest { Principal = principal, Target = leadReference }; var principalAccessRes = (RetrievePrincipalAccessResponse) _serviceProxy.Execute(principalAccessReq); Console.WriteLine("Access rights of {0} ({1}) on the lead: {2}\r\n", GetEntityReferenceString(principal), additionalIdentifier, principalAccessRes.AccessRights); } private void RetrieveAndDisplayLeadAccess(EntityReference leadReference) { var accessRequest = new RetrieveSharedPrincipalsAndAccessRequest { Target = leadReference }; // The RetrieveSharedPrincipalsAndAccessResponse returns an entity reference // that has a LogicalName of "user" when returning access information for a // "team." var accessResponse = (RetrieveSharedPrincipalsAndAccessResponse) _serviceProxy.Execute(accessRequest); Console.WriteLine("The following have the specified granted access to the lead."); foreach (var principalAccess in accessResponse.PrincipalAccesses) { Console.WriteLine("\t{0}:\r\n\t\t{1}", GetEntityReferenceString(principalAccess.Principal), principalAccess.AccessMask); } Console.WriteLine(); } private String GetEntityReferenceString(EntityReference entityReference) { return String.Format("{0} with GUID {1}", entityReference.LogicalName, entityReference.Id); } /// <summary> /// Creates any entity records that this sample requires. /// </summary> public void CreateRequiredRecords() { // Create a unique identifier for this sample for preventing name conflicts. var sampleIdentifier = Guid.NewGuid(); // Retrieve/create the system users to use for the sample. var ldapPath = String.Empty; _systemUserIds = SystemUserProvider.RetrieveDelegates( _serviceProxy, ref ldapPath); // Retrieve the root business unit to use for creating the team for the // sample. var businessUnitQuery = new QueryExpression { EntityName = BusinessUnit.EntityLogicalName, ColumnSet = new ColumnSet("businessunitid"), Criteria = new FilterExpression() }; businessUnitQuery.Criteria.AddCondition("parentbusinessunitid", ConditionOperator.Null); var businessUnitResult = _serviceProxy.RetrieveMultiple(businessUnitQuery); var businessUnit = businessUnitResult.Entities[0].ToEntity<BusinessUnit>(); // Get the GUID of the current user. var who = new WhoAmIRequest(); var whoResponse = (WhoAmIResponse)_serviceProxy.Execute(who); _currentUserId = whoResponse.UserId; // Create a team for use in the sample. var team = new Team { AdministratorId = new EntityReference( "systemuser", _currentUserId), Name = String.Format("User Access Sample Team {0}", sampleIdentifier), BusinessUnitId = businessUnit.ToEntityReference() }; _teamId = _serviceProxy.Create(team); // Add the second user to the newly created team. var addToTeamRequest = new AddMembersTeamRequest { TeamId = _teamId, MemberIds = new[] { _systemUserIds[1] } }; _serviceProxy.Execute(addToTeamRequest); // Create a lead for use in the sample. var lead = new Lead { CompanyName = "User Access Sample Company", FirstName = "Sample", LastName = "Lead", Subject = "User Access Sample Lead", }; _leadId = _serviceProxy.Create(lead); // Create a task to associate to the lead. var leadReference = new EntityReference(Lead.EntityLogicalName, _leadId); var task = new Task { Subject = "User Access Sample Task", RegardingObjectId = leadReference }; _taskId = _serviceProxy.Create(task); // Create a letter to associate to the lead. var letter = new Letter { Subject = "User Access Sample Letter", RegardingObjectId = leadReference }; _serviceProxy.Create(letter); } private void DeleteRequiredRecords(bool prompt) { bool toBeDeleted = true; if (prompt) { // Ask the user if the created entities should be deleted. Console.Write("\nDo you want these entity records deleted? (y/n) [y]: "); String answer = Console.ReadLine(); if (answer.StartsWith("y") || answer.StartsWith("Y") || answer == String.Empty) { toBeDeleted = true; } else { toBeDeleted = false; } } if (toBeDeleted) { // Delete records created in this sample. _serviceProxy.Delete(Team.EntityLogicalName, _teamId); // Deleting the lead will delete its associated activities. _serviceProxy.Delete(Lead.EntityLogicalName, _leadId); Console.WriteLine("Entity record(s) have been deleted."); } } #endregion How To Sample Code #region Main method /// <summary> /// Standard Main() method used by most SDK samples. /// </summary> /// <param name="args"></param> static public void Main(string[] args) { try { // Obtain the target organization's web address and client logon // credentials from the user. ServerConnection serverConnect = new ServerConnection(); ServerConnection.Configuration config = serverConnect.GetServerConfiguration(); var app = new UserAccess(); app.Run(config, true); } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp); Console.WriteLine("Code: {0}", ex.Detail.ErrorCode); Console.WriteLine("Message: {0}", ex.Detail.Message); Console.WriteLine("Plugin Trace: {0}", ex.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == ex.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault"); } catch (System.TimeoutException ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Message: {0}", ex.Message); Console.WriteLine("Stack Trace: {0}", ex.StackTrace); Console.WriteLine("Inner Fault: {0}", null == ex.InnerException.Message ? "No Inner Fault" : ex.InnerException.Message); } catch (System.Exception ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine(ex.Message); // Display the details of the inner exception. if (ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>; if (fe != null) { Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp); Console.WriteLine("Code: {0}", fe.Detail.ErrorCode); Console.WriteLine("Message: {0}", fe.Detail.Message); Console.WriteLine("Plugin Trace: {0}", fe.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == fe.Detail.InnerFault ? "No Inner Fault" : "Has Inner Fault"); } } } // Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException, // SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException. finally { Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } } #endregion Main method } }
Microsoft Dynamics 365
© 2016 Microsoft. All rights reserved. Copyright
Community Additions
ADD
Show: