Utilisez les messages avec le SDK pour .NET

Il est important de comprendre que toutes les opérations de données dans Dataverse sont définies comme des messages et que les définitions de ces messages sont stockées dans Dataverse.

Chaque message contient :

  • Un nom unique
  • Un ensemble de paramètres d’entrée
  • Un ensemble de paramètres de sortie

Il existe trois manières différentes d’utiliser un message avec le SDK pour .NET, comme expliqué dans les sections suivantes :

méthode Description
Classes OrganizationRequest et OrganizationResponse Utilisez ces classes lorsque vous n’avez pas de classes de requête et de réponse SDK. Vous préférerez peut-être utiliser cette approche plutôt que de générer des classes de requête et de réponse SDK lorsque vous connaissez le nom du message et les détails des paramètres d’entrée et de sortie.
Classes de requête et de réponse SDK L’utilisation de ces classes est la manière la plus courante d’utiliser les messages. De nombreux messages ont déjà des classes définies dans le SDK pour .NET. Pour les actions personnalisées, vous pouvez générer des classes.
Méthodes IOrganizationService IOrganizationService fournit quelques méthodes pour les opérations de données courantes. Ces méthodes sont les moyens les plus rapides et les plus simples d’effectuer les opérations de données les plus courantes.

Classes OrganizationRequest et OrganizationResponse

Notes

L’utilisation des classes OrganizationRequest et OrganizationResponse n’est pas la manière la plus courante d’utiliser les messages dans Dataverse. Cependant, ces classes montrent comment les messages sont implémentés. Comprendre cela est important pour comprendre comment les autres parties de Dataverse fonctionnent.

Vous pouvez utiliser un message sans les classes Requête et Réponse du SDK.

  1. Utilisez la classe OrganizationRequest.

  2. Envoyez la requête à l’aide de la méthode IOrganizationService.Execute, qui renvoie une instance OrganizationResponse.

    Les éléments de la collection OrganizationResponse.Results contiennent les résultats.

Par exemple, si vous souhaitez créer un enregistrement de compte, vous pouvez procéder ainsi :

public static Guid OrganizationRequestExample(IOrganizationService service) {

   // Instantiate an Entity instance of type 'account'
    var account = new Entity("account");
    account["name"] = "Test account";

   // Instantiate a collection of parameters with one item 'Target',
   // set to the account entity instance
    ParameterCollection parameters = new ParameterCollection
    {
        { "Target", account }
    };

   // Instantiate an OrganizationRequest instance setting the
   // RequestName and Parameters
    OrganizationRequest request = new OrganizationRequest()
    {
        RequestName = "Create",
        Parameters = parameters
    };

   // Send the request using the IOrganizationService.Execute method
    OrganizationResponse response = service.Execute(request);

   // Parse the output parameter 'id' from the Results
    return (Guid)response.Results["id"];
}

Pour créer un enregistrement de compte à l’aide de cette méthode, vous devez savoir :

  • Le nom du message : Create.
  • Le nom et le type de données de chaque paramètre d’entrée : un seul paramètre nommé Target qui est une Entité.
  • Le nom et le type de données de chaque paramètre de sortie : un seul paramètre nommé id qui est un Guid.

Ces informations sont stockées dans Dataverse. La table SdkMessage contient des informations sur tous les messages.

Dataverse gère les informations sur les paramètres d’entrée et de sortie dans les tables privées. Vous n’avez pas besoin de le récupérer, car il existe un moyen plus simple : utiliser les classes de requête et de réponse du SDK.

Classes de requête et de réponse SDK

Les classes de requête et de réponse du SDK réduisent la complexité d’utilisation des classes OrganizationRequest et OrganizationResponse. Vous n’avez pas besoin de connaître le nom du message et les paramètres d’entrée et de sortie, car les classes les ont inclus.

Le SDK pour .NET contient des définitions pour les messages Dataverse communs dans ces espaces de noms :

Espace de noms Description
Microsoft.Xrm.Sdk.Messages Messages pour les opérations de données courantes et messages utilisés pour créer et modifier les données de schéma, également appelés métadonnées.
Microsoft.Crm.Sdk.Messages Messages pour la logique métier et les opérations pour prendre en charge des fonctionnalités spéciales pour prendre en charge ALM et les applications. Certains messages de cet espace de noms prennent en charge des fonctionnalités que l’on ne trouve que dans les applications métier Microsoft Dynamics 365.

Ces classes contiennent des propriétés pour tous les paramètres d’entrée et de sortie.

  • Les classes se terminant par *Request contiennent les propriétés des paramètres d’entrée.

    Ces classes héritent de la classe OrganizationRequest.

  • Les classes se terminant par *Response contiennent les propriétés des paramètres de sortie.

    Ces classes héritent de la classe OrganizationResponse.

Par exemple, pour créer un enregistrement, vous pouvez utiliser la classe Microsoft.Xrm.Sdk.Messages.CreateRequest pour préparer la requête. Utilisez IOrganizationService.Execute pour envoyer la requête et les résultats seront sous la forme d’une instance de classe Microsoft.Xrm.Sdk.Messages.CreateResponse.

L’exemple suivant utilise la classe Microsoft.Xrm.Sdk.Messages.CreateRequest avec une classe à liaison anticipée générée pour l’entité de compte :

public static Guid CreateRequestExample(IOrganizationService service)
{
    // Instantiate an Account using generated early-bound class
    var account = new Account
    {
        Name = "Test account"
    };

    // Instantiate a CreateRequest
    var request = new CreateRequest
    {
        // Set the Target property
        Target = account
    };

    // Send the request using the IOrganizationService.Execute method
    // Cast the OrganizationResponse into a CreateResponse
    var response = (CreateResponse)service.Execute(request);

    // Return the id property value
    return response.id;
}

Générer des classes pour les actions personnalisées

Il existe d’autres messages qui n’ont pas de classes dans le SDK. Par exemple, les solutions installées fréquemment incluent de nouvelles définitions de message définies comme des actions personnalisées (API personnalisée ou actions de processus personnalisées). Pour plus d’informations, voir : Créer vos propres messages

Les développeurs peuvent générer des classes de requête et de réponse pour les messages trouvés dans leur environnement à l’aide des outils suivants :

Outil Description
CLI Power Platform
pac modelbuilder build
commande
Génère des classes .NET (Core) multiplateformes pour les applications qui utilisent le Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.
Utilisez le paramètre --generateActions pour générer des classes de requête et de réponse.
Commande de build CLI pac modelbuilder Power Platform Génère des classes .NET Framework pour prendre en charge les applications qui utilisent .NET Framework, telles que les plug-ins Dataverse.

Pour plus d’informations : Générer des classes de liaison anticipée pour le SDK pour .NET

Transmisson de paramètres facultatifs avec une requête

Il existe plusieurs paramètres facultatifs que vous pouvez passer pour appliquer des comportements spéciaux aux messages. Vous ne pouvez pas utiliser les méthodes IOrganizationService lorsque vous utilisez des paramètres facultatifs. Vous devez utiliser les classes de requête du SDK ou la classe OrganizationRequest.

Plus d’informations : Utiliser des paramètres facultatifs

Méthodes IOrganizationService

Outre la méthode IOrganizationService.Execute, l’interface IOrganizationService précise que les méthodes suivantes doivent également être implémentées. Ces méthodes encapsulent les classes Requête et Réponse correspondantes :

méthode Classes de requête et de réponse
Create CreateRequest / CreateResponse
Retrieve RetrieveRequest / RetrieveResponse
RetrieveMultiple RetrieveMultipleRequest / RetrieveMultipleResponse
Update UpdateRequest / UpdateResponse
Delete DeleteRequest / DeleteResponse
Associate AssociateRequest / AssociateResponse
Disassociate DisassociateRequest / DisassociateResponse

Ces méthodes simplifient l’exécution de ces opérations avec moins de lignes de code. L’exemple suivant utilise la méthode IOrganizationService.Create pour créer un enregistrement de compte :

public static Guid CreateMethodExample(IOrganizationService service)
{
   // Instantiate an Account using generated early-bound class
    var account = new Account
    {
        Name = "Test account"
    };

    // Use the Create method to get the id of the created account.
    return service.Create(account);
}

Comme vous pouvez le constater, les opérations de données courantes ont été rationalisées à l’aide des méthodes IOrganizationService et d’autres messages système sont simplifiés par les classes Requête et Réponse et dans les assemblys du Kit de développement logiciel (SDK) ou générés avec des outils. La plupart du temps, vous n’avez pas besoin d’utiliser les classes OrganizationRequest et OrganizationResponse sous-jacentes, mais il est important de comprendre les différentes options disponibles pour utiliser les messages, en particulier lorsque vous utilisez des API et des plug-ins personnalisés.

Utilisation des messages dans les plug-ins

Les données décrivant une opération dans un plug-in se présentent sous la forme de IExecutionContext.InputParameters et IExecutionContext.OutputParameters.

Dans les étapes PreValidation et PreOperation avant l’exploitation main du pipeline d’événements, IExecutionContext.InputParameters contient les OrganizationRequest.ParametersOrganizationRequest.Parameters.

Avec une API personnalisée, votre plug-in lit les IExecutionContext.InputParameters et contient la logique pour définir les IExecutionContext.OutputParameters en tant qu’étape d’exploitation main.

Une fois l’étape d’exploitation main à l’étape PostOperation scène, les IExecutionContext.OutputParameters contiennent les OrganizationResponse.Results.

Comprendre la structure des messages vous aidera à comprendre où trouver les données que vous souhaitez vérifier ou modifier dans le plug-in.

Pour plus d’informations :

Messages privés

Microsoft Dataverse contient des messages qui ne sont pas destinés aux développeurs tiers. Microsoft a ajouté ces messages pour activer une fonctionnalité, mais ils peuvent également être ajoutés par des solutions tierces avec la fonctionnalité d’API personnalisée. Les messages privés sont indiqués par la propriété SdkMessage.IsPrivate.

Attention

Vous ne devez pas utiliser de messages privés à moins que vous ne les ayez créés en tant qu’API personnalisée. En marquant un message comme privé, l’éditeur de solutions exprime explicitement qu’il ne prend pas en charge l’utilisation du message par d’autres applications. Il peut supprimer le message ou introduire des changements cassants à tout moment. L’utilisation de ces messages par toute personne autre que l’éditeur de solutions n’est pas prise en charge. L’appel de messages privés à partir de plug-ins n’est pas pris en charge.

Pour plus d’informations, voir : Créer et utiliser des API personnalisées

Prise en charge de la table pour les messages

Certains messages peuvent être utilisés avec plusieurs tables. Par exemple les messages Create, Update et Delete peuvent être utilisés pour la plupart des tables, mais certaines tables peuvent ne pas prendre en charge tous les messages courants.

Ces informations sont stockées dans la table SdkMessageFilter. Vous pouvez interroger cette table pour déterminer si vous pouvez utiliser un message pour une table.

Utilisez cette méthode statique pour obtenir une liste de noms de messages pouvant fonctionner avec une table :

/// <summary>
/// Write the names of messages for a table to the console
/// </summary>
/// <param name="service">The authenticated IOrganizationService to use</param>
/// <param name="tableName">The logical name of the table</param>
static void OutputTableMessageNames(IOrganizationService service, string tableName)
{
    var query = new QueryExpression(entityName: "sdkmessagefilter")
    {
        Criteria =
        {
            Conditions =
            {
                new ConditionExpression(
                    attributeName:"primaryobjecttypecode",
                    conditionOperator: ConditionOperator.Equal,
                    value: tableName)
            }
        },
        // Link to SdkMessage to get the names
        LinkEntities =
        {
            new LinkEntity(
                linkFromEntityName:"sdkmessagefilter",
                linkToEntityName: "sdkmessage",
                linkFromAttributeName: "sdkmessageid",
                linkToAttributeName: "sdkmessageid",
                joinOperator: JoinOperator.Inner)
            {
                EntityAlias = "sdkmessage",
                Columns = new ColumnSet("name"),
                LinkCriteria =
                {
                    Conditions =
                    {
                        // Don't include private messages
                        new ConditionExpression("isprivate", ConditionOperator.Equal, false)
                    }
                }
            }
        }
    };

    EntityCollection results = service.RetrieveMultiple(query);

        foreach (var entity in results.Entities)
        {
            Console.WriteLine(((AliasedValue)entity["sdkmessage.name"]).Value);
        }
}

Si vous utilisez cette méthode en définissant le paramètre tableName sur account, vous obtiendrez des résultats qui incluent ces noms de message :

Sortie :

Assign
Create
Delete
GrantAccess
Merge
ModifyAccess
Retrieve
RetrieveMultiple
RetrievePrincipalAccess
RetrieveSharedPrincipalsAndAccess
RevokeAccess
SetState
SetStateDynamicEntity
Update

Notes

Certains des messages sont déconseillés. SetState et SetStateDynamicEntity existent toujours, mais vous devriez utiliser Update à la place.

Prise en charge des messages pour les tables

Certains messages peuvent être utilisés uniquement avec des tables spécifiques. Par exemple, vous ne pouvez utiliser le message RetrieveUnpublishedMultiple qu’avec un ensemble spécifique de tables contenant des données pouvant être publiées

Ces informations sont stockées dans la table SdkMessageFilter. Vous pouvez interroger cette table pour déterminer quelles tables peuvent être utilisées pour un message spécifique.

Utilisez cette méthode statique pour obtenir une liste de noms de tables pouvant être utilisées avec un message :

/// <summary>
/// Write the names of tables for a message to the console
/// </summary>
/// <param name="service">The authenticated IOrganizationService to use</param>
/// <param name="messageName">The name of the message</param>
static void OutputTablesForMessage(IOrganizationService service, string messageName) {

    var query = new QueryExpression(entityName: "sdkmessage")
    {
        Criteria = { 
            Conditions =
            {
                new ConditionExpression(
                        attributeName: "name",
                        conditionOperator: ConditionOperator.Equal,
                        value: messageName)
            }
        },
        LinkEntities = {
            new LinkEntity(
                linkFromEntityName:"sdkmessage",
                linkToEntityName: "sdkmessagefilter",
                linkFromAttributeName: "sdkmessageid",
                linkToAttributeName: "sdkmessageid",
                joinOperator: JoinOperator.Inner)
            {
                EntityAlias = "sdkmessagefilter",
                Columns = new ColumnSet("primaryobjecttypecode"),
            }
        }
    };

            EntityCollection results = service.RetrieveMultiple(query);
            List<string> names = new List<string>();

            foreach (var entity in results.Entities)
            {
                names.Add(((AliasedValue)entity["sdkmessagefilter.primaryobjecttypecode"]).Value as string);
            }

            names.Distinct().ToList().ForEach(name => Console.WriteLine(name));
}

Si vous utilisez cette méthode en définissant le paramètre messageName sur RetrieveUnpublishedMultiple, vous obtiendrez des résultats qui incluent ces noms de table :

Sortie :

organizationui
systemform
savedquery
savedqueryvisualization
sitemap
hierarchyrule
appmodule
appconfig
appconfiginstance
webresource
mobileofflineprofile
mobileofflineprofileitem
mobileofflineprofileitemassociation
navigationsetting
appelement
appsetting
teammobileofflineprofilemembership
usermobileofflineprofilemembership

Notes

  • Pour certains messages, vous pouvez constater que des valeurs d’espace réservé sont renvoyées, telles que DeletedEntity for objectTypeCode=11478 ou new_system_donotuseentity_rp53fd1p1ekxpa_t12_b71d6344c5. Ce ne sont pas des noms de table valides. Ignorez ces valeurs.

  • Cette requête renvoie également les tables privées. Dans l’exemple ci-dessus : organizationui,hierarchyrule, appelement et appsetting sont des tables privées et ne sont pas prises en charge.

Voir aussi

Opérations de table à l’aide du SDK pour .NET
Utiliser ExecuteAsync pour exécuter des messages en mode asynchrone
Exécuter des messages en une seule transaction de base de données
Exécuter plusieurs requêtes à l’aide du SDK pour .NET

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).