CrmServiceClient is always returning null Organization Service

24k Views Asked by At

I've got the following code to connect to Dynamics 365 Online organization. It throws a null reference exception on orgService.Execute(new WhoAmIRequest()); and error log is below the code. I've tried this on two machines with different console apps. I've tried both the 8.2 and 8.0 SDK DLLs. If I rewrite this using CrmConnection with the 7.x SDK DLLs everything works fine. I can browse to the organization using the same credentials (cut & pasted to be sure there is not a typo.)

The connection string format is taken from the example at https://msdn.microsoft.com/en-us/library/mt608573.aspx:

Named account using Office 365

<add name="MyCRMServer" -connectionString="AuthType=Office365;[email protected]; Password=passcode;Url=https://contoso.crm.dynamics.com"/>

The basic code.

var connectionString = @"Url=https://ORGNAME.crm.dynamics.com; [email protected]; Password=43JF##$j#@Ha; Authype=Office365;";

var client = new CrmServiceClient(connectionString);            

var orgService = (IOrganizationService)client.OrganizationWebProxyClient ?? client.OrganizationServiceProxy;

orgService.Execute(new WhoAmIRequest());

Error log output:

Microsoft.Xrm.Tooling.Connector.CrmServiceClient Information: 8 : Discovery URI is = https://ORGNAME.crm.dynamics.com:443/XRMServices/2011/Discovery.svc
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Information: 8 : DiscoverOrganizations - Initializing Discovery Server Object with https://ORGNAME.crm.dynamics.com/XRMServices/2011/Discovery.svc
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Verbose: 16 : DiscoverOrganizations - attempting to connect to CRM server @ https://ORGNAME.crm.dynamics.com/XRMServices/2011/Discovery.svc
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : Source  : System.ServiceModel
Method  : Retrieve
Date    : 2/13/2017
Time    : 5:42:37 PM
Error   : Metadata contains a reference that cannot be resolved: 'https://ORGNAME.crm.dynamics.com/_common/error/errorhandler.aspx?BackUri=&ErrorCode=&Parm0=%0d%0a%0d%0aتفاصيل الخطأ: The service '%2fXRMServices%2f2011%2fDiscovery.svc' cannot be activated due to an exception during compilation.  The exception message is: Could not load file or assembly 'Microsoft.Crm.Site.Services%2c Version%3d8.0.0.0%2c Culture%3dneutral%2c PublicKeyToken%3d31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified..&RequestUri=%2fXRMServices%2f2011%2fDiscovery.svc%3fwsdl%26sdkversion%3d8.1&user_lcid=1025'.
Stack Trace : at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
   at System.ServiceModel.Description.MetadataExchangeClient.ResolveNext(ResolveCallState resolveCallState)
   at System.ServiceModel.Description.MetadataExchangeClient.GetMetadata(MetadataRetriever retriever)
   at System.ServiceModel.Description.MetadataExchangeClient.GetMetadata(Uri address, MetadataExchangeClientMode mode)
   at Microsoft.Xrm.Sdk.Client.ServiceMetadataUtility.RetrieveServiceEndpointMetadata(Type contractType, Uri serviceUri, Boolean checkForSecondary)
   at Microsoft.Xrm.Sdk.Client.ServiceConfiguration`1..ctor(Uri serviceUri, Boolean checkForSecondary)
   at Microsoft.Xrm.Sdk.Client.ServiceConfigurationFactory.CreateManagement[TService](Uri serviceUri, Boolean enableProxyTypes, Assembly assembly)
   at Microsoft.Xrm.Sdk.Client.ServiceConfigurationFactory.CreateManagement[TService](Uri serviceUri)
   at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.CreateAndAuthenticateProxy[T](IServiceManagement`1 servicecfg, Uri ServiceUri, Uri homeRealm, ClientCredentials userCredentials, ClientCredentials deviceCredentials, String LogString)
   at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.DiscoverOrganizations(Uri discoveryServiceUri, Uri homeRealmUri, ClientCredentials clientCredentials, ClientCredentials deviceCredentials)
   at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.DiscoverOrganizations(Uri discoveryServiceUri, Uri homeRealmUri, NetworkCredential networkCredential)
   at Microsoft.Xrm.Tooling.Connector.CrmWebSvc.InitCRM2011Service()
======================================================================================================================
Inner Exception Level 1 : 
Source  : System.Runtime.Serialization
Method  : ThrowXmlException
Date    : 2/13/2017
Time    : 5:42:37 PM
Error   : CData elements not valid at top level of an XML document. Line 1, position 3.
Stack Trace : at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, XmlException exception)
   at System.Xml.XmlUTF8TextReader.Read()
   at System.ServiceModel.Description.MetadataExchangeClient.MetadataLocationRetriever.GetXmlReader(HttpWebResponse response, Int64 maxMessageSize, XmlDictionaryReaderQuotas readerQuotas)
   at System.ServiceModel.Description.MetadataExchangeClient.MetadataLocationRetriever.DownloadMetadata(TimeoutHelper timeoutHelper)
   at System.ServiceModel.Description.MetadataExchangeClient.MetadataRetriever.Retrieve(TimeoutHelper timeoutHelper)
======================================================================================================================

Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : Unable to Login to Dynamics CRM
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : OrganizationWebProxyClient is null
Microsoft.Xrm.Tooling.Connector.CrmServiceClient Error: 2 : OrganizationServiceProxy is null
4

There are 4 best solutions below

3
On BEST ANSWER

Have you tried passing the parameters directly to the CrmServiceClient instead of the connection string?

I can connect successfully to Dynamics365 by using this following method

public CrmServiceClient(string crmUserId, SecureString crmPassword, string crmRegion, string orgName, bool useUniqueInstance = false, bool useSsl = false, OrganizationDetail orgDetail = null, bool isOffice365 = false);

And here's how I applied

var pwd = ConvertToSecureString("userpassword");
CrmServiceClient client = new CrmServiceClient("[email protected]", pwd, "NorthAmerica", "orgname", isOffice365: true);

And here's the method to convert the password to secure string

private System.Security.SecureString ConvertToSecureString(string password)
{
    if (password == null)
        throw new ArgumentNullException("missing pwd");

    var securePassword = new System.Security.SecureString();
    foreach (char c in password)
        securePassword.AppendChar(c);

    securePassword.MakeReadOnly();
    return securePassword;
 }
1
On

As per latest Microsoft recommendation we are not supposed to use “AuthType=Office365”.

https://learn.microsoft.com/en-us/powerapps/developer/common-data-service/authenticate-office365-deprecation

We can use Application Account (Client ID & Secret Key) to generate Token & access Dynamics CRM Organization Service. But if you want to use User ID & PWD then Use (AuthType = OAuth)

Sample Code :

string connectionString = "AuthType = OAuth; Url = 'https://*****.crm.dynamics.com'; Username = '*******'; Password = '*******'; AppId = 51f81489-12ee-4a9e-aaae-a2591f45987d; RedirectUri = app://58145B91-0C36-4500-8554-080854F2AC97;LoginPrompt=Never";

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

CrmServiceClient crmServiceClient = new CrmServiceClient(connectionString);
WhoAmIResponse whoAmIResponse = crmServiceClient.Execute(new WhoAmIRequest()) as WhoAmIResponse;

Note : While trying to use this from Azure Function I got below errors :

  1. ERROR REQUESTING Token FROM THE Authentication contextNeed a non-empty authority
  2. One or more errors occurred. => An error occurred while sending the request. => The underlying connection was closed: An unexpected error occurred on a send. => Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. => An existing connection was forcibly closed by the remote hostERROR REQUESTING Token FROM THE Authentication context
  3. CurrentAccessToken = 'crmServiceClient.CurrentAccessToken' threw an exception of type 'System.NullReferenceException'

Easily you can resolve these using just one additional line : ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Ref URL : https://support.microsoft.com/en-us/help/4051700
Microsoft Dynamics 365 Customer Engagement (online) to require TLS 1.2 for connectivity

Pls let me know if you are facing any other issues.

Thanks, Sumit

0
On

I was struggling on fixing this issue because everything I did except installing higher version (On MS docs also They didn't mentioned this) of Microsoft.CrmSdk.XrmTooling.CoreAssembly since lower version of this dll doesn't support ClientSecret authentiation.

0
On

I was getting error

Unable to login to Dynamics CRM, Error was :                    
Data[0] = "The provided uri did not return any Service Endpoints!   

I received this error when attempting to connect to Dynamics using a connection string with AuthType=ClientSecret. Previously I was connecting successfully using username and password with a connection string of the form

"Url={dynamicsConnectionString};Username={username};Password={password};AuthType=Office365;"

The connection string was changed to have the form

"AuthType=ClientSecret;RequireNewInstance=false;Url={CrmDynamicsPrivatePrimaryConnection};ClientId={CrmDynamicsPrivateClientId};ClientSecret={CrmDynamicsPrivateClientSecret};LoginPrompt=Never;"

The error occurred because I was using an outdated version of Microsoft.CrmSdk.XrmTooling.CoreAssembly. I was using version 9.0.2.27, and according to a web report, version 9.1.0.13 is needed for connecting with ClientSecret. I updated to version 9.1.0.68 using NuGet, and the Dynamics connection worked.