Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Lorsque vous créez un message Microsoft Dataverse à l’aide d’une API personnalisée, vous devez spécifier le nom et le type de données de chacun des paramètres de requête et des propriétés de réponse. Les types de données peuvent être ouverts ou fermés. Avec les types fermés, chaque nom de propriété et valeur de type est connu. Tous les types définis dans Dataverse sont fermés. Le système connaît les types fermés et peut les valider pour vous. Si vous utilisez le nom incorrect ou définissez la valeur sur le type incorrect, vous obtenez une erreur. Mais les types fermés ne sont pas dynamiques. Ils n’autorisent pas les propriétés complexes et imbriquées. Normalement, une structure spécifique est une bonne chose, mais parfois votre logique métier nécessite une approche plus flexible.
Contrairement aux types fermés, les types ouverts peuvent avoir des propriétés dynamiques. L’utilisation de types ouverts avec des API personnalisées est logique quand :
- Vous devez utiliser des données dynamiques structurées. Ces données ne peuvent pas être décrites par une classe. Il n’est donc pas nécessaire de sérialiser ou de le désérialiser.
- Vous souhaitez qu’une API personnalisée accepte un paramètre de requête ou retourne une propriété de réponse qui a un type complexe qui ne peut pas être exprimé à l’aide des options disponibles. Dans ce cas, vous devez utiliser un type fermé personnalisé.
Il est important de comprendre le scénario qui s’applique à votre API personnalisée pour utiliser correctement les types ouverts. Commençons par comprendre comment utiliser les types ouverts.
Comment utiliser des types ouverts
Pour utiliser des types ouverts, vous avez besoin d’un message qui est configuré pour eux. Avec une API personnalisée, vous spécifiez qu’une propriété de paramètre de requête ou de réponse est ouverte en définissant Type (3) ou EntityCollection (4) sans spécifier un LogicalEntityName.
Lorsque vous ne spécifiez pas le LogicalEntityNameparamètre , vous indiquez à Dataverse que l’entité est une collection de paires clé/valeur qui ne peuvent pas être validées par rapport à une définition de table, de sorte qu’elle n’essaie pas.
EntityCollection sans LogicalEntityName est simplement un tableau de d’entités.
Note
Une API personnalisée définie en tant que fonctions ne peut pas utiliser les types ouverts comme paramètres de requête, mais peut les utiliser comme propriétés de réponse.
Utiliser des entités Dataverse
Bien qu’il ne s’agit pas réellement d’un type ouvert, il est important de mentionner que vous pouvez avoir une API personnalisée avec des paramètres ou des propriétés de réponse qui représentent plusieurs types d’entités fermés. Par exemple, vous pouvez créer une API personnalisée avec un Customer paramètre qui attend soit des AccountContact instances d’entité. Dataverse autorise n’importe quel type d’entité . Votre code de plug-in doit vérifier la valeur Entity.LogicalName pour déterminer s’il s’agit d’un type attendu.
Utiliser Entity en tant que dictionnaire
Le cas le plus courant consiste à utiliser Entity en tant que dictionnaire. Utilisez la collection Entity.Attributes pour spécifier un ensemble de clés et de valeurs. Les valeurs peuvent être n’importe quel type .NET et peuvent être imbriquées. N’utilisez aucune autre propriété de classe Entity .
Supposons que votre application utilise des données provenant ou envoyées à Microsoft Graph et représente le type de ressource educationSchool. Vous pouvez utiliser un type ouvert comme dans les exemples suivants.
Pour utiliser un type ouvert avec le Kit de développement logiciel (SDK), utilisez la classe Entity sans spécifier le nom de l’entité, puis définissez la collection Entity.Attributes avec les clés et leurs valeurs.
var educationSchool = new Entity() {
Attributes =
{
{ "id", Guid.NewGuid() },
{ "displayName","Redmond STEM Academy" },
{ "phone", "555-1234" },
{ "address", new Entity() //physicalAddress resource type
{
Attributes =
{
{ "city","Redmond" },
{ "countryOrRegion","United States" },
{ "postalCode","98008" },
{ "state","Washington" },
{ "street","123 Maple St" },
}
}
}
}
};
Utiliser des types Dataverse
Outre les types .NET de base, vous pouvez également utiliser des types connus pour Dataverse. Le Kit de développement logiciel (SDK) pour .NET contient des définitions de nombreuses classes que Dataverse connaît et, dans l’API web, ces types sont répertoriés dans la référence de type complexe de l’API web et la référence de type énumération.
Lorsque vous utilisez le Kit de développement logiciel (SDK), vous pouvez simplement définir les valeurs.
Lorsque vous utilisez l’API web, vous devez spécifier le type à l’aide de l’espace de noms de l’API web : Microsoft.Dynamics.CRM. L’exemple suivant utilise ces types d’API Web Dataverse :
{
"@odata.type": "Microsoft.Dynamics.CRM.expando",
"label@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"label": {
"Label": "Yes",
"LanguageCode": 1033
},
"labelarray": [
{
"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "test",
"LanguageCode": 1033
},
{
"@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel",
"Label": "prøve",
"LanguageCode": 1030
}
],
"labelarray@odata.type": "Collection(Microsoft.Dynamics.CRM.LocalizedLabel)",
"enumarray": ["DateOnly"],
"enumarray@odata.type": "Collection(Microsoft.Dynamics.CRM.DateTimeFormat)"
}
Données dynamiques structurées
Les données dynamiques structurées peuvent être définies à l’aide de différents formats qui peuvent être définis en tant que chaîne, comme JSON, XML, YAML et HTML. Ce type de données peut être facilement défini à l’aide d’un paramètre de chaîne ou d’une propriété de réponse. Pourquoi utiliser des types ouverts ?
- Utilisez une chaîne lorsque les données structurées sont transmises via votre API personnalisée à un autre service ou qu’elles sont consommées en tant que chaîne par une autre application qui appelle votre API personnalisée.
- Utilisez un type ouvert lorsque le plug-in qui prend en charge votre API personnalisée, ou les plug-ins qui étendent votre API personnalisée, doivent lire ou modifier les données structurées.
L’analyse d’une valeur de chaîne dans un objet tel que XDocument ou JObject afin de pouvoir la manipuler dans votre plug-in est une opération relativement coûteuse. Lorsque votre plug-in ou tout autre plug-in qui peut étendre la logique dans votre API personnalisée, modifie les données, il doit convertir l’objet en chaîne. Vous pouvez éviter ces opérations coûteuses à l’aide de types ouverts.
Avec les types ouverts, les appelants de votre API personnalisée peuvent utiliser la structure de dictionnaire familière que la classe Entity fournit. Votre plug-in peut interagir avec celui-ci de la même façon que vous travaillez avec d’autres enregistrements Dataverse.
Si vous sérialisez ou désérialisez les données de chaîne dans une classe, vos données ne sont pas dynamiques. Vous devez passer en revue la section suivante.
Types fermés personnalisés
Les types ouverts autorisent les données dynamiques et non structurées. Toutefois, vous devez déterminer si votre API a des paramètres véritablement dynamiques ou si vous souhaitez réellement avoir un type personnalisé.
Actuellement, vous ne pouvez pas définir un type personnalisé que Dataverse connaît. Toutefois, à l’aide de types ouverts, vous pouvez définir une classe de type fermé que Dataverse peut traiter en tant que type ouvert. Les développeurs qui utilisent votre API personnalisée peuvent utiliser vos classes pour avoir une expérience plus productive et plus productive avec moins de possibilités d’erreurs.
Par exemple, supposons que votre API personnalisée nécessite un paramètre qui suit un cours à l’aide d’un tableau de coordonnées de latitude et de longitude. Vous avez besoin d’une Location classe.
Vous pouvez créer une Location classe qui hérite de la classe Entity et contient les propriétés dont vous avez besoin. Par exemple:
using Microsoft.Xrm.Sdk;
namespace MyCompany
{
/// <summary>
/// Specifies a location for use with my_CustomAPI
/// </summary>
public class Location : Entity
{
// Gets or sets the latitude of the Location.
[AttributeLogicalName("Latitude")]
public double Latitude
{
get
{
return GetAttributeValue<double>("Latitude");
}
set
{
SetAttributeValue("Latitude", value);
}
}
// Gets or sets the longitude of the Location.
[AttributeLogicalName("Longitude")]
public double Longitude
{
get
{
return GetAttributeValue<double>("Longitude");
}
set
{
SetAttributeValue("Longitude", value);
}
}
}
}
Étant donné que ce type hérite de la Entity classe, il peut utiliser les Entity méthodes GetAttributeValue et SetAttributeValue pour accéder aux valeurs de la Attributes collection. Vous pouvez utiliser cette classe dans votre code de plug-in et la partager avec des consommateurs dans une bibliothèque ou dans un exemple de code dans votre documentation. Le résultat est le code qui est plus facile à utiliser et à lire.
Before:
var location = new Entity() {
Attributes =
{
{ "Latitude", 47.66132951804776 },
{ "Longitude", -122.11446844957624},
}
};
// OR
var location = new Entity();
location["Latitude"] = 47.66132951804776;
location["Longitude"] = -122.11446844957624;
After:
var location = new Location {
Latitude = 47.66132951804776,
Longitude = -122.11446844957624
};
// OR
var location = new Location()
location.Latitude = 47.66132951804776;
location.Longitude = -122.11446844957624;
Problèmes connus
Erreur lors de l’utilisation de données Array avec l’API web
Lorsque vous utilisez l’API web pour envoyer des données qui contiennent un tableau, l’erreur suivante se produit lorsque votre API personnalisée a un plug-in :
{
"error": {
"code": "0x80040224",
"message": "Element 'http://schemas.datacontract.org/2004/07/System.Collections.Generic:value' contains
data from a type that maps to the name 'System.Collections.Generic:List`1'. The deserializer has no
knowledge of any type that maps to this name. Consider changing the implementation of the ResolveName
method on your DataContractResolver to return a non-null value for name 'List`1' and namespace
'System.Collections.Generic'.",
}
}
Cette erreur ne se produit pas lorsque l’application cliente utilise le Kit de développement logiciel (SDK) pour .NET ou lorsqu’aucun plug-in n’est défini pour l’API personnalisée.
Utilisez le bouton Commentaires pour cette page ci-dessous pour envoyer des questions sur les types ouverts.
Voir aussi
Créer et utiliser des API personnalisées
didacticiel avancé Odata.org : type ouvert