Microsoft Dynamics CRM SDK CRMServiceClient 连接字符串缓存错误
Microsoft Dynamics CRM SDK CRMServiceClient connection string cache bug
最后一个 Dynamics SDK 的缓存行为让我抓狂。
首先,如果您想使用 CrmServiceClient 访问不同的环境,您必须在连接字符串中使用参数 RequireNewInstance=True;
。否则,CrmServiceClient 的每个实例都将使用相同的连接,即使您创建实例并将实例部署到不同的环境也是如此。
现在,即使你在连接字符串中使用 RequireNewInstance=True;
我发现在某些情况下仍然会出现缓存。
var client1 = new CrmServiceClient("RequireNewInstance=True;
Url=https://myCompany.crm.dynamics.com;
Username=myUser@myCompany.onmicrosoft.com; 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; Username=myUser@myCompany.onmicrosoft.com;
Password=myPassowrd; AuthType=Office365");
client2一直使用第一个连接串,无法判断新的连接串是否正确
关于如何在我的 asp.net 应用程序中正确测试 Dynamics Crm 连接字符串的任何想法?
如果您不包含 RequireNewInstance=true
,我同意选择重用现有连接 counter-intuitive,但我无法重现您所看到的内容。如果我从 LinqPad crmSvcClient2
尝试以下操作,将打印出错误,然后在 Execute 调用(SDK 的 8.2.0.2 版本)上抛出一个空引用。使用此版本的 SDK,您需要在连接后始终检查 LastCrmError
以查看连接是否失败。
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();
}
我想我找到了问题所在。它似乎只发生在 Dynamics 365 在线试用版中,这就是我们根据环境获得不一致结果的原因。
显然,url 无需完全有效即可建立与 CRM 在线试用环境的连接,只要凭据有效且 url 结构保持不变即可。
让我们考虑以下示例:
var client1 = new CrmServiceClient("RequireNewInstance=True;
Url=https://fake.crm.dynamics.com;
Username=myUser@myCompany.onmicrosoft.com; Password=myPassowrd;
AuthType=Office365");
在这种情况下,我可以用我想要的任何内容替换 url 的 "fake" 部分,但仍然使用 CrmServiceClient 服务正确执行请求。
如果我尝试在其他环境中执行此操作(例如 2015 年,内部部署,not-trial crm 在线等),CrmServiceClient 的 IsReady 属性 将 return false我会在 LastCrmError 属性.
中收到错误
非常奇怪的行为,很难查明。
现在我想我理解了不一致的行为,我知道它最终不会影响我们的客户,所以我会把这个回复标记为答案,即使我仍然不知道为什么我们在试用和正常环境之间会有不同的行为。
回复晚了,但您看到的行为是因为当您指定错误时 URL 发现服务用于确定要连接到哪个实例。
要防止这种情况,请在您的连接字符串中指定 SkipDiscovery=True:
var connectionString2 = @"AuthType=Office365;Url=https://FAKE.crm.dynamics.com;Username=USERNAME;Password=PASSWORD;RequireNewInstance=True;SkipDiscovery=True;";
编辑:从 9.0.7 开始,SkipDiscovery 默认为真,感谢@mwardm
最后一个 Dynamics SDK 的缓存行为让我抓狂。
首先,如果您想使用 CrmServiceClient 访问不同的环境,您必须在连接字符串中使用参数 RequireNewInstance=True;
。否则,CrmServiceClient 的每个实例都将使用相同的连接,即使您创建实例并将实例部署到不同的环境也是如此。
现在,即使你在连接字符串中使用 RequireNewInstance=True;
我发现在某些情况下仍然会出现缓存。
var client1 = new CrmServiceClient("RequireNewInstance=True;
Url=https://myCompany.crm.dynamics.com;
Username=myUser@myCompany.onmicrosoft.com; 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; Username=myUser@myCompany.onmicrosoft.com;
Password=myPassowrd; AuthType=Office365");
client2一直使用第一个连接串,无法判断新的连接串是否正确
关于如何在我的 asp.net 应用程序中正确测试 Dynamics Crm 连接字符串的任何想法?
如果您不包含 RequireNewInstance=true
,我同意选择重用现有连接 counter-intuitive,但我无法重现您所看到的内容。如果我从 LinqPad crmSvcClient2
尝试以下操作,将打印出错误,然后在 Execute 调用(SDK 的 8.2.0.2 版本)上抛出一个空引用。使用此版本的 SDK,您需要在连接后始终检查 LastCrmError
以查看连接是否失败。
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();
}
我想我找到了问题所在。它似乎只发生在 Dynamics 365 在线试用版中,这就是我们根据环境获得不一致结果的原因。
显然,url 无需完全有效即可建立与 CRM 在线试用环境的连接,只要凭据有效且 url 结构保持不变即可。
让我们考虑以下示例:
var client1 = new CrmServiceClient("RequireNewInstance=True;
Url=https://fake.crm.dynamics.com;
Username=myUser@myCompany.onmicrosoft.com; Password=myPassowrd;
AuthType=Office365");
在这种情况下,我可以用我想要的任何内容替换 url 的 "fake" 部分,但仍然使用 CrmServiceClient 服务正确执行请求。
如果我尝试在其他环境中执行此操作(例如 2015 年,内部部署,not-trial crm 在线等),CrmServiceClient 的 IsReady 属性 将 return false我会在 LastCrmError 属性.
中收到错误非常奇怪的行为,很难查明。 现在我想我理解了不一致的行为,我知道它最终不会影响我们的客户,所以我会把这个回复标记为答案,即使我仍然不知道为什么我们在试用和正常环境之间会有不同的行为。
回复晚了,但您看到的行为是因为当您指定错误时 URL 发现服务用于确定要连接到哪个实例。 要防止这种情况,请在您的连接字符串中指定 SkipDiscovery=True:
var connectionString2 = @"AuthType=Office365;Url=https://FAKE.crm.dynamics.com;Username=USERNAME;Password=PASSWORD;RequireNewInstance=True;SkipDiscovery=True;";
编辑:从 9.0.7 开始,SkipDiscovery 默认为真,感谢@mwardm