即使在创建新实例时,CRM上下文对象也保持连接

本文关键字:上下文 CRM 对象 连接 创建 新实例 实例 | 更新日期: 2023-09-27 18:15:03

我为WCF服务准备了一个系统,在这个系统中,我从客户端获取一些凭证。然后,我尝试使用这些凭证对CRM进行身份验证。如果身份验证失败,我将使用预定义的服务帐户,凭据存储在web.config中。

我发现,无论如何,无论我如何拆除第一个对象,所使用的第一组凭据对任何进一步的请求都是持久的。我甚至实例化新对象,在using语句中包装每个上下文,等等。

我把代码简化成一个简单的"连接,重试"块,这也遇到了同样的问题。代码如下:

try
{
    var connection = new CrmConnection();
    connection.ServiceUri = new Uri("https://my.crm.dynamics.com/");
    connection.ClientCredentials = new ClientCredentials();
    connection.ClientCredentials.UserName.UserName = "removed1";
    connection.ClientCredentials.UserName.Password = "removed1";
    using (var crm = new CrmOrganizationServiceContext(connection))
    {
        var req = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest();
        var resp = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)crm.Execute(req);
    }
}
catch (Exception ex) { }
try
{
    var connection = new CrmConnection();
    connection.ServiceUri = new Uri("https://my.crm.dynamics.com/");
    connection.ClientCredentials = new ClientCredentials();
    connection.ClientCredentials.UserName.UserName = "removed2";
    connection.ClientCredentials.UserName.Password = "removed2";
    using (var crm = new CrmOrganizationServiceContext(connection))
    {
        var req = new Microsoft.Crm.Sdk.Messages.WhoAmIRequest();
        var resp = (Microsoft.Crm.Sdk.Messages.WhoAmIResponse)crm.Execute(req);
    }
}
catch (Exception ex) { }

假设removed1错误,removed2正确。第二次调用将立即失败,并出现令牌异常,表示凭据无效。如果removed1正确,而removed2不正确,则第一个将进行身份验证并获得WhoAmIRequest fine。然后,removed2应该失败,但它没有,因为它似乎仍然使用旧凭据保持连接。无效凭据仍然允许服务发出请求。不是很好!

奇怪的是,验证的代码是在一个单独的项目中。我已经将这个项目包含在一个简单的控制台应用程序中,一切正常。我只能假设这与WCF服务及其保持连接的方式有关。我尝试过手动处理,调用垃圾收集,设置为null等。我也尝试过使用web配置连接字符串的名称调用(硬编码2测试),尝试手动创建具有唯一名称的连接字符串设置,使用CrmConnection.Parse()等。

我甚至复制粘贴了我直接使用到控制台应用程序的代码,它工作得很好。因此,我确信这是与WCF服务的行为有关,而不是代码本身。我设置类的行为为

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]

但是运气不好。如果它是重要的,这段代码运行在一个实现IDispatchMessageInspector的消息检查器类中。

我如何确保我可以得到一个新的会话?谢谢。

即使在创建新实例时,CRM上下文对象也保持连接

您正在使用CrmConnection类的默认构造函数。这样做时,您的连接将按名称进行缓存。这个名称应该是ConnectionStringSettings的名称,但是使用这个构造函数,该属性永远不会被设置,并保持其默认值,因此总是返回创建的第一个连接对象。

只需使用另一个构造函数的重载,例如使用连接字符串或接受服务url,凭据等。

CrmConnection类旨在提供一种在配置文件中创建连接字符串的简单方法,类似于数据库连接字符串。它有它的问题,并已从Dynamics CRM 2016 SDK中删除。