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.
Une application qui consomme une API REST est un scénario très courant. En règle générale, vous devez générer du code client que votre application peut utiliser pour appeler l’API REST. Dans ce tutoriel, vous allez apprendre à générer automatiquement le client d’API REST pendant le processus de génération à l’aide de MSBuild. Vous utiliserez NSwag, un outil qui génère du code client pour une API REST.
L’exemple de code complet est disponible à génération de client API REST dans le référentiel d’exemples .NET sur GitHub.
L’exemple montre une application console qui consomme l’API publique Pet Store, qui publie une spécification OpenAPI .
Le tutoriel suppose une connaissance de base des termes MSBuild tels que les tâches, les cibles, les propriétés ou les runtimes. Pour obtenir le contexte nécessaire, consultez l’article Concepts MSBuild.
Lorsque vous souhaitez exécuter un outil en ligne de commande dans le cadre d’une build, il existe deux approches à prendre en compte. L’une consiste à utiliser la tâche MSBuild Exec, qui vous permet d’exécuter un outil en ligne de commande et de spécifier ses paramètres. L’autre méthode consiste à créer une tâche personnalisée dérivée de ToolTask, ce qui vous donne un meilleur contrôle.
Conditions préalables
Vous devez avoir une compréhension des concepts MSBuild tels que les tâches, les cibles et les propriétés. Consultez les concepts de MSBuild .
Les exemples nécessitent MSBuild, qui est installé avec Visual Studio, mais peut également être installé séparément. Consultez Télécharger MSBuild sans Visual Studio.
Option 1 : Tâche d'exécution
La tâche Exec appelle simplement le processus spécifié avec les arguments spécifiés, attend qu’il se termine, puis retourne true si le processus se termine correctement et false en cas d’erreur.
La génération de code NSwag peut être utilisée à partir de MSBuild ; voir NSwag.MSBuild.
Le code complet se trouve dans le dossier PetReaderExecTaskExample ; vous pouvez télécharger et regarder. Dans ce tutoriel, vous allez parcourir pas à pas et apprendre les concepts sur le chemin.
Créez une application console nommée
PetReaderExecTaskExample. Utilisez .NET 6.0 ou version ultérieure.Créez un autre projet dans la même solution :
PetShopRestClient(cette solution va contenir le client généré en tant que bibliothèque). Pour ce projet, utilisez .NET Standard 2.1. Le client généré ne compile pas sur .NET Standard 2.0.Dans le projet
PetReaderExecTaskExample, ajoutez une dépendance de projet au projetPetShopRestClient.Dans le projet
PetShopRestClient, incluez les packages NuGet suivants :- Nswag.MSBuild, qui permet d’accéder au générateur de code à partir de MSBuild
- Newtonsoft.Json, nécessaire pour compiler le client généré
- System.ComponentModel.Annotations, nécessaire pour compiler le client généré
Dans le projet
PetShopRestClient, ajoutez un dossier (nomméPetShopRestClient) pour la génération de code et supprimez le Class1.cs généré automatiquement.Créez un fichier texte nommé petshop-openapi-spec.json à la racine du projet. Copiez la spécification OpenAPI à partir de ici et enregistrez-la dans le fichier. Il est préférable d'enregistrer une copie de la spécification au lieu de la lire en ligne pendant la construction. Vous souhaitez toujours une build reproductible de manière cohérente qui dépend uniquement de l’entrée. L’utilisation directe de l’API peut transformer une build qui fonctionne aujourd’hui en une build qui échoue demain à partir de la même source. La capture instantanée enregistrée sur petshop-openapi-spec.json nous permet d’avoir toujours une version qui est générée même si la spécification change.
Ensuite, modifiez PetShopRestClient.csproj et ajoutez une cible MSBuild pour générer le client pendant le processus de build.
Tout d’abord, ajoutez certaines propriétés utiles pour la génération du client :
<PropertyGroup> <PetOpenApiSpecLocation>petshop-openapi-spec.json</PetOpenApiSpecLocation> <PetClientClassName>PetShopRestClient</PetClientClassName> <PetClientNamespace>PetShopRestClient</PetClientNamespace> <PetClientOutputDirectory>PetShopRestClient</PetClientOutputDirectory> </PropertyGroup>Ajoutez les cibles suivantes :
<Target Name="generatePetClient" BeforeTargets="CoreCompile" Inputs="$(PetOpenApiSpecLocation)" Outputs="$(PetClientOutputDirectory)\$(PetClientClassName).cs"> <Exec Command="$(NSwagExe) openapi2csclient /input:$(PetOpenApiSpecLocation) /classname:$(PetClientClassName) /namespace:$(PetClientNamespace) /output:$(PetClientOutputDirectory)\$(PetClientClassName).cs" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" /> </Exec> </Target> <Target Name="forceReGenerationOnRebuild" AfterTargets="CoreClean"> <Delete Files="$(PetClientOutputDirectory)\$(PetClientClassName).cs"></Delete> </Target>Notez que cette cible utilise les attributs BeforeTarget et AfterTarget comme moyen de définir l’ordre de génération. La première cible appelée
generatePetClientsera exécutée avant la cible de compilation principale, de sorte que la source sera créée avant l’exécution du compilateur. Les paramètres d’entrée et de sortie sont liés à la génération incrémentielle. MSBuild peut comparer les timestamps des fichiers d’entrée avec ceux des fichiers de sortie et déterminer s’il faut ignorer, générer ou regénérer partiellement une cible.Après avoir installé le package NuGet
NSwag.MSBuilddans votre projet, vous pouvez utiliser la variable$(NSwagExe)dans votre fichier.csprojpour exécuter l’outil en ligne de commande NSwag dans une cible MSBuild. De cette façon, les outils peuvent facilement être mis à jour via NuGet. Ici, vous utilisez la tâche MSBuildExecpour exécuter le programme NSwag avec les paramètres requis pour générer l’API REST cliente. Consultez Commande et paramètres NSwag.Vous pouvez capturer la sortie de
<Exec>en ajoutantConsoleToMsBuild="true"à votre balise<Exec>, et ensuite capturer cette sortie à l’aide du paramètreConsoleOutputdans une balise<Output>.ConsoleOutputretourne le résultat en tant queItem. L’espace blanc est coupé.ConsoleOutputest activé lorsqueConsoleToMSBuilda la valeur true.La deuxième cible appelée
forceReGenerationOnRebuildsupprime la classe générée pendant le nettoyage pour forcer la régénération du code généré pendant l’exécution de la cible de reconstruction. Cette cible s’exécute après la cible MSBuild prédéfinieCoreClean.Exécutez une reconstruction de solution Visual Studio et consultez le client généré sur le dossier
PetShopRestClient.À présent, utilisez le client généré. Accédez au client Program.cs, puis copiez le code suivant :
using System; using System.Net.Http; namespace PetReaderExecTaskExample { internal class Program { private const string baseUrl = "https://petstore.swagger.io/v2"; static void Main(string[] args) { HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(baseUrl); var petClient = new PetShopRestClient.PetShopRestClient(httpClient); var pet = petClient.GetPetByIdAsync(1).Result; Console.WriteLine($"Id: {pet.Id} Name: {pet.Name} Status: {pet.Status} CategoryName: {pet.Category.Name}"); } } }Note
Ce code utilise
new HttpClient()car il est simple à illustrer, mais il n’est pas la meilleure pratique pour le code réel. La meilleure pratique consiste à utiliserHttpClientFactorypour créer un objetHttpClientqui résout les problèmes connus deHttpClientrequête comme l’épuisement des ressources ou les problèmes DNS obsolètes. Consultez Utiliser IHttpClientFactory pour implémenter des requêtes HTTP résilientes.
Félicitations! À présent, vous pouvez exécuter le programme pour voir comment il fonctionne.
Option 2 : Tâche personnalisée dérivée de ToolTask
Dans de nombreux cas, l’utilisation de la tâche de Exec est suffisante pour exécuter un outil externe pour faire quelque chose comme la génération de code client de l’API REST, mais que se passe-t-il si vous souhaitez autoriser la génération de code client DE l’API REST si et seulement si vous n’utilisez pas de chemin Windows absolu comme entrée ? Ou que se passe-t-il si vous avez besoin de calculer d’une certaine façon où se trouve l’exécutable ? En cas de situation où vous devez exécuter du code pour effectuer un travail supplémentaire, la tâche de l’outil MSBuild est la meilleure solution. La classe ToolTask est une classe abstraite dérivée de MSBuild Task. Vous pouvez définir une sous-classe concrète, qui crée une tâche MSBuild personnalisée. Cette approche vous permet d’exécuter tout code nécessaire pour préparer l’exécution des commandes. Vous devez d’abord lire le didacticiel Créer une tâche personnalisée pour la génération de code.
Vous allez créer une tâche personnalisée dérivée de MSBuild ToolTask qui génère un client d’API REST, mais elle sera conçue pour émettre une erreur si vous essayez de référencer la spécification OpenAPI à l’aide d’une adresse HTTP. NSwag prend en charge une adresse HTTP en tant qu’entrée de spécification OpenAPI, mais à des fins de cet exemple, supposons qu’il existe une exigence de conception pour interdire cela.
Le code complet se trouve dans ce dossier PetReaderToolTaskExample ; vous pouvez télécharger et regarder. Dans ce tutoriel, vous allez parcourir pas à pas et découvrir certains concepts que vous pouvez appliquer à vos propres scénarios.
Créez un projet Visual Studio pour la tâche personnalisée. Appelez-le
RestApiClientGeneratoret utilisez le modèle de bibliothèque de classes (C#) avec .NET Standard 2.0. Nommez la solutionPetReaderToolTaskExample.Supprimez Class1.cs, qui a été généré automatiquement.
Ajoutez les packages NuGet
Microsoft.Build.Utilities.Core:Créer une classe appelée
RestApiClientGeneratorHéritez de MSBuild
ToolTasket implémentez la méthode abstraite, comme indiqué dans le code suivant :using Microsoft.Build.Utilities; namespace RestApiClientGenerator { public class RestApiClientGenerator : ToolTask { protected override string ToolName => throw new System.NotImplementedException(); protected override string GenerateFullPathToTool() { throw new System.NotImplementedException(); } } }
Ajoutez les paramètres suivants :
- InputOpenApiSpec, où se trouve la spécification
- ClientClassName, nom de la classe générée
- ClientNamespaceName, espace de noms où la classe est générée
- FolderClientClass, chemin d’accès au dossier où se trouve la classe
- NSwagCommandFullPath, chemin d’accès complet au répertoire où se trouve NSwag.exe
[Required] public string InputOpenApiSpec { get; set; } [Required] public string ClientClassName { get; set; } [Required] public string ClientNamespaceName { get; set; } [Required] public string FolderClientClass { get; set; } [Required] public string NSwagCommandFullPath { get; set; }Installez l'outil en ligne de commande NSwag . Vous aurez besoin du chemin d’accès complet au répertoire où se trouve NSwag.exe.
Implémentez les méthodes abstraites :
protected override string ToolName => "RestApiClientGenerator"; protected override string GenerateFullPathToTool() { return $"{NSwagCommandFullPath}\\NSwag.exe"; }Il existe de nombreuses méthodes que vous pouvez remplacer. Pour l’implémentation actuelle, définissez ces deux éléments :
- Définissez le paramètre de commande :
protected override string GenerateCommandLineCommands() { return $"openapi2csclient /input:{InputOpenApiSpec} /classname:{ClientClassName} /namespace:{ClientNamespaceName} /output:{FolderClientClass}\\{ClientClassName}.cs"; }- Validation des paramètres :
protected override bool ValidateParameters() { //http address is not allowed var valid = true; if (InputOpenApiSpec.StartsWith("http:") || InputOpenApiSpec.StartsWith("https:")) { valid = false; Log.LogError("URL is not allowed"); } return valid; }Note
Cette validation simple peut être effectuée d’une autre manière sur le fichier MSBuild, mais il est recommandé de le faire dans le code C# et d’encapsuler la commande et la logique.
Construisez le projet.
Créer une application console pour utiliser la nouvelle tâche MSBuild
L’étape suivante consiste à créer une application qui utilise la tâche.
Créez un projet application console et appelez-le
PetReaderToolTaskConsoleApp. Choisissez la version .NET souhaitée. Marquez-le comme projet de démarrage.Créez un projet de bibliothèque de classes pour générer le code, appelé
PetRestApiClient. Utilisez .NET Standard.Dans le projet
PetReaderToolTaskConsoleApp, créez une dépendance de projet pourPetRestApiClient.Dans le projet
PetRestApiClient, créez un dossierPetRestApiClient. Ce dossier contient le code généré.Supprimez Class1.cs, qui a été généré automatiquement.
Sur
PetRestApiClient, ajoutez les packages NuGet suivants :- Newtonsoft.Json, nécessaire pour compiler le client généré
- System.ComponentModel.Annotations, nécessaire pour compiler le client généré
Dans le projet
PetRestApiClient, créez un fichier texte nommé petshop-openapi-spec.json (dans le dossier du projet). Pour ajouter la spécification OpenAPI, copiez le contenu à partir de ici dans le fichier. Nous aimons une build reproductible qui dépend uniquement de l’entrée, comme indiqué précédemment. Dans cet exemple, vous déclenchez une erreur de génération si un utilisateur choisit une URL comme entrée de spécification OpenAPI.Important
Une reconstruction générale ne fonctionnera pas. Vous verrez des erreurs qui indiquent qu’il n’est pas en mesure de copier ou de supprimer
RestApiClientGenerator.dll'. Cela est dû au fait qu’il tente de générer la tâche personnalisée MBuild dans le même processus de génération qui l’utilise. SélectionnezPetReaderToolTaskConsoleAppet régénérez uniquement ce projet. La autre solution consiste à placer la tâche personnalisée dans une solution Visual Studio complètement indépendante, comme vous l’avez fait dans Tutoriel : Créer une tâche personnalisée exemple.Copiez le code suivant dans Program.cs:
using System; using System.Net.Http; namespace PetReaderToolTaskConsoleApp { internal class Program { private const string baseUrl = "https://petstore.swagger.io/v2"; static void Main(string[] args) { HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri(baseUrl); var petClient = new PetRestApiClient.PetRestApiClient(httpClient); var pet = petClient.GetPetByIdAsync(1).Result; Console.WriteLine($"Id: {pet.Id} Name: {pet.Name} Status: {pet.Status} CategoryName: {pet.Category.Name}"); } } }Modifiez les instructions MSBuild pour appeler la tâche et générer le code. Modifiez PetRestApiClient.csproj en procédant comme suit :
Enregistrer l'utilisation de la tâche personnalisée MSBuild :
<UsingTask TaskName="RestApiClientGenerator.RestApiClientGenerator" AssemblyFile="..\RestApiClientGenerator\bin\Debug\netstandard2.0\RestApiClientGenerator.dll" />Ajoutez certaines propriétés nécessaires pour exécuter la tâche :
<PropertyGroup> <!--The place where the OpenAPI spec is in--> <PetClientInputOpenApiSpec>petshop-openapi-spec.json</PetClientInputOpenApiSpec> <PetClientClientClassName>PetRestApiClient</PetClientClientClassName> <PetClientClientNamespaceName>PetRestApiClient</PetClientClientNamespaceName> <PetClientFolderClientClass>PetRestApiClient</PetClientFolderClientClass> <!--The directory where NSawg.exe is in--> <NSwagCommandFullPath>C:\Nsawg\Win</NSwagCommandFullPath> </PropertyGroup>Important
Sélectionnez la valeur de
NSwagCommandFullPathappropriée en fonction de l’emplacement d’installation de votre système.Ajoutez une cible MSBuild pour générer le client pendant le processus de build. Cette cible doit s’exécuter avant que
CoreCompiles’exécute pour générer le code utilisé dans la compilation.<Target Name="generatePetClient" BeforeTargets="CoreCompile" Inputs="$(PetClientInputOpenApiSpec)" Outputs="$(PetClientFolderClientClass)\$(PetClientClientClassName).cs"> <!--Calling our custom task derivated from MSBuild Tool Task--> <RestApiClientGenerator InputOpenApiSpec="$(PetClientInputOpenApiSpec)" ClientClassName="$(PetClientClientClassName)" ClientNamespaceName="$(PetClientClientNamespaceName)" FolderClientClass="$(PetClientFolderClientClass)" NSwagCommandFullPath="$(NSwagCommandFullPath)"></RestApiClientGenerator> </Target> <Target Name="forceReGenerationOnRebuild" AfterTargets="CoreClean"> <Delete Files="$(PetClientFolderClientClass)\$(PetClientClientClassName).cs"></Delete> </Target>
InputetOutputsont liés à la génération incrémentielle, et la cibleforceReGenerationOnRebuildsupprime le fichier généré aprèsCoreClean, ce qui force le client à être régénéré pendant l’opération de régénération.Sélectionnez
PetReaderToolTaskConsoleAppet régénérez uniquement ce projet. À présent, le code client est généré et le code se compile. Vous pouvez l’exécuter et voir comment elle fonctionne. Ce code génère le code à partir d’un fichier et est autorisé.Dans cette étape, vous allez illustrer la validation des paramètres. Dans PetRestApiClient.csproj, modifiez la propriété
$(PetClientInputOpenApiSpec)pour utiliser l’URL :<PetClientInputOpenApiSpec>https://petstore.swagger.io/v2/swagger.json</PetClientInputOpenApiSpec>Sélectionnez
PetReaderToolTaskConsoleAppet régénérez uniquement ce projet. Vous obtenez l’erreur « L’URL n’est pas autorisée » conformément à l’exigence de conception.
Télécharger le code
Installez l’outil de ligne de commande NSwag . Ensuite, vous aurez besoin du chemin d’accès complet au répertoire où se trouve NSwag.exe. Après cela, modifiez PetRestApiClient.csproj et sélectionnez la valeur de $(NSwagCommandFullPath) appropriée en fonction du chemin d’installation de votre ordinateur. À présent, sélectionnez RestApiClientGenerator et générez uniquement ce projet, puis sélectionnez et régénérez PetReaderToolTaskConsoleApp. Vous pouvez exécuter PetReaderToolTaskConsoleApp. pour vérifier que tout fonctionne comme prévu.
Étapes suivantes
Vous pouvez publier votre tâche personnalisée en tant que package NuGet.
didacticiel : Créer une tâche personnalisée
Vous pouvez également apprendre à tester une tâche personnalisée.