Microsoft Dynamics CRM SDK CRMServiceClient connection string cache bug
Asked Answered
M

3

6

Caching behavior of the last Dynamics SDK is driving me crazy.

First, if you want to use CrmServiceClient to access different environments you have to use the parameter RequireNewInstance=True; in the connection string. If not, every instance of CrmServiceClient will use the same connection, even if you create and dispose instances to different environments.

Now, even if you use the RequireNewInstance=True; in the connection string I found that cache still occurs in some scenarios.

var client1 = new CrmServiceClient("RequireNewInstance=True;
Url=https://myCompany.crm.dynamics.com;
[email protected]; Password=myPassowrd;
AuthType=Office365");

//Now, client 2 points to a url that doesn’t exists:
var client2 = new CrmServiceClient("RequireNewInstance=True; 
Url=https://xxx.crm.dynamics.com; [email protected]; 
Password=myPassowrd; AuthType=Office365");

The client2 keeps using the first connection string, so you cannot determine if the new connection string is correct.

Any ideas how to test Dynamics Crm connections strings correctly in my asp.net application?

Maximamaximal answered 27/1, 2017 at 14:33 Comment(0)
M
2

I think I found the problem. It seems to only happens on Dynamics 365 online trials, that was the reason we were getting inconsistent results depending on the environment.

Apparently, the url doesn't need to be completely valid to establish a connection to a CRM online trial environment, as long as the credentials are valid and the url structure is kept.

Let's consider the following example:

var client1 = new CrmServiceClient("RequireNewInstance=True; 
Url=https://fake.crm.dynamics.com; 
[email protected]; Password=myPassowrd; 
AuthType=Office365");

In this case I can substitute the "fake" part of the url with whatever I want, but still execute requests correctly using the CrmServiceClient service.

If I try to do this with another environment (e.g. 2015, on premise, not-trial crm online, etc.), the IsReady property of the CrmServiceClient would return false and I would get an error in the LastCrmError property.

Very weird behavior, and difficult to pinpoint. Now that I think I understand the inconsistent behavior I know that finally it will not affect our clients, so I will mark this response as the answer even if I still do not know why we have different behavior between a trial and a normal environment..

Maximamaximal answered 30/1, 2017 at 18:13 Comment(0)
I
4

Late reply, but the behavior you're seeing is because when you're specifying an erroneous URL the discovery service is used to ascertain which instance to connect to. To prevent this specify SkipDiscovery=True in your connection string:

var connectionString2 = @"AuthType=Office365;Url=https://FAKE.crm.dynamics.com;Username=USERNAME;Password=PASSWORD;RequireNewInstance=True;SkipDiscovery=True;";

Edit: SkipDiscovery is true by default starting with 9.0.7, kudos to @mwardm

Interatomic answered 17/10, 2018 at 12:59 Comment(2)
FYI: The default value of SkipDiscovery has changed from false to true across versions 9.2.0.5 and 9.2.0.7 of the XrmTooling DLL.Safelight
Oops - versions should have been 9.0.2.5 and 9.0.2.7. It's been a long day :-(Safelight
M
2

I think I found the problem. It seems to only happens on Dynamics 365 online trials, that was the reason we were getting inconsistent results depending on the environment.

Apparently, the url doesn't need to be completely valid to establish a connection to a CRM online trial environment, as long as the credentials are valid and the url structure is kept.

Let's consider the following example:

var client1 = new CrmServiceClient("RequireNewInstance=True; 
Url=https://fake.crm.dynamics.com; 
[email protected]; Password=myPassowrd; 
AuthType=Office365");

In this case I can substitute the "fake" part of the url with whatever I want, but still execute requests correctly using the CrmServiceClient service.

If I try to do this with another environment (e.g. 2015, on premise, not-trial crm online, etc.), the IsReady property of the CrmServiceClient would return false and I would get an error in the LastCrmError property.

Very weird behavior, and difficult to pinpoint. Now that I think I understand the inconsistent behavior I know that finally it will not affect our clients, so I will mark this response as the answer even if I still do not know why we have different behavior between a trial and a normal environment..

Maximamaximal answered 30/1, 2017 at 18:13 Comment(0)
L
1

I agree choosing to reuse the existing connection if you don't include RequireNewInstance=true seems counter-intuitive, but I can't reproduce what you're seeing. If I try the following from LinqPad crmSvcClient2 will print out errors and then throw a null ref on the Execute call (8.2.0.2 version of the SDK). With this version of the SDK you'll want to always check LastCrmError after connecting to see if the connection failed.

var connectionString = @"AuthType=Office365;Url=https://REAL.crm.dynamics.com;Username=USERNAME;Password=PASSWORD;RequireNewInstance=True;";
var connectionString2 = @"AuthType=Office365;Url=https://FAKE.crm.dynamics.com;Username=USERNAME;Password=PASSWORD;RequireNewInstance=True;";   

using (var crmSvcClient = new CrmServiceClient(connectionString))
{
    "crmSvcClient".Dump();
    crmSvcClient.LastCrmError.Dump();
    ((WhoAmIResponse)crmSvcClient.Execute(new WhoAmIRequest())).OrganizationId.Dump();
    crmSvcClient.ConnectedOrgFriendlyName.Dump();


}
using (var crmSvcClient2 = new CrmServiceClient(connectionString2))
{
    "crmSvcClient2".Dump();
    crmSvcClient2.LastCrmError.Dump();
    ((WhoAmIResponse)crmSvcClient2.Execute(new WhoAmIRequest())).OrganizationId.Dump();
    crmSvcClient2.ConnectedOrgFriendlyName.Dump();
}

enter image description here

Lucic answered 27/1, 2017 at 15:28 Comment(10)
Thanks for answering Matt. Try using the exact same connection string, but only change the url from the real to the fake. That is, keep the user and password used in crmSvcClient. You should get the behavior that I'm experiencingMaximamaximal
@Maximamaximal hmmm... that is what I did. The first connection was correct, while the second has correct user credentials but a fake org name.Lucic
I tried again, in different clients, using x64 and x86 just in case, even following your exact same connection string structure, to be completely sure, and I get the same wrong behavior. I even tried to put some working sample on .net fiddle but I couldn't because a problem with the packages dependencies. So, you have EXACTLY THE SAME connection string, with just a url difference (e.g. xxx.crm.dynamics.com), the first CrmServiceClient connects and the second doesn't ??Maximamaximal
@Maximamaximal correct. Are we using the same version of the SDK?Lucic
Yep, I'm using the SDK 8.2.0.2 also. I think I discovered something, could you tell me your CRM online version? It seems that it works wrong on the last version (8.2.0.779), but works as you suggest in previous versions (e.g. 8.1.0.538). :\Maximamaximal
@Maximamaximal I'm testing against CRM version 8.2.0.779Lucic
@Marcos, you could try taking a look at the SDK code and either compiling a debug version you can step into, or just looking at it and seeing how connection caching is handled. I did this a few weeks ago (when the RequireNewInstance functionality was updated), but I don't remember seeing anything that would cause what you are seeing.Lucic
I didn't know code was avaialbe. Could you point me where to download source code for the SDK?Maximamaximal
@Marcos, the code is not, but you can use tools like "Telerik JustDecompile" to take a look or build a debug-able version.Lucic
Thanks, I'll try. Now, I found that the behavior doesn't have to do with connecting to a correct url and then to an incorrect url later, it's just a matter of the environment to which is connected (in fact I tried 4 environments and I'm getting the wrong behavior only in one). I'll resume tests probably next week and post a solution, if I find one.Maximamaximal

© 2022 - 2024 — McMap. All rights reserved.