Exemple de fonctions et d’actions de l’API Web (C#)
Notes
Vous n’êtes pas sûr de l’entité par rapport à la table ? Voir Développeurs : Comprendre la terminologie dans Microsoft Dataverse.
Cet exemple illustre comment appeler des fonctions et des actions liées et non liées, notamment des actions personnalisées, à l’aide de l’API Web Microsoft Dataverse.
Notes
Cet exemple implémente les opérations détaillées dans l’Exemple de fonctions et d’actions de l’API Web. Cet exemple utilise également les méthodes de classe CDSWebApiService pour la messagerie, les améliorations de performances et le traitement des erreurs.
Conditions préalables
Les conditions préalables pour tous les exemples C# de l’API Web de Dataverse sont détaillées dans la section Conditions préalables de la rubrique parente Exemples de l’API Web (C#).
Comment exécuter cet exemple
Accédez au référentiel GitHub PowerApps-Exemples clonez ou téléchargez le référentiel d’exemples, puis extrayez son contenu dans un dossier local. Accédez au dossier cds/webapi/C#/FunctionsAndActions. Ce dossier doit contenir les fichiers suivants :
| Fichier | Fonction/Description |
|---|---|
| Program.cs | Contient le code source principal pour cet exemple. |
| App.config | Fichier de configuration de l’application, contenant les informations de connexion au serveur Dataverse. Ce fichier est partagé avec plusieurs exemples d’API web dans le référentiel. Si vous configurez les informations de connexion pour un exemple, vous pouvez exécuter les autres exemples avec la même configuration. |
| FunctionsAndActions.sln FunctionsAndActions.csproj Packages.config AssemblyInfo.cs |
Fichiers d’information sur la solution, le projet, la configuration du package NuGet et l’assembly Visual Studio 2019 standard pour cet exemple. |
| WebAPIFunctionsandActions_1_0_0_0_managed.zip | Solution gérée personnalisée contenant deux actions personnalisées appelées par cet exemple. |
Utilisez ensuite la procédure suivante pour exécuter cet exemple.
En utilisant Dynamics 365 Customer Engagement (Paramètres > Solutions) ou Power Apps (Solutions), importez le fichier de solution fourni (.zip) dans votre environnement de test.
Recherchez le fichier de solution FunctionsAndActions.sln et double-cliquez dessus pour charger la solution dans Visual Studio. Générez la solution FunctionsAndActions. Tous les packages NuGet requis qui manquent ou doivent être mis à jour sont téléchargés et installés automatiquement.
Modifiez le fichier de configuration de l’application, App.config, pour spécifier les informations de connexion de votre serveur Dataverse.
Compilez et exécutez le projet FunctionsAndActions à partir de Visual Studio. Tous les exemples de solution sont configurés pour s’exécuter en mode débogage par défaut.
Liste des codes
Liste partielle Program.cs
sing System;
using System.Collections.Generic;
using System.Configuration;
using System.Net;
namespace PowerApps.Samples
{
/// <summary>
/// This program demonstrates use of functions and actions with the
/// Power Platform data service Web API.
/// </summary>
/// <remarks>Be sure to fill out App.config with your test environment information
/// and import the provided managed solution into your test environment using the web app
/// before running this program.</remarks>
/// <see cref="Https://docs.microsoft.com/powerapps/developer/data-platform/webapi/samples/functions-actions-csharp"/>
public class Program
{
public static void Main()
{
Console.Title = "Function and Actions demonstration";
// Track entity instance URIs so those records can be deleted prior to exit.
Dictionary<string, Uri> entityUris = new Dictionary<string, Uri>();
try
{
// Get environment configuration information from the connection string in App.config.
ServiceConfig config = new ServiceConfig(
ConfigurationManager.ConnectionStrings["Connect"].ConnectionString);
// Use the service class that handles HTTP messaging, error handling, and
// performance optimizations.
using (CDSWebApiService svc = new CDSWebApiService(config))
{
// Create any entity instances required by the program code that follows
CreateRequiredRecords(svc, entityUris);
#region Call an unbound function with no parameters
Console.WriteLine("\n* Call an unbound function with no parameters.");
// Retrieve the current user's full name from the WhoAmI function:
Console.Write("\tGetting information on the current user..");
JToken currentUser = svc.Get("WhoAmI");
// Obtain the user's ID and full name
JToken user = svc.Get("systemusers(" + currentUser["UserId"] + ")?$select=fullname");
Console.WriteLine("completed.");
Console.WriteLine("\tCurrent user's full name is '{0}'.", user["fullname"]);
#endregion Call an unbound function with no parameters
#region Call an unbound function that requires parameters
Console.WriteLine("\n* Call an unbound function that requires parameters");
// Retrieve the code for the specified time zone
int localeID = 1033;
string timeZoneName = "Pacific Standard Time";
// Define the unbound function and its parameters
string[] uria = new string[] {
"GetTimeZoneCodeByLocalizedName",
"(LocalizedStandardName=@p1,LocaleId=@p2)",
"?@p1='" + timeZoneName + "'&@p2=" + localeID };
// This would also work:
// string[] uria = ["GetTimeZoneCodeByLocalizedName", "(LocalizedStandardName='" +
// timeZoneName + "',LocaleId=" + localeId + ")"];
JToken localizedName = svc.Get(string.Join("", uria));
string timeZoneCode = localizedName["TimeZoneCode"].ToString();
Console.WriteLine(
"\tThe time zone '{0}' has the code '{1}'.", timeZoneName, timeZoneCode);
#endregion Call an unbound function that requires parameters
#region Call a bound function
Console.WriteLine("\n* Call a bound function");
// Retrieve the total time (minutes) spent on all tasks associated with
// incident "Sample Case".
string boundUri = entityUris["Sample Case"] +
@"/Microsoft.Dynamics.CRM.CalculateTotalTimeIncident()";
JToken cttir = svc.Get(boundUri);
string totalTime = cttir["TotalTime"].ToString();
Console.WriteLine("\tThe total duration of tasks associated with the incident " +
"is {0} minutes.", totalTime);
#endregion Call a bound function
#region Call an unbound action that requires parameters
Console.WriteLine("\n* Call an unbound action that requires parameters");
// Close the existing opportunity "Opportunity to win" and mark it as won.
JObject opportClose = new JObject()
{
{ "subject", "Won Opportunity" },
{ "opportunityid@odata.bind", entityUris["Opportunity to win"] }
};
JObject winOpportParams = new JObject()
{
{ "Status", "3" },
{ "OpportunityClose", opportClose }
};
JObject won = svc.Post("WinOpportunity", winOpportParams);
Console.WriteLine("\tOpportunity won.");
#endregion Call an unbound action that requires parameters
#region Call a bound action that requires parameters
Console.WriteLine("\n* Call a bound action that requires parameters");
// Add a new letter tracking activity to the current user's queue.
// First create a letter tracking instance.
JObject letterAttributes = new JObject()
{
{"subject", "Example letter" },
{"description", "Body of the letter" }
};
Console.Write("\tCreating letter 'Example letter'..");
Uri letterUri = svc.PostCreate("letters", letterAttributes);
entityUris.Add("Example letter", letterUri);
Console.WriteLine("completed.");
//Retrieve the ID associated with this new letter tracking activity.
JToken letter = svc.Get(letterUri + "?$select=activityid,subject");
string letterActivityId = (string)letter["activityid"];
// Retrieve the URL to current user's queue.
string myUserId = (string)currentUser["UserId"];
JToken queueRef = svc.Get("systemusers(" + myUserId + ")/queueid/$ref");
string myQueueUri = (string)queueRef["@odata.id"];
//Add the letter activity to current user's queue, then return its queue ID.
JObject targetUri = JObject.Parse(
@"{activityid: '" + letterActivityId + @"', '@odata.type': 'Microsoft.Dynamics.CRM.letter' }");
JObject addToQueueParams = new JObject()
{
{ "Target", targetUri }
};
string queueItemId = (string)svc.Post(
myQueueUri + "/Microsoft.Dynamics.CRM.AddToQueue", addToQueueParams)["QueueItemId"];
Console.WriteLine("\tLetter 'Example letter' added to current user's queue.");
Console.WriteLine("\tQueueItemId returned from AddToQueue action: {0}", queueItemId);
#endregion Call a bound action that requires parameters
#region Call a bound custom action that requires parameters
Console.WriteLine("\n* Call a bound custom action that requires parameters");
// Add a note to a specified contact. Uses the custom action sample_AddNoteToContact, which
// is bound to the contact to annotate, and takes a single param, the note to add. It also
// returns the URI to the new annotation.
JObject note = JObject.Parse(
@"{NoteTitle: 'Sample note', NoteText: 'The text content of the note.'}");
string actionUri = entityUris["Jon Fogg"].ToString() + "/Microsoft.Dynamics.CRM.sample_AddNoteToContact";
JObject contact = svc.Post(actionUri, note);
Uri annotationUri = new Uri(svc.BaseAddress + "annotations(" + contact["annotationid"] + ")");
entityUris.Add((string)note["NoteTitle"], annotationUri);
Console.WriteLine("\tA note with the title '{0}' was created and " +
"associated with the contact 'Jon Fogg'.", note["NoteTitle"]);
#endregion Call a bound custom action that requires parameters
#region Call an unbound custom action that requires parameters
Console.WriteLine("\n* Call an unbound custom action that requires parameters");
// Create a customer of the specified type, using the custom action sample_CreateCustomer,
// which takes two parameters: the type of customer ('account' or 'contact') and the name of
// the new customer.
string customerName = "New account customer (sample)";
JObject customerAttributes = JObject.Parse(
@"{CustomerType: 'account', AccountName: '" + customerName + "'}");
JObject response = svc.Post("sample_CreateCustomer", customerAttributes);
Console.WriteLine("\tThe account '" + customerName + "' was created.");
// Because the CreateCustomer custom action does not return any data about the created instance,
// we must query the customer instance to figure out its URI.
JToken customer = svc.Get("accounts?$filter=name eq 'New account customer (sample)'&$select=accountid&$top=1");
Uri customerUri = new Uri(svc.BaseAddress + "accounts(" + customer["value"][0]["accountid"] + ")");
entityUris.Add( customerName, customerUri );
// Try to call the same custom action with invalid parameters, here the same name is
// not valid for a contact. (ContactFirstname and ContactLastName parameters are
// required when CustomerType is contact.
customerAttributes = JObject.Parse(
@"{CustomerType: 'contact', AccountName: '" + customerName + "'}");
try
{
customerUri = svc.PostCreate("sample_CreateCustomer", customerAttributes);
Console.WriteLine("\tCall to the custom CreateCustomer action succeeded, which was not expected.");
}
catch (AggregateException e)
{
Console.WriteLine("\tCall to the custom CreateCustomer action did not succeed (as was expected).");
foreach (Exception inner in (e as AggregateException).InnerExceptions)
{ Console.WriteLine("\t -" + inner.Message); }
}
#endregion Call an unbound custom action that requires parameters
DeleteEntityRecords(svc, entityUris);
}
}
catch (Exception e)
{
Console.BackgroundColor = ConsoleColor.Red; // Highlight exceptions
if ( e is AggregateException )
{
foreach (Exception inner in (e as AggregateException).InnerExceptions)
{ Console.WriteLine("\n" + inner.Message); }
}
else if ( e is ServiceException)
{
var ex = e as ServiceException;
Console.WriteLine("\nMessage send response: status code {0}, {1}",
ex.StatusCode, ex.ReasonPhrase);
}
Console.ReadKey(); // Pause terminal
}
}
}
}
Voir aussi
Utilisation de l’API web Dataverse
Utiliser des fonctions API Web
Utiliser des actions API Web
Exemples d’API Web
Exemple de fonctions et d’actions de l’API Web
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é).
Commentaires
Envoyer et afficher des commentaires pour