Développement

Création d'applications console pour l'automatisation Dynamics 365

18 novembre 2024
Sabhat Qureshi
10 min de lecture

Pourquoi les applications console pour Dynamics 365 ?

Les applications console sont des outils puissants pour automatiser les tâches administratives, effectuer des opérations de données en masse et exécuter des jobs planifiés contre les environnements Dynamics 365. Contrairement aux plugins qui s'exécutent dans le pipeline d'exécution de la plateforme, les apps console s'exécutent en externe et peuvent effectuer des opérations qui seraient impraticables ou impossibles dans le contexte d'exécution normal. Pour en savoir plus, consultez la documentation de la Dataverse web API et du Organization Service.

Cas d'usage courants

  • Migration de données : Import/export en masse d'enregistrements entre systèmes
  • Maintenance planifiée : Nettoyage d'anciens enregistrements, recalcul de rollups
  • Exports de Reporting : Générer des exports CSV/Excel sur planification
  • Sync d'intégration : Synchroniser les données avec des systèmes externes
  • Gestion d'environnement : Automatiser le déploiement de solutions et la configuration
  • Automatisation de tests : Créer des données de test, exécuter des tests d'intégration

Configuration de votre projet

Création du projet

Créez une nouvelle Application Console .NET Framework 4.6.2 dans Visual Studio. Cette version du framework correspond aux exigences du SDK Dynamics 365.

// Visual Studio → New Project → Console App (.NET Framework)

// Target Framework: .NET Framework 4.6.2

// Project Name: D365AutomationConsole

Packages NuGet requis

Installez les packages NuGet suivants pour vous connecter à Dynamics 365 :

Install-Package Microsoft.CrmSdk.CoreAssemblies

Install-Package Microsoft.CrmSdk.XrmTooling.CoreAssembly

Install-Package Microsoft.CrmSdk.Deployment

Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

Méthodes d'authentification

Authentification par chaîne de connexion

L'approche la plus simple utilise une chaîne de connexion avec le CrmServiceClient.

using Microsoft.Xrm.Tooling.Connector;

var connectionString = @"
    AuthType=OAuth;
    Url=https://yourorg.crm.dynamics.com;
    AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;
    RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97;
    LoginPrompt=Auto";

var client = new CrmServiceClient(connectionString);

if (client.IsReady)
{
    Console.WriteLine("Connected to: " + client.ConnectedOrgFriendlyName);
    IOrganizationService service = client.OrganizationServiceProxy;
    // Use service for operations
}
else
{
    Console.WriteLine("Connection failed: " + client.LastCrmError);
}

N'indiquez pas de nom d'utilisateur ni de mot de passe dans les chaînes de connexion

Cet exemple se connecte de manière interactive (LoginPrompt=Auto) et ne stocke jamais de mot de passe. La connexion par nom d'utilisateur et mot de passe (ROPC) est bloquée par l'authentification multifacteur et l'accès conditionnel, et laisse des identifiants en clair : ne l'utilisez pas. Pour les traitements sans surveillance, utilisez l'approche par secret client ou par certificat ci-dessous et conservez le secret dans Azure Key Vault.

Client ID et secret (Recommandé pour l'Automatisation)

Pour les scénarios d'automatisation sans surveillance, utilisez un App Registration Microsoft Entra ID avec les identifiants client.

var connectionString = @"
    AuthType=ClientSecret;
    Url=https://yourorg.crm.dynamics.com;
    ClientId=your-app-registration-client-id;
    ClientSecret=your-client-secret";

var client = new CrmServiceClient(connectionString);

Important : Enregistrez un Application User dans Dynamics 365 avec les rôles de sécurité appropriés pour l'app registration.

Authentification basée sur certificat

Pour la plus haute sécurité dans les scénarios de production, utilisez l'authentification par certificat.

var connectionString = @"
    AuthType=Certificate;
    Url=https://yourorg.crm.dynamics.com;
    ClientId=your-app-registration-client-id;
    Thumbprint=your-certificate-thumbprint;
    StoreName=My;
    StoreLocation=CurrentUser";

var client = new CrmServiceClient(connectionString);

Opérations courantes

Opérations CRUD

Effectuez les opérations create, retrieve, update, delete en utilisant l'Organization service.

// Create
var account = new Entity("account");
account["name"] = "Contoso Ltd";
account["telephone1"] = "+1-555-0123";
Guid accountId = service.Create(account);
Console.WriteLine($"Created account: {accountId}");

// Retrieve
var retrieved = service.Retrieve("account", accountId,
    new ColumnSet("name", "telephone1", "accountnumber"));
Console.WriteLine($"Retrieved: {retrieved["name"]}");

// Update
var updateAccount = new Entity("account", accountId);
updateAccount["accountnumber"] = "ACC-001";
service.Update(updateAccount);
Console.WriteLine("Account updated");

// Delete
service.Delete("account", accountId);
Console.WriteLine("Account deleted");

Requêtage de données

Utilisez QueryExpression ou FetchXML pour récupérer des données de Dynamics 365.

var query = new QueryExpression("contact")
{
    ColumnSet = new ColumnSet("fullname", "emailaddress1", "parentcustomerid"),
    Criteria = new FilterExpression
    {
        Conditions =
        {
            new ConditionExpression("statecode", ConditionOperator.Equal, 0),
            new ConditionExpression("emailaddress1", ConditionOperator.NotNull)
        }
    },
    Orders = { new OrderExpression("fullname", OrderType.Ascending) },
    TopCount = 100
};

// Add linked entity for account name
var accountLink = query.AddLink("account", "parentcustomerid", "accountid", JoinOperator.LeftOuter);
accountLink.Columns.AddColumn("name");
accountLink.EntityAlias = "parentaccount";

var results = service.RetrieveMultiple(query);
foreach (var contact in results.Entities)
{
    var accountName = contact.GetAttributeValue<AliasedValue>("parentaccount.name")?.Value;
    Console.WriteLine($"{contact["fullname"]} - {accountName ?? "No Account"}");
}

Opérations en masse

Utilisez ExecuteMultipleRequest pour des opérations en masse efficaces.

public void BulkCreateContacts(IOrganizationService service, List<Entity> contacts)
{
    var batchSize = 100;
    var batches = contacts
        .Select((contact, index) => new { contact, index })
        .GroupBy(x => x.index / batchSize)
        .Select(g => g.Select(x => x.contact).ToList())
        .ToList();

    int totalCreated = 0;
    foreach (var batch in batches)
    {
        var multipleRequest = new ExecuteMultipleRequest
        {
            Settings = new ExecuteMultipleSettings
            {
                ContinueOnError = true,
                ReturnResponses = true
            },
            Requests = new OrganizationRequestCollection()
        };

        foreach (var contact in batch)
        {
            multipleRequest.Requests.Add(new CreateRequest { Target = contact });
        }

        var response = (ExecuteMultipleResponse)service.Execute(multipleRequest);

        int successCount = response.Responses.Count(r => r.Fault == null);
        totalCreated += successCount;

        // Log any failures
        foreach (var item in response.Responses.Where(r => r.Fault != null))
        {
            Console.WriteLine($"Error at index {item.RequestIndex}: {item.Fault.Message}");
        }

        Console.WriteLine($"Batch complete: {successCount}/{batch.Count} created");
    }

    Console.WriteLine($"Total created: {totalCreated}/{contacts.Count}");
}

Bonne pratique :

Regroupez les opérations par lots de 100-500 pour une performance optimale. Gérez les échecs partiels gracieusement.

Planification des apps console

Exécutez les applications console sur une planification utilisant Windows Task Scheduler ou Azure Functions.

Windows Task Scheduler

Pour les scénarios on-premises, utilisez Windows Task Scheduler pour exécuter les apps console à des intervalles spécifiés.

Azure Functions

Pour l'automatisation hébergée dans le cloud, convertissez la logique de l'app console en Azure Functions avec des déclencheurs timer.

Gestion des erreurs et journalisation

Mettez en œuvre une gestion d'erreurs robuste et une journalisation pour l'automatisation en production.

public void ProcessRecord(IOrganizationService service, Guid recordId)
{
    try
    {
        var record = service.Retrieve("account", recordId, new ColumnSet(true));
        // Process record
    }
    catch (FaultException<OrganizationServiceFault> ex)
    {
        // Dynamics 365 specific error
        Console.WriteLine($"D365 Error: {ex.Detail.Message}");
        Console.WriteLine($"Error Code: {ex.Detail.ErrorCode}");

        if (ex.Detail.InnerFault != null)
        {
            Console.WriteLine($"Inner Error: {ex.Detail.InnerFault.Message}");
        }
    }
    catch (TimeoutException ex)
    {
        Console.WriteLine($"Timeout: {ex.Message}");
        // Implement retry logic
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Unexpected error: {ex.Message}");
        throw;
    }
}

Bonnes pratiques :

  • Utiliser des blocs try-catch autour de toutes les opérations API
  • Logger les erreurs vers des fichiers, Event Log ou Application Insights
  • Mettre en œuvre une logique de retry pour les échecs transitoires
  • Envoyer des notifications pour les échecs critiques
  • Suivre les métriques d'exécution pour la surveillance

Considérations de sécurité

Considérations clés :

  • Ne jamais coder en dur les identifiants dans le code source
  • Utiliser Azure Key Vault pour la gestion des secrets
  • Mettre en œuvre des comptes de service au moindre privilège
  • Faire tourner les secrets et certificats régulièrement
  • Activer la journalisation d'audit pour les opérations automatisées

Conclusion

Les applications console fournissent une approche puissante pour automatiser les tâches Dynamics 365 qui vont au-delà de ce qui est possible avec les plugins ou Power Automate. De la migration de données à la maintenance planifiée, les apps console offrent un accès complet au SDK avec la flexibilité de l'exécution externe.

Concentrez-vous sur l'authentification appropriée, la gestion d'erreurs et les pratiques de sécurité pour construire des solutions d'automatisation fiables qui peuvent s'exécuter sans surveillance dans les environnements de production.

Besoin d'aide pour votre projet Dynamics 365 ?

Nous pouvons vous aider à mettre ces bonnes pratiques en œuvre dans votre environnement Dynamics 365.