CRM 2016 SDK Code – Connection to the Organization Service Fails

By | February 28, 2016

Crm2016logo
We have just upgraded one of our muti-tenant environments to CRM 2016 and while testing customers’ custom code which uses the crm sdk we realized that calls to the web service were not working anymore.

We will give you the background of the problem and the steps you need to take in order to overcome this problem in case anyone else runs into a similar situation.

We have designed a method for connectivity to crm that we have been using since crm 4.0 which we update as new versions of .Net and CRM SDK come out. It’s a fairly simple and straight forward set of code that figures out what type of authentication the specific deployment of crm we want to connect to requires and using a system account makes the connection and returns an instance of the IOrganizationService.


Below is a copy of the method:


public static IOrganizationService GetOrganizationSvc()
{
IOrganizationService crmService = null;
OrganizationServiceProxy orgService = null;
OrganizationService fedService = null;
ClientCredentials clientCredentials = new ClientCredentials();
IServiceConfiguration serviceConfiguration = null;

Uri crmURL = null;
string userId = null;
string password = null;
string domain = null;

/* retrieve service configuration settings */
crmURL = new Uri(RegistryManager.GetRegistryConfiguration(RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.CRMURL));
ServiceUri = crmURL;
userId = RegistryManager.GetRegistryConfiguration(RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.UserId);
password = RegistryManager.GetRegistryConfiguration(RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.Password);
domain = RegistryManager.GetRegistryConfiguration(RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.Domain);

/* we need to know the type of authentication for the specific environment we’re connecting to */
serviceConfiguration = ServiceConfigurationFactory.CreateConfiguration(crmURL);

/* sets credentials based on the authentication type for the environment we’re connection to */
switch (serviceConfiguration.AuthenticationType)
{
case AuthenticationProviderType.ActiveDirectory:
{
clientCredentials.Windows.ClientCredential.UserName = userId;
clientCredentials.Windows.ClientCredential.Password = password;
clientCredentials.Windows.ClientCredential.Domain = domain;

orgService = new OrganizationServiceProxy(crmURL, null, clientCredentials, null);
orgService.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(Assembly.GetExecutingAssembly()));
orgService.EnableProxyTypes();
orgService.Timeout = new TimeSpan(0, 5, 0);
crmService = orgService;

break;
}
case AuthenticationProviderType.Federation:
{
clientCredentials.UserName.UserName = string.Format(“{0}\\{1}”, domain, userId);
clientCredentials.UserName.Password = password;

orgService = new OrganizationServiceProxy(crmURL, null, clientCredentials, null);
orgService.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(Assembly.GetExecutingAssembly()));

orgService.EnableProxyTypes();
orgService.Timeout = new TimeSpan(0, 5, 0);
crmService = orgService;
break;
}
case AuthenticationProviderType.LiveId:
break;
case AuthenticationProviderType.None:
break;
default:
break;
}

return crmService;
}

orgservice

Developer Resources CRM 2015

Up until crm 2016 we just had to pass the organization url when creating the instance of IServiceConfiguration object.

As you well know you can obtain the crm service url in crm itself by going to Settings>Customizations>Developer Resources.

With 2016 this functionality has changed. To create an instance of the IServiceConfiguration we have now to pass the url to the Discovery service and include the crm version in the url.

The url would look like

http://<server name>:5555/XRMServices/2011/Discovery.svc?wsdl&sdkversion=8

The interesting part is that when you go to the Resources in CRM the version part is not given to you as the picture below shows.

So, once we modified our code to use the Discovery url as shown above the remaining code was now able to work without any additional changes.

resource2016

 

Below is the modified code so it gives you an idea of what you need to change.

public static IOrganizationService GetOrganizationSvc()
{
IOrganizationService crmService = null;
OrganizationServiceProxy orgService = null;
ClientCredentials clientCredentials = new ClientCredentials();
IServiceConfiguration serviceConfiguration = null;

Uri crmURL = null;
string userId = null;
string password = null;
string domain = null;
Uri discoveryService = null;

/* retrieve service configuration settings */
crmURL = new Uri( RegistryManager.GetRegistryConfiguration( RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.CRMURL ) );
userId = RegistryManager.GetRegistryConfiguration( RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.UserId );
password = RegistryManager.GetRegistryConfiguration( RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.Password );
domain = RegistryManager.GetRegistryConfiguration( RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.Domain );
discoveryService = new Uri( RegistryManager.GetRegistryConfiguration( RegistryManager.CONFIGURATION_MEMBER_PATH, CustomConfigurationSettings.DiscoveryURL ) );

/* we need to know the type of authentication for the specific environment we’re connecting to */
serviceConfiguration = ServiceConfigurationFactory.CreateConfiguration( discoveryService );
//serviceConfiguration = ServiceConfigurationFactory.CreateManagement( discoveryService );

/* sets credentials based on the authentication type for the environment we’re connection to */
switch( serviceConfiguration.AuthenticationType )
{
case AuthenticationProviderType.ActiveDirectory:
{
clientCredentials.Windows.ClientCredential.UserName = userId;
clientCredentials.Windows.ClientCredential.Password = password;
clientCredentials.Windows.ClientCredential.Domain = domain;

orgService = new OrganizationServiceProxy( crmURL, null, clientCredentials, null );
orgService.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add( new ProxyTypesBehavior( Assembly.GetExecutingAssembly() ) );
orgService.EnableProxyTypes();
orgService.Timeout = new TimeSpan( 0, 5, 0 );
crmService = orgService;
break;
}
case AuthenticationProviderType.Federation:
{
clientCredentials.UserName.UserName = string.Format( “{0}\\{1}”, domain, userId );
clientCredentials.UserName.Password = password;

orgService = new OrganizationServiceProxy( crmURL, null, clientCredentials, null );
orgService.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add( new ProxyTypesBehavior( Assembly.GetExecutingAssembly() ) );

orgService.EnableProxyTypes();
orgService.Timeout = new TimeSpan( 0, 5, 0 );
crmService = orgService;
break;
}
case AuthenticationProviderType.LiveId:
break;
case AuthenticationProviderType.None:
break;
default:
break;
}

return crmService;
}

We hope this tip might save someone else some time trying to figure our this problem.

Drop us a comment or if you have any questions please contact us through our QualTech-Software Solutions or QualTechCloud Integrated Cloud Solutions customer form.

Leave a Reply