如何防止每次建立 CrmServiceClient 连接时 Dynamics 365 都进行身份验证

时间:2021-03-16 17:15:47

标签: c# dynamics-crm dynamics-crm-online dynamics-365

我们正在从 Dynamics On-Prem 迁移到 Dynamics 365 online。因此,我们还必须更改连接到 Dynamics 的 Web 应用程序。

Web 应用程序仍在运行,但性能很差。我们开始做一些跟踪,看看为什么。在此跟踪中,我们看到该应用程序正在为单个请求执行对 Dynamics online 的不同调用。这样做的原因是我们确实在检索不同的数据集。但是我们惊讶地看到身份验证也进行了多次。这种身份验证减慢了动态响应。我们期望仅对第一个请求进行身份验证。

我用来建立连接的代码位于一个抽象类中,该类由不同的其他类实例化。此类使用以下属性从命名空间 Microsoft.Xrm.Tooling.Connector 返回 CrmServiceClient:

     protected CrmServiceClient CustomCrmServiceProxy
    {
        get
        {
            CrmServiceClient client = new CrmServiceClient(CrmConnection.Connectionstring);
            client.CallerId = GetCallerId();

            return client;
        }
    }

连接字符串是 AuthType=ClientSecret;url={0};ClientId={1};ClientSecret={2};替换值。

在使用抽象类的类中,我们像这样调用属性

var data = this.CustomCrmServiceProxy.RetrieveMultiple("fetch xml");

重要是我们将调用者id传递给CrmServiceClient,当访问者切换到另一种语言的页面时,这个调用者可能会有所不同。

有没有办法防止多重身份验证? 实现单例模式是一种选择吗?但是在这种情况下,不同的 callerid 怎么办? CrmServiceClient 可能有一个很好的例子吗?

3 个答案:

答案 0 :(得分:0)

你能试试这样的吗?

这将创建连接的单个实例(带有调用者 ID),然后持续引用该实例。

CrmServiceClient _client = null;

protected CrmServiceClient CustomCrmServiceProxy
{
  get
  {
    if (_client == null)
    {
        _client = new CrmServiceClient(CrmConnection.Connectionstring);
        _client.CallerId = GetCallerId();
    }
    return _client;
}

答案 1 :(得分:0)

CrmServiceClient 提供了许多构造函数,提供了重用连接实例的机会。

例如以下构造函数重载具有参数 useUniqueInstance。当应使用缓存实例时,将 false 值传递给它。

public CrmServiceClient(string userId, SecureString password, string domain, string homeRealm, string hostName, string port, string orgName, bool useUniqueInstance = false, bool useSsl = false, OrganizationDetail orgDetail = null)

然而,在大多数情况下,一个 Web 应用程序将被多个客户端使用,通常是并发的,并且在这些情况下,单例连接对象不能很好地扩展。在这些情况下,您可以引入连接池

连接池类将负责维护 CrmServiceClient 实例的集合。工厂模式可用于从池对象中声明实例。处置后,工厂实例会将所有声明的实例返回到池中。

您的工厂类可以实现现有的 IOrganizationServiceFactory。此界面的设计考虑到了模拟要求。

<块引用>

注意:不要让当前使用 CrmServiceClient 连接的类负责创建这些实例。而是将 IOrganizationServiceFactoryIOrganizationService 对象注入到这些类的构造函数中。

答案 2 :(得分:0)

我见过程序执行 get 访问器的次数比我想象的要多的情况。

与其将其作为属性,不如尝试将其变成一种方法。

protected CrmServiceClient GetService()
{
    var client = new CrmServiceClient(CrmConnection.Connectionstring);
    client.CallerId = GetCallerId();
    return client;
}

然后,延迟实例化的一种选择是:

private CrmServiceClient _svc;
private CrmServiceClient svc => _svc ?? (_svc = GetService());