Saturday, 15 April 2017

How to connect to Dynamics CRM 2016 Online and On Premise using a C# console application

With the release of the CRM 2016 SDK, came a much needed yet underrated update – Xrm.Tooling.Connector.
The team at Microsoft has simplified connections to CRM to the point of being a developer’s dream, no need for Http bindings, Service References, or countless debugging attempts to get a C# Console application or a ASP.NET Portal to connect to Dynamics CRM.
How to use it –
1 – The app.config file from the SDK example contains a sample of each connection type, make sure you have the correct connectionstring added to your app.config.
    <!-- Online using Office 365 -->
    <!-- <add name="Server=CRM Online, organization=contoso, user=someone" connectionString="Url=https://contoso.crm.dynamics.com; Username=someone@contoso.onmicrosoft.com; Password=password; authtype=Office365"/> -->
    
    <!-- On-premises with provided user credentials -->
    <!-- <add name="Server=myserver, organization=AdventureWorksCycle, user=administrator" connectionString="Url=http://myserver/AdventureWorksCycle; Domain=mydomain; Username=administrator; Password=password; authtype=AD"/> -->

    <!-- On-premises using Windows integrated security -->
    <!-- <add name="Server=myserver, organization=AdventureWorksCycle" connectionString="Url=http://myserver/AdventureWorksCycle; authtype=AD"/> -->

    <!-- On-Premises (IFD) with claims -->
   
 <!--<add name="Server=litware.com, organization=contoso, user=someone@litware.com" connectionString="Url=https://contoso.litware.com; Username=someone@litware.com; Password=password; authtype=IFD"/>-->
**These connection strings are read as an array for the ConfigurationManager
2 – In your Console application,
string connStr = ConfigurationManager.ConnectionStrings[0].ConnectionString;
3. To use this connection string
              // Establish a connection to the organization web service.
                Println("Connecting to Online using O365...");

                // Connect to the CRM web service using a connection string.
                CrmServiceClient conn = new Microsoft.Xrm.Tooling.Connector.CrmServiceClient(connStr);

                // Cast the proxy client to the IOrganizationService interface.
                //_orgService = (IOrganizationService)conn.OrganizationWebProxyClient != null ? (IOrganizationService)conn.OrganizationWebProxyClient : (IOrganizationService)conn.OrganizationServiceProxy;
                IOrganizationService service = (IOrganizationService)conn.OrganizationServiceProxy;
                Print("connected");
                
                // Obtain information about the logged on user from the web service.
                Guid userid = ((WhoAmIResponse)service.Execute(new WhoAmIRequest())).UserId;
                Entity systemUser = (Entity)service.Retrieve("systemuser", userid,
                    new ColumnSet(new string[] { "firstname", "lastname" }));
                Println("Logged on user is " + systemUser.Attributes["firstname"].ToString() + " " + systemUser.Attributes["lastname"].ToString() + ".");

                // Retrieve the version of Microsoft Dynamics CRM.
                RetrieveVersionRequest versionRequest = new RetrieveVersionRequest();
                RetrieveVersionResponse versionResponse =
                    (RetrieveVersionResponse)service.Execute(versionRequest);
                Println("Microsoft Dynamics CRM version " + versionResponse.Version + ".");
And Finally, don’t forget to add the assembly reference –
using Microsoft.Xrm.Tooling.Connector;

Tuesday, 11 April 2017

CRM 2015 – Understanding impersonation in plugins and knowing when to use it

What is impersonation
When you create a plugin in CRM (step by step blog post here) you write an execute method which gets passed in
IServiceProvider serviceProvider
This has lots of variables and objects such as
  • IPluginExecutionContext
  • ITracingService
  • IOrganizationServiceFactory
You use the IOrganisationServiceFactory to create a IOrganizationService.  The IOrganizationService is the CRM SDK, it provides you access to CRM programmatically .  CRM developers use the IOrganizationService (which I will often call CRMService) to
  • CRUD operation – Create, Retrieve, Update, Delete records in CRM
  • Assign records
  • Change status
  • pretty much everything you can do in CRM
Here is the code to create the IOrganizationService, taken from the Plugin class of the CRM Dev toolkit
// Obtain the Organization Service factory service from the service provider
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);
When creating your plugin you will notice there is a Run in Context setting, most of the time you will choose to Run In Context of Calling User.
Create Account Plugin 1

99 percent of the time Calling User is the right choice

It’s usually the right choice to use the Calling User because any updates, retrieves or any interaction with CRM data will be done using the calling users identity and privileges.
If you visualize a plugin as an automated extension of the CRM form, it’s likely you want the the code in the plugin to run with security privileges as the calling user.  It allows you not to abdicate the need to apply security to the plugin code and pass this off the users security profile and CRM.
The PluginExecutionContext (which I explain in this blog post) has the field called UserId.  We pass this to the IOrganizationFactory to create an IOrganizationService with the user who initiated the plugin.  The good news is the CRM Dev toolkit does all this for us, so we can just chill out and get the IOrganizationService and work on the business logic.
// Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);
Running the CrmService (IOrganizationService) as the calling user means you are interacting with the data in CRM as the calling user, which means
  • The IOrganizationService can only retrieve data the user can retrieve
  • When IOrganizationService updates, creates records they are stamped with the calling user
  • The plugin cannot do anything the calling user cannot do
The calling user setting adheres to the security role assigned to the calling user, integrity of your precious CRM data is kept intact.

Why impersonate System User

If running plugins as the calling user is so good, why impersonate other users or system admins.
  • What if you need to retrieve records the user doesn’t have access to?
  • What if you need to update records the user doesn’t have access to?
You might be thinking, “if the user doesn’t have access to those records, maybe the plugin shouldn’t be updating them”.
It’s a point to consider point but sometimes you want to create records or update records based on the action/status of an entity to move the code to the next stage/state.
Sometimes you want to assign a record to another user when a record goes to a certain state but you wouldn’t want users to be able to assign records.

How is running in context different from impersonation

The running in context setting on a plugin mentioned early runs the whole plugin in that context.
Impersonation allows you to run a small section of code in another context.
Impersonation gives the CRM developer more flexibility to target a particular action in a plugin they would like to run with elevation permissions.  The rest of the plugin actions can be run as

Dangers of impersonation

The downsides of impersonation is it potentially gives users running the plugin\custom workflow enhanced security privileges which could lead who we don’t want updating\deleting records doing exactly that.
When using impersonation in plugins consider accountability and audit trails.  When a plugin impersonates a system user or a different user, the impersonated user will update those records.  It can be confusing/worrying for users when looking at audit records to see System Admin updating records.
I’m sure there have been thousands of support calls querying why System Admin has been updating records.

Impersonation Code

Easy way to impersonate System User is to pass null to the CreateOrganizationService and it will run as System user, find out more in this CRM SDK article
// Use the factory to generate the Organization Service.
OrganizationServiceImpersonated = factory.CreateOrganizationService(null);
You can pass in a different user Id to the CreateOrganizationService to create an IOrganizationService
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.InitiatingUserId);
The sample code in the CRM SDK article impersonates using OrganizationServiceContext.  I personally have used this
// Retrieve the system user ID of the user to impersonate.
OrganizationServiceContext orgContext = new OrganizationServiceContext(_serviceProxy);
_userId = (from user in orgContext.CreateQuery&lt;SystemUser&gt;()
where user.FullName == "Kevin Cook"
select user.SystemUserId.Value).FirstOrDefault();
// To impersonate another user, set the OrganizationServiceProxy.CallerId
// property to the ID of the other user.
_serviceProxy.CallerId = _userId;

Impersonating during plugin-in registration

You can impersonate a user during plugin-registration but I’m not entirely sure why you would do this, so I’m not going to talk about.  Most CRM developer will impersonate someone inside a plugin.
If you want to learn more read
and the articles in the futher reading section

Why, What, Where, When

What is Impersonation

Impersonation in plugins/custom workflows is creating an IOrganisationService as a different user

Why use Impersonation

Use impersonation when you need to update/retrieve/delete/Create records users security roles doesn’t let them.

Where

If you don’t want to increase users security roles but still want the plugin to do a particularly action.  e.g. delete a record


Wednesday, 5 April 2017

Microsoft Dynamics CRM 2011 Relationship Field Mapping

Recently, a Microsoft Dynamics CRM customer noticed a difference in functionality when creating a new Contract record and creating a new Contract record from a Contact. Today we’ll explore how this relates to CRM 2011 relationship mapping.
As you can see below when creating a new Contract record from the Contract entity and selecting the Customer the Bill To Customer field gets automatically filled.
CRM 2011 relationship mapping
It’s a great out of the box feature to have since the Bill To Customer will most likely be the same as the Customer.  But when you create a new Contract from the Contact record the same functionality doesn’t occur. Take a look:
CRM 2011 relationship mpaping - add a new contract
This is because the OnChange event of the Customer field did not occur.  Instead of adding JavaScript to the Contract form an easier way to keep the same functionality consistent is to use CRM 2011 Relationship Mapping.
To do this you customize the Contact’s entity one to many relationship to the Contract entity.
Microsoft Dynamics CRM Relationship Mappings
Then add a new Mapping that will map the Contact to the Bill To Customer field.
Relationship Mappings with Dynamics CRM
Now when a new Contract record is created from a Contact the same functionality will occur.

How to Use Dependent Lookups for Dynamics CRM 2013/2015/2016

Let’s walk through the necessary steps using two fields to classify your Accounts as an example. We’ll use Class and Sub-Class as the fields. For this example, we’ve created a new entity for each of these fields.
The Sub-Class entity contains the name of the Sub-Class as well as a lookup to the “parent” Class record. This relationship will allow us to filter the list of available Sub-Classes based on the selected Class.
The Class entity has only a single field to store the name of the Class. We’ve added a sub-grid to display only the list of Sub-Classes that are valid for this Class.
For the example below of Retail, once we add these fields to the Account form and modify the properties of the Sub-Class field, the user will only be able to choose one of the Available Sub-Classes listed, when Retail is selected as the Class on the Account form.

Now that we have the entities and some sample data in place, we’ll need to create these new fields on the Account entity and add them to the Account form.
This is how the new lookups look on the CRM form:
Next, we’ll configure the Sub-Class field properties so that only the Available Sub-Classes are options.

Note: Be sure to publish your customizations once you are finished.
You should now see the desired behavior on the Account record. If you populate a value for Class, you’ll notice how only the Available Sub-Classes can be be selected as an option.
This is technically all that needs to be done, however, you should also put a Business Rule in place to prevent a user from selecting a Sub-Class unless the Class field is populated.
In the Account entity, navigate to Customize the System, select Business Rules, and then click New.

The Business Rule below will meet this need.
In the red box below, we are saying that if the Class is blank, we lock the Sub-Class field. This will make it Read Only.
In addition, we need to clear the Sub-Class field. We do this to ensure that a user cannot change the value of the Class and leave an invalid Sub-Class populated.
In the blue box, we are saying that if Class is populated, we unlock the field so the user is able to populate it.
That’s all for the blog today! Want to learn more about Dynamics CRM 2016? Register for our CRM 2016 Boot Camp in Minneapolis, MN.