Créer une API web avec ASP.NET Core et MongoDB
Remarque
Ceci n’est pas la dernière version de cet article. Pour la version actuelle, consultez la version .NET 9 de cet article.
Avertissement
Cette version d’ASP.NET Core n’est plus prise en charge. Pour plus d’informations, consultez la stratégie de support .NET et .NET Core. Pour la version actuelle, consultez la version .NET 9 de cet article.
Important
Ces informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.
Pour la version actuelle, consultez la version .NET 9 de cet article.
Par Pratik Khandelwal et Scott Addie
Ce tutoriel crée une API web qui exécute des opérations de création, lecture, mise à jour et suppression (CRUD) sur une base de données NoSQL MongoDB.
Dans ce tutoriel, vous allez apprendre à :
- Configurer MongoDB
- Créer une base de données MongoDB
- Définir une collection et un schéma MongoDB
- Effectuer des opérations CRUD MongoDB à partir d’une API web
- Personnaliser la sérialisation JSON
Prérequis
Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
Configurer MongoDB
Activez l’accès à MongoDB et MongoDB Shell depuis n’importe où sur la machine de développement (Windows/Linux/macOS) :
Téléchargez et installez MongoDB Shell :
- macOS/Linux : choisissez un répertoire où extraire MongoDB Shell. Ajoutez le chemin d’accès obtenu pour
mongosh
à la variable d’environnementPATH
. - Windows : MongoDB Shell (mongosh.exe) est installé dans C:\Users<utilisateur>\AppData\Local\Programs\mongosh. Ajoutez le chemin d’accès obtenu pour
mongosh.exe
à la variable d’environnementPATH
.
- macOS/Linux : choisissez un répertoire où extraire MongoDB Shell. Ajoutez le chemin d’accès obtenu pour
Téléchargez et installez MongoDB :
- macOS/Linux : vérifiez le répertoire où MongoDB a été installé, généralement dans /usr/local/mongodb. Ajoutez le chemin d’accès obtenu pour
mongodb
à la variable d’environnementPATH
. - Windows : MongoDB est installé par défaut dans C:\Program Files\MongoDB. Ajoutez C:\Program Files\MongoDB\Server<numéro_version>\bin à la variable d’environnement
PATH
.
- macOS/Linux : vérifiez le répertoire où MongoDB a été installé, généralement dans /usr/local/mongodb. Ajoutez le chemin d’accès obtenu pour
Choisir un répertoire de stockage des données : sélectionnez un répertoire sur votre machine de développement pour stocker les données. Le cas échéant, créez le répertoire. MongoDB Shell ne crée pas nouveaux répertoires :
- macOS/Linux : par exemple,
/usr/local/var/mongodb
. - Windows : par exemple,
C:\\BooksData
.
- macOS/Linux : par exemple,
Dans l’interpréteur de commandes du système d’exploitation (et non l’interpréteur de commandes MongoDB), utilisez la commande suivante pour vous connecter à MongoDB sur le port par défaut 27017. Remplacez
<data_directory_path>
par le répertoire choisi à l’étape précédente.mongod --dbpath <data_directory_path>
Utilisez l’interpréteur de commandes MongoDB précédemment installé dans les étapes suivantes pour créer une base de données, des collections, et stocker des documents. Pour plus d’informations sur les commandes MongoDB Shell, consultez mongosh
.
Ouvrez une instance de l’interpréteur de commandes MongoDB en lançant
mongosh.exe
.Dans l’interpréteur de commandes, connectez-vous à la base de données de test par défaut en exécutant la commande suivante :
mongosh
Exécutez la commande suivante dans le shell de commandes :
use BookStore
Une base de données nommée BookStore est créée si elle n’existe pas déjà. Si la base de données existe déjà, sa connexion est ouverte pour les transactions.
Créez une collection
Books
à l’aide de la commande suivante :db.createCollection('Books')
Le résultat suivant s’affiche :
{ "ok" : 1 }
Définissez un schéma pour la collection
Books
et insérez deux documents à l’aide de la commande suivante :db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
Un résultat similaire à ce qui suit s’affiche :
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Remarque
Les
ObjectId
affichés dans le résultat précédent ne correspondent pas à ceux affichés dans l’interpréteur de commandes.Affichez les documents de la base de données à l’aide de la commande suivante :
db.Books.find().pretty()
Un résultat similaire à ce qui suit s’affiche :
{ "_id" : ObjectId("61a6058e6c43f32854e51f51"), "Name" : "Design Patterns", "Price" : 54.93, "Category" : "Computers", "Author" : "Ralph Johnson" } { "_id" : ObjectId("61a6058e6c43f32854e51f52"), "Name" : "Clean Code", "Price" : 43.15, "Category" : "Computers", "Author" : "Robert C. Martin" }
Le schéma ajoute une propriété
_id
automatiquement générée de typeObjectId
pour chaque document.
Créer le projet d’API web ASP.NET Core
Accédez à Fichier>Nouveau>Projet.
Sélectionnez le type de projet API web ASP.NET Core, puis Suivant.
Nommez le projet BookStoreApi, puis sélectionnez Suivant.
Sélectionnez le framework .NET 8.0 (prise en charge à long terme), puis Créer.
Dans la fenêtre Console du Gestionnaire de Package, accédez à la racine du projet. Exécutez la commande suivante afin d’installer le pilote .NET pour MongoDB :
Install-Package MongoDB.Driver
Ajouter un modèle d’entité
Ajoutez un répertoire Models à la racine du projet.
Ajoutez une classe
Book
au répertoire Models avec le code suivant :using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace BookStoreApi.Models; public class Book { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } [BsonElement("Name")] public string BookName { get; set; } = null!; public decimal Price { get; set; } public string Category { get; set; } = null!; public string Author { get; set; } = null!; }
Dans la classe précédente, la propriété
Id
est :- Requise pour mapper l’objet Common Language Runtime (CLR) à la collection MongoDB.
- Annotée avec
[BsonId]
pour faire de cette propriété la clé primaire du document. - Annotée avec
[BsonRepresentation(BsonType.ObjectId)]
pour autoriser le passage du paramètre en tant que typestring
au lieu d’une structure ObjectId. Mongo gère la conversion destring
enObjectId
.
La propriété
BookName
est annotée avec l’attribut[BsonElement]
. La valeur de l’attribut deName
représente le nom de propriété dans la collection MongoDB.
Ajouter un modèle de configuration
Ajoutez les valeurs de configuration de base de données suivantes à
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Ajoutez une classe
BookStoreDatabaseSettings
au répertoire Models avec le code suivant :namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
La classe
BookStoreDatabaseSettings
précédente est utilisée pour stocker les valeurs de propriétéBookStoreDatabase
du fichierappsettings.json
. Les noms de propriétés JSON et C# sont nommés de manière identique pour faciliter le processus de mappage.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
Dans le code précédent, l’instance de configuration à laquelle la section
BookStoreDatabase
du fichierappsettings.json
est liée est inscrite dans le conteneur d’injection de dépendances. Par exemple, la propriétéConnectionString
de l’objetBookStoreDatabaseSettings
est peuplée avec la propriétéBookStoreDatabase:ConnectionString
dansappsettings.json
.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBookStoreDatabaseSettings
:using BookStoreApi.Models;
Ajouter un service d’opérations CRUD
Ajoutez un répertoire Services à la racine du projet.
Ajoutez une classe
BooksService
au répertoire Services avec le code suivant :using BookStoreApi.Models; using Microsoft.Extensions.Options; using MongoDB.Driver; namespace BookStoreApi.Services; public class BooksService { private readonly IMongoCollection<Book> _booksCollection; public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); } public async Task<List<Book>> GetAsync() => await _booksCollection.Find(_ => true).ToListAsync(); public async Task<Book?> GetAsync(string id) => await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync(); public async Task CreateAsync(Book newBook) => await _booksCollection.InsertOneAsync(newBook); public async Task UpdateAsync(string id, Book updatedBook) => await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook); public async Task RemoveAsync(string id) => await _booksCollection.DeleteOneAsync(x => x.Id == id); }
Dans le code précédent, une instance de
BookStoreDatabaseSettings
est récupérée à partir de l’injection de dépendances via l’injection de constructeur. Cette technique permet d’accéder aux valeurs de configuration d’appsettings.json
, qui ont été ajoutées à la section Ajouter un modèle de configuration.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
Dans le code précédent, la classe
BooksService
est inscrite auprès de l’injection de dépendances pour permettre la prise en charge de l’injection de constructeur dans les classes consommatrices. La durée de vie de service de singleton est la plus appropriée, carBooksService
a une dépendance directe surMongoClient
. Selon les recommandations officielles de réutilisation de Mongo Client,MongoClient
doit être inscrit auprès de l’injection de dépendances avec une durée de vie de service de singleton.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBooksService
:using BookStoreApi.Services;
La classe BooksService
utilise les membres MongoDB.Driver
suivants pour exécuter des opérations CRUD dans la base de données :
MongoClient : Lit l’instance de serveur qui permet d’exécuter des opérations de base de données. Le constructeur de cette classe est fourni dans la chaîne de connexion MongoDB :
public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); }
IMongoDatabase : Représente la base de données Mongo qui permet d’exécuter des opérations. Ce tutoriel utilise la méthode générique GetCollection<TDocument>(collection) sur l’interface pour accéder aux données d’une collection spécifique. Exécutez des opérations CRUD sur la collection, après l’appel de cette méthode. Dans l’appel à la méthode
GetCollection<TDocument>(collection)
:collection
représente le nom de la collection.TDocument
représente le type d’objet CLR stocké dans la collection.
GetCollection<TDocument>(collection)
retourne un objet MongoCollection représentant la collection. Dans ce didacticiel, les méthodes suivantes sont appelées sur la collection :
- DeleteOneAsync : Supprime un seul document correspondant aux critères de recherche fournis.
- Find<TDocument> : Retourne tous les documents de la collection correspondant aux critères de recherche fournis.
- InsertOneAsync : Insère l’objet fourni en tant que nouveau document dans la collection.
- ReplaceOneAsync : Remplace le seul document correspondant aux critères de recherche fournis par l’objet indiqué.
Ajout d'un contrôleur
Ajoutez une classe BooksController
au répertoire Contrôleurs avec le code suivant :
using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;
namespace BookStoreApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly BooksService _booksService;
public BooksController(BooksService booksService) =>
_booksService = booksService;
[HttpGet]
public async Task<List<Book>> Get() =>
await _booksService.GetAsync();
[HttpGet("{id:length(24)}")]
public async Task<ActionResult<Book>> Get(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
return book;
}
[HttpPost]
public async Task<IActionResult> Post(Book newBook)
{
await _booksService.CreateAsync(newBook);
return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
}
[HttpPut("{id:length(24)}")]
public async Task<IActionResult> Update(string id, Book updatedBook)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
updatedBook.Id = book.Id;
await _booksService.UpdateAsync(id, updatedBook);
return NoContent();
}
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> Delete(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
await _booksService.RemoveAsync(id);
return NoContent();
}
}
Le contrôleur d’API web précédent :
- Utilise la classe
BooksService
pour exécuter des opérations CRUD. - Contient des méthodes d’action pour prendre en charge les requêtes HTTP GET, POST, PUT et DELETE.
- Appelle CreatedAtAction dans la méthode d’action
Create
pour retourner une réponse HTTP 201. Le code d’état 201 est la réponse standard d’une méthode HTTP POST qui crée une ressource sur le serveur.CreatedAtAction
ajoute également un en-têteLocation
à la réponse. L’en-têteLocation
spécifie l’URI du livre qui vient d’être créé.
Tester l’API web
Générez et exécutez l'application.
Accédez à
https://localhost:<port>/api/books
, où<port>
est le numéro de port attribué automatiquement pour l’application, pour tester la méthode d’actionGet
sans paramètre du contrôleur, sélectionnez Essayer>Exécuter. Une réponse JSON similaire à la suivante s’affiche :[ { "id": "61a6058e6c43f32854e51f51", "bookName": "Design Patterns", "price": 54.93, "category": "Computers", "author": "Ralph Johnson" }, { "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" } ]
Accédez à
https://localhost:<port>/api/books/{id here}
pour tester la méthode d’actionGet
surchargée du contrôleur. Une réponse JSON similaire à la suivante s’affiche :{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurer les options de sérialisation JSON
Vous devez changer deux détails concernant les réponses JSON retournées dans la section Tester l’API web :
- Vous devez changer la casse mixte par défaut des noms de propriétés pour qu’elle corresponde à la casse Pascal des noms de propriétés de l’objet CLR.
- La propriété
bookName
doit être retournée sous la formeName
.
Pour satisfaire les exigences précédentes, apportez les changements suivants :
Dans
Program.cs
, ajoutez le code en surbrillance suivant à l’appel de méthodeAddControllers
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>(); builder.Services.AddControllers() .AddJsonOptions( options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
À la suite du changement effectué, les noms de propriétés de la réponse JSON sérialisée de l’API web correspondent aux noms de propriétés équivalents du type d’objet CLR. Par exemple, la propriété
Author
de la classeBook
est sérialisée en tant queAuthor
au lieu deauthor
.Dans
Models/Book.cs
, annotez la propriétéBookName
avec l’attribut[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
La valeur de l’attribut
[JsonPropertyName]
deName
représente le nom de propriété dans la réponse JSON sérialisée de l’API web.Ajoutez le code suivant en haut de
Models/Book.cs
pour résoudre la référence d’attribut[JsonProperty]
:using System.Text.Json.Serialization;
Répétez les étapes définies dans la section Tester l’API web. Notez la différence des noms de propriétés JSON.
Ajouter la prise en charge de l’authentification à une API web
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Serveur Identity Duende
Duende Identity Server est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende Identity Server active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Federation Gateway
Important
Duende Software peut vous demander de payer des frais de licence pour une utilisation en production de Duende Identity Server. Pour plus d’informations, consultez Migrer de ASP.NET Core 5.0 vers 6.0.
Pour plus d’informations, consultez la documentation Duende Identity Server (site web de Duende Software).
Ressources supplémentaires
Ce tutoriel crée une API web qui exécute des opérations de création, lecture, mise à jour et suppression (CRUD) sur une base de données NoSQL MongoDB.
Dans ce tutoriel, vous allez apprendre à :
- Configurer MongoDB
- Créer une base de données MongoDB
- Définir une collection et un schéma MongoDB
- Effectuer des opérations CRUD MongoDB à partir d’une API web
- Personnaliser la sérialisation JSON
Prérequis
Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
Configurer MongoDB
Activez l’accès à MongoDB et Mongo DB Shell à partir de n’importe où sur l’ordinateur de développement :
Sur Windows, MongoDB est installé par défaut dans C:\Program Files\MongoDB. Ajoutez C:\Program Files\MongoDB\Server<numéro_version>\bin à la variable d’environnement
PATH
.Téléchargez l’interpréteur de commandes MongoDB et choisissez un répertoire dans lequel l’extraire. Ajoutez le chemin d’accès obtenu pour
mongosh.exe
à la variable d’environnementPATH
.Choisissez sur l’ordinateur de développement un répertoire pour le stockage des données. Par exemple, C:\BooksData sous Windows. Le cas échéant, créez le répertoire. L’interpréteur de commandes mongo ne crée pas nouveaux répertoires.
Dans l’interpréteur de commandes du système d’exploitation (et non l’interpréteur de commandes MongoDB), utilisez la commande suivante pour vous connecter à MongoDB sur le port par défaut 27017. Remplacez
<data_directory_path>
par le répertoire choisi à l’étape précédente.mongod --dbpath <data_directory_path>
Utilisez l’interpréteur de commandes MongoDB précédemment installé dans les étapes suivantes pour créer une base de données, des collections, et stocker des documents. Pour plus d’informations sur les commandes MongoDB Shell, consultez mongosh
.
Ouvrez une instance de l’interpréteur de commandes MongoDB en lançant
mongosh.exe
.Dans l’interpréteur de commandes, connectez-vous à la base de données de test par défaut en exécutant la commande suivante :
mongosh
Exécutez la commande suivante dans le shell de commandes :
use BookStore
Une base de données nommée BookStore est créée si elle n’existe pas déjà. Si la base de données existe déjà, sa connexion est ouverte pour les transactions.
Créez une collection
Books
à l’aide de la commande suivante :db.createCollection('Books')
Le résultat suivant s’affiche :
{ "ok" : 1 }
Définissez un schéma pour la collection
Books
et insérez deux documents à l’aide de la commande suivante :db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
Un résultat similaire à ce qui suit s’affiche :
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Remarque
Les
ObjectId
affichés dans le résultat précédent ne correspondent pas à ceux affichés dans l’interpréteur de commandes.Affichez les documents de la base de données à l’aide de la commande suivante :
db.Books.find().pretty()
Un résultat similaire à ce qui suit s’affiche :
{ "_id" : ObjectId("61a6058e6c43f32854e51f51"), "Name" : "Design Patterns", "Price" : 54.93, "Category" : "Computers", "Author" : "Ralph Johnson" } { "_id" : ObjectId("61a6058e6c43f32854e51f52"), "Name" : "Clean Code", "Price" : 43.15, "Category" : "Computers", "Author" : "Robert C. Martin" }
Le schéma ajoute une propriété
_id
automatiquement générée de typeObjectId
pour chaque document.
Créer le projet d’API web ASP.NET Core
Accédez à Fichier>Nouveau>Projet.
Sélectionnez le type de projet API web ASP.NET Core, puis Suivant.
Nommez le projet BookStoreApi, puis sélectionnez Suivant.
Sélectionnez l’infrastructure .NET 7.0 (support Standard), puis Créer.
Dans le menu Outils, sélectionnez Gestionnaire de package NuGet>Console du gestionnaire de package.
Dans la fenêtre Console du Gestionnaire de Package, accédez à la racine du projet. Exécutez la commande suivante afin d’installer le pilote .NET pour MongoDB :
Install-Package MongoDB.Driver
Ajouter un modèle d’entité
Ajoutez un répertoire Models à la racine du projet.
Ajoutez une classe
Book
au répertoire Models avec le code suivant :using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace BookStoreApi.Models; public class Book { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } [BsonElement("Name")] public string BookName { get; set; } = null!; public decimal Price { get; set; } public string Category { get; set; } = null!; public string Author { get; set; } = null!; }
Dans la classe précédente, la propriété
Id
est :- Requise pour mapper l’objet Common Language Runtime (CLR) à la collection MongoDB.
- Annotée avec
[BsonId]
pour faire de cette propriété la clé primaire du document. - Annotée avec
[BsonRepresentation(BsonType.ObjectId)]
pour autoriser le passage du paramètre en tant que typestring
au lieu d’une structure ObjectId. Mongo gère la conversion destring
enObjectId
.
La propriété
BookName
est annotée avec l’attribut[BsonElement]
. La valeur de l’attribut deName
représente le nom de propriété dans la collection MongoDB.
Ajouter un modèle de configuration
Ajoutez les valeurs de configuration de base de données suivantes à
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Ajoutez une classe
BookStoreDatabaseSettings
au répertoire Models avec le code suivant :namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
La classe
BookStoreDatabaseSettings
précédente est utilisée pour stocker les valeurs de propriétéBookStoreDatabase
du fichierappsettings.json
. Les noms de propriétés JSON et C# sont nommés de manière identique pour faciliter le processus de mappage.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
Dans le code précédent, l’instance de configuration à laquelle la section
BookStoreDatabase
du fichierappsettings.json
est liée est inscrite dans le conteneur d’injection de dépendances. Par exemple, la propriétéConnectionString
de l’objetBookStoreDatabaseSettings
est peuplée avec la propriétéBookStoreDatabase:ConnectionString
dansappsettings.json
.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBookStoreDatabaseSettings
:using BookStoreApi.Models;
Ajouter un service d’opérations CRUD
Ajoutez un répertoire Services à la racine du projet.
Ajoutez une classe
BooksService
au répertoire Services avec le code suivant :using BookStoreApi.Models; using Microsoft.Extensions.Options; using MongoDB.Driver; namespace BookStoreApi.Services; public class BooksService { private readonly IMongoCollection<Book> _booksCollection; public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); } public async Task<List<Book>> GetAsync() => await _booksCollection.Find(_ => true).ToListAsync(); public async Task<Book?> GetAsync(string id) => await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync(); public async Task CreateAsync(Book newBook) => await _booksCollection.InsertOneAsync(newBook); public async Task UpdateAsync(string id, Book updatedBook) => await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook); public async Task RemoveAsync(string id) => await _booksCollection.DeleteOneAsync(x => x.Id == id); }
Dans le code précédent, une instance de
BookStoreDatabaseSettings
est récupérée à partir de l’injection de dépendances via l’injection de constructeur. Cette technique permet d’accéder aux valeurs de configuration d’appsettings.json
, qui ont été ajoutées à la section Ajouter un modèle de configuration.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
Dans le code précédent, la classe
BooksService
est inscrite auprès de l’injection de dépendances pour permettre la prise en charge de l’injection de constructeur dans les classes consommatrices. La durée de vie de service de singleton est la plus appropriée, carBooksService
a une dépendance directe surMongoClient
. Selon les recommandations officielles de réutilisation de Mongo Client,MongoClient
doit être inscrit auprès de l’injection de dépendances avec une durée de vie de service de singleton.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBooksService
:using BookStoreApi.Services;
La classe BooksService
utilise les membres MongoDB.Driver
suivants pour exécuter des opérations CRUD dans la base de données :
MongoClient : Lit l’instance de serveur qui permet d’exécuter des opérations de base de données. Le constructeur de cette classe reçoit la chaîne de connexion MongoDB :
public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); }
IMongoDatabase : Représente la base de données Mongo qui permet d’exécuter des opérations. Ce tutoriel utilise la méthode générique GetCollection<TDocument>(collection) sur l’interface pour accéder aux données d’une collection spécifique. Exécutez des opérations CRUD sur la collection, après l’appel de cette méthode. Dans l’appel à la méthode
GetCollection<TDocument>(collection)
:collection
représente le nom de la collection.TDocument
représente le type d’objet CLR stocké dans la collection.
GetCollection<TDocument>(collection)
retourne un objet MongoCollection représentant la collection. Dans ce didacticiel, les méthodes suivantes sont appelées sur la collection :
- DeleteOneAsync : Supprime un seul document correspondant aux critères de recherche fournis.
- Find<TDocument> : Retourne tous les documents de la collection correspondant aux critères de recherche fournis.
- InsertOneAsync : Insère l’objet fourni en tant que nouveau document dans la collection.
- ReplaceOneAsync : Remplace le seul document correspondant aux critères de recherche fournis par l’objet indiqué.
Ajout d'un contrôleur
Ajoutez une classe BooksController
au répertoire Contrôleurs avec le code suivant :
using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;
namespace BookStoreApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly BooksService _booksService;
public BooksController(BooksService booksService) =>
_booksService = booksService;
[HttpGet]
public async Task<List<Book>> Get() =>
await _booksService.GetAsync();
[HttpGet("{id:length(24)}")]
public async Task<ActionResult<Book>> Get(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
return book;
}
[HttpPost]
public async Task<IActionResult> Post(Book newBook)
{
await _booksService.CreateAsync(newBook);
return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
}
[HttpPut("{id:length(24)}")]
public async Task<IActionResult> Update(string id, Book updatedBook)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
updatedBook.Id = book.Id;
await _booksService.UpdateAsync(id, updatedBook);
return NoContent();
}
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> Delete(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
await _booksService.RemoveAsync(id);
return NoContent();
}
}
Le contrôleur d’API web précédent :
- Utilise la classe
BooksService
pour exécuter des opérations CRUD. - Contient des méthodes d’action pour prendre en charge les requêtes HTTP GET, POST, PUT et DELETE.
- Appelle CreatedAtAction dans la méthode d’action
Create
pour retourner une réponse HTTP 201. Le code d’état 201 est la réponse standard d’une méthode HTTP POST qui crée une ressource sur le serveur.CreatedAtAction
ajoute également un en-têteLocation
à la réponse. L’en-têteLocation
spécifie l’URI du livre qui vient d’être créé.
Tester l’API web
Générez et exécutez l'application.
Accédez à
https://localhost:<port>/api/books
, où<port>
est le numéro de port attribué automatiquement à l’application, pour tester la méthode d’actionGet
sans paramètre du contrôleur. Une réponse JSON similaire à la suivante s’affiche :[ { "id": "61a6058e6c43f32854e51f51", "bookName": "Design Patterns", "price": 54.93, "category": "Computers", "author": "Ralph Johnson" }, { "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" } ]
Accédez à
https://localhost:<port>/api/books/{id here}
pour tester la méthode d’actionGet
surchargée du contrôleur. Une réponse JSON similaire à la suivante s’affiche :{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurer les options de sérialisation JSON
Vous devez changer deux détails concernant les réponses JSON retournées dans la section Tester l’API web :
- Vous devez changer la casse mixte par défaut des noms de propriétés pour qu’elle corresponde à la casse Pascal des noms de propriétés de l’objet CLR.
- La propriété
bookName
doit être retournée sous la formeName
.
Pour satisfaire les exigences précédentes, apportez les changements suivants :
Dans
Program.cs
, ajoutez le code en surbrillance suivant à l’appel de méthodeAddControllers
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>(); builder.Services.AddControllers() .AddJsonOptions( options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
À la suite du changement effectué, les noms de propriétés de la réponse JSON sérialisée de l’API web correspondent aux noms de propriétés équivalents du type d’objet CLR. Par exemple, la propriété
Author
de la classeBook
est sérialisée en tant queAuthor
au lieu deauthor
.Dans
Models/Book.cs
, annotez la propriétéBookName
avec l’attribut[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
La valeur de l’attribut
[JsonPropertyName]
deName
représente le nom de propriété dans la réponse JSON sérialisée de l’API web.Ajoutez le code suivant en haut de
Models/Book.cs
pour résoudre la référence d’attribut[JsonProperty]
:using System.Text.Json.Serialization;
Répétez les étapes définies dans la section Tester l’API web. Notez la différence des noms de propriétés JSON.
Ajouter la prise en charge de l’authentification à une API web
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Serveur Identity Duende
Duende Identity Server est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende Identity Server active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Federation Gateway
Important
Duende Software peut vous demander de payer des frais de licence pour une utilisation en production de Duende Identity Server. Pour plus d’informations, consultez Migrer de ASP.NET Core 5.0 vers 6.0.
Pour plus d’informations, consultez la documentation Duende Identity Server (site web de Duende Software).
Ressources supplémentaires
Ce tutoriel crée une API web qui exécute des opérations de création, lecture, mise à jour et suppression (CRUD) sur une base de données NoSQL MongoDB.
Dans ce tutoriel, vous allez apprendre à :
- Configurer MongoDB
- Créer une base de données MongoDB
- Définir une collection et un schéma MongoDB
- Effectuer des opérations CRUD MongoDB à partir d’une API web
- Personnaliser la sérialisation JSON
Prérequis
- Visual Studio 2022 avec la charge de travail Développement web et ASP.NET.
- SDK .NET 6.0
Configurer MongoDB
Activez l’accès à MongoDB et Mongo DB Shell à partir de n’importe où sur l’ordinateur de développement :
Sur Windows, MongoDB est installé par défaut dans C:\Program Files\MongoDB. Ajoutez C:\Program Files\MongoDB\Server<numéro_version>\bin à la variable d’environnement
PATH
.Téléchargez l’interpréteur de commandes MongoDB et choisissez un répertoire dans lequel l’extraire. Ajoutez le chemin d’accès obtenu pour
mongosh.exe
à la variable d’environnementPATH
.Choisissez sur l’ordinateur de développement un répertoire pour le stockage des données. Par exemple, C:\BooksData sous Windows. Le cas échéant, créez le répertoire. L’interpréteur de commandes mongo ne crée pas nouveaux répertoires.
Dans l’interpréteur de commandes du système d’exploitation (et non l’interpréteur de commandes MongoDB), utilisez la commande suivante pour vous connecter à MongoDB sur le port par défaut 27017. Remplacez
<data_directory_path>
par le répertoire choisi à l’étape précédente.mongod --dbpath <data_directory_path>
Utilisez l’interpréteur de commandes MongoDB précédemment installé dans les étapes suivantes pour créer une base de données, des collections, et stocker des documents. Pour plus d’informations sur les commandes MongoDB Shell, consultez mongosh
.
Ouvrez une instance de l’interpréteur de commandes MongoDB en lançant
mongosh.exe
.Dans l’interpréteur de commandes, connectez-vous à la base de données de test par défaut en exécutant la commande suivante :
mongosh
Exécutez la commande suivante dans le shell de commandes :
use BookStore
Une base de données nommée BookStore est créée si elle n’existe pas déjà. Si la base de données existe déjà, sa connexion est ouverte pour les transactions.
Créez une collection
Books
à l’aide de la commande suivante :db.createCollection('Books')
Le résultat suivant s’affiche :
{ "ok" : 1 }
Définissez un schéma pour la collection
Books
et insérez deux documents à l’aide de la commande suivante :db.Books.insertMany([{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" }, { "Name": "Clean Code", "Price": 43.15, "Category": "Computers","Author": "Robert C. Martin" }])
Un résultat similaire à ce qui suit s’affiche :
{ "acknowledged" : true, "insertedIds" : [ ObjectId("61a6058e6c43f32854e51f51"), ObjectId("61a6058e6c43f32854e51f52") ] }
Remarque
Les
ObjectId
affichés dans le résultat précédent ne correspondent pas à ceux affichés dans l’interpréteur de commandes.Affichez les documents de la base de données à l’aide de la commande suivante :
db.Books.find().pretty()
Un résultat similaire à ce qui suit s’affiche :
{ "_id" : ObjectId("61a6058e6c43f32854e51f51"), "Name" : "Design Patterns", "Price" : 54.93, "Category" : "Computers", "Author" : "Ralph Johnson" } { "_id" : ObjectId("61a6058e6c43f32854e51f52"), "Name" : "Clean Code", "Price" : 43.15, "Category" : "Computers", "Author" : "Robert C. Martin" }
Le schéma ajoute une propriété
_id
automatiquement générée de typeObjectId
pour chaque document.
Créer le projet d’API web ASP.NET Core
Accédez à Fichier>Nouveau>Projet.
Sélectionnez le type de projet API web ASP.NET Core, puis Suivant.
Nommez le projet BookStoreApi, puis sélectionnez Suivant.
Sélectionnez le framework .NET 6.0 (support à long terme), puis Créer.
Dans la fenêtre Console du Gestionnaire de Package, accédez à la racine du projet. Exécutez la commande suivante afin d’installer le pilote .NET pour MongoDB :
Install-Package MongoDB.Driver
Ajouter un modèle d’entité
Ajoutez un répertoire Models à la racine du projet.
Ajoutez une classe
Book
au répertoire Models avec le code suivant :using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace BookStoreApi.Models; public class Book { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string? Id { get; set; } [BsonElement("Name")] public string BookName { get; set; } = null!; public decimal Price { get; set; } public string Category { get; set; } = null!; public string Author { get; set; } = null!; }
Dans la classe précédente, la propriété
Id
est :- Requise pour mapper l’objet Common Language Runtime (CLR) à la collection MongoDB.
- Annotée avec
[BsonId]
pour faire de cette propriété la clé primaire du document. - Annotée avec
[BsonRepresentation(BsonType.ObjectId)]
pour autoriser le passage du paramètre en tant que typestring
au lieu d’une structure ObjectId. Mongo gère la conversion destring
enObjectId
.
La propriété
BookName
est annotée avec l’attribut[BsonElement]
. La valeur de l’attribut deName
représente le nom de propriété dans la collection MongoDB.
Ajouter un modèle de configuration
Ajoutez les valeurs de configuration de base de données suivantes à
appsettings.json
:{ "BookStoreDatabase": { "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookStore", "BooksCollectionName": "Books" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }
Ajoutez une classe
BookStoreDatabaseSettings
au répertoire Models avec le code suivant :namespace BookStoreApi.Models; public class BookStoreDatabaseSettings { public string ConnectionString { get; set; } = null!; public string DatabaseName { get; set; } = null!; public string BooksCollectionName { get; set; } = null!; }
La classe
BookStoreDatabaseSettings
précédente est utilisée pour stocker les valeurs de propriétéBookStoreDatabase
du fichierappsettings.json
. Les noms de propriétés JSON et C# sont nommés de manière identique pour faciliter le processus de mappage.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase"));
Dans le code précédent, l’instance de configuration à laquelle la section
BookStoreDatabase
du fichierappsettings.json
est liée est inscrite dans le conteneur d’injection de dépendances. Par exemple, la propriétéConnectionString
de l’objetBookStoreDatabaseSettings
est peuplée avec la propriétéBookStoreDatabase:ConnectionString
dansappsettings.json
.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBookStoreDatabaseSettings
:using BookStoreApi.Models;
Ajouter un service d’opérations CRUD
Ajoutez un répertoire Services à la racine du projet.
Ajoutez une classe
BooksService
au répertoire Services avec le code suivant :using BookStoreApi.Models; using Microsoft.Extensions.Options; using MongoDB.Driver; namespace BookStoreApi.Services; public class BooksService { private readonly IMongoCollection<Book> _booksCollection; public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); } public async Task<List<Book>> GetAsync() => await _booksCollection.Find(_ => true).ToListAsync(); public async Task<Book?> GetAsync(string id) => await _booksCollection.Find(x => x.Id == id).FirstOrDefaultAsync(); public async Task CreateAsync(Book newBook) => await _booksCollection.InsertOneAsync(newBook); public async Task UpdateAsync(string id, Book updatedBook) => await _booksCollection.ReplaceOneAsync(x => x.Id == id, updatedBook); public async Task RemoveAsync(string id) => await _booksCollection.DeleteOneAsync(x => x.Id == id); }
Dans le code précédent, une instance de
BookStoreDatabaseSettings
est récupérée à partir de l’injection de dépendances via l’injection de constructeur. Cette technique permet d’accéder aux valeurs de configuration d’appsettings.json
, qui ont été ajoutées à la section Ajouter un modèle de configuration.Ajoutez le code en surbrillance suivant à
Program.cs
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>();
Dans le code précédent, la classe
BooksService
est inscrite auprès de l’injection de dépendances pour permettre la prise en charge de l’injection de constructeur dans les classes consommatrices. La durée de vie de service de singleton est la plus appropriée, carBooksService
a une dépendance directe surMongoClient
. Selon les recommandations officielles de réutilisation de Mongo Client,MongoClient
doit être inscrit auprès de l’injection de dépendances avec une durée de vie de service de singleton.Ajoutez le code suivant en haut de
Program.cs
pour résoudre la référence àBooksService
:using BookStoreApi.Services;
La classe BooksService
utilise les membres MongoDB.Driver
suivants pour exécuter des opérations CRUD dans la base de données :
MongoClient : Lit l’instance de serveur qui permet d’exécuter des opérations de base de données. Le constructeur de cette classe reçoit la chaîne de connexion MongoDB :
public BooksService( IOptions<BookStoreDatabaseSettings> bookStoreDatabaseSettings) { var mongoClient = new MongoClient( bookStoreDatabaseSettings.Value.ConnectionString); var mongoDatabase = mongoClient.GetDatabase( bookStoreDatabaseSettings.Value.DatabaseName); _booksCollection = mongoDatabase.GetCollection<Book>( bookStoreDatabaseSettings.Value.BooksCollectionName); }
IMongoDatabase : Représente la base de données Mongo qui permet d’exécuter des opérations. Ce tutoriel utilise la méthode générique GetCollection<TDocument>(collection) sur l’interface pour accéder aux données d’une collection spécifique. Exécutez des opérations CRUD sur la collection, après l’appel de cette méthode. Dans l’appel à la méthode
GetCollection<TDocument>(collection)
:collection
représente le nom de la collection.TDocument
représente le type d’objet CLR stocké dans la collection.
GetCollection<TDocument>(collection)
retourne un objet MongoCollection représentant la collection. Dans ce didacticiel, les méthodes suivantes sont appelées sur la collection :
- DeleteOneAsync : Supprime un seul document correspondant aux critères de recherche fournis.
- Find<TDocument> : Retourne tous les documents de la collection correspondant aux critères de recherche fournis.
- InsertOneAsync : Insère l’objet fourni en tant que nouveau document dans la collection.
- ReplaceOneAsync : Remplace le seul document correspondant aux critères de recherche fournis par l’objet indiqué.
Ajout d'un contrôleur
Ajoutez une classe BooksController
au répertoire Contrôleurs avec le code suivant :
using BookStoreApi.Models;
using BookStoreApi.Services;
using Microsoft.AspNetCore.Mvc;
namespace BookStoreApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class BooksController : ControllerBase
{
private readonly BooksService _booksService;
public BooksController(BooksService booksService) =>
_booksService = booksService;
[HttpGet]
public async Task<List<Book>> Get() =>
await _booksService.GetAsync();
[HttpGet("{id:length(24)}")]
public async Task<ActionResult<Book>> Get(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
return book;
}
[HttpPost]
public async Task<IActionResult> Post(Book newBook)
{
await _booksService.CreateAsync(newBook);
return CreatedAtAction(nameof(Get), new { id = newBook.Id }, newBook);
}
[HttpPut("{id:length(24)}")]
public async Task<IActionResult> Update(string id, Book updatedBook)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
updatedBook.Id = book.Id;
await _booksService.UpdateAsync(id, updatedBook);
return NoContent();
}
[HttpDelete("{id:length(24)}")]
public async Task<IActionResult> Delete(string id)
{
var book = await _booksService.GetAsync(id);
if (book is null)
{
return NotFound();
}
await _booksService.RemoveAsync(id);
return NoContent();
}
}
Le contrôleur d’API web précédent :
- Utilise la classe
BooksService
pour exécuter des opérations CRUD. - Contient des méthodes d’action pour prendre en charge les requêtes HTTP GET, POST, PUT et DELETE.
- Appelle CreatedAtAction dans la méthode d’action
Create
pour retourner une réponse HTTP 201. Le code d’état 201 est la réponse standard d’une méthode HTTP POST qui crée une ressource sur le serveur.CreatedAtAction
ajoute également un en-têteLocation
à la réponse. L’en-têteLocation
spécifie l’URI du livre qui vient d’être créé.
Tester l’API web
Générez et exécutez l'application.
Accédez à
https://localhost:<port>/api/books
, où<port>
est le numéro de port attribué automatiquement à l’application, pour tester la méthode d’actionGet
sans paramètre du contrôleur. Une réponse JSON similaire à la suivante s’affiche :[ { "id": "61a6058e6c43f32854e51f51", "bookName": "Design Patterns", "price": 54.93, "category": "Computers", "author": "Ralph Johnson" }, { "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" } ]
Accédez à
https://localhost:<port>/api/books/{id here}
pour tester la méthode d’actionGet
surchargée du contrôleur. Une réponse JSON similaire à la suivante s’affiche :{ "id": "61a6058e6c43f32854e51f52", "bookName": "Clean Code", "price": 43.15, "category": "Computers", "author": "Robert C. Martin" }
Configurer les options de sérialisation JSON
Vous devez changer deux détails concernant les réponses JSON retournées dans la section Tester l’API web :
- Vous devez changer la casse mixte par défaut des noms de propriétés pour qu’elle corresponde à la casse Pascal des noms de propriétés de l’objet CLR.
- La propriété
bookName
doit être retournée sous la formeName
.
Pour satisfaire les exigences précédentes, apportez les changements suivants :
Dans
Program.cs
, ajoutez le code en surbrillance suivant à l’appel de méthodeAddControllers
:var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.Configure<BookStoreDatabaseSettings>( builder.Configuration.GetSection("BookStoreDatabase")); builder.Services.AddSingleton<BooksService>(); builder.Services.AddControllers() .AddJsonOptions( options => options.JsonSerializerOptions.PropertyNamingPolicy = null);
À la suite du changement effectué, les noms de propriétés de la réponse JSON sérialisée de l’API web correspondent aux noms de propriétés équivalents du type d’objet CLR. Par exemple, la propriété
Author
de la classeBook
est sérialisée en tant queAuthor
au lieu deauthor
.Dans
Models/Book.cs
, annotez la propriétéBookName
avec l’attribut[JsonPropertyName]
:[BsonElement("Name")] [JsonPropertyName("Name")] public string BookName { get; set; } = null!;
La valeur de l’attribut
[JsonPropertyName]
deName
représente le nom de propriété dans la réponse JSON sérialisée de l’API web.Ajoutez le code suivant en haut de
Models/Book.cs
pour résoudre la référence d’attribut[JsonProperty]
:using System.Text.Json.Serialization;
Répétez les étapes définies dans la section Tester l’API web. Notez la différence des noms de propriétés JSON.
Ajouter la prise en charge de l’authentification à une API web
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Serveur Identity Duende
Duende Identity Server est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende Identity Server active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Federation Gateway
Important
Duende Software peut vous demander de payer des frais de licence pour une utilisation en production de Duende Identity Server. Pour plus d’informations, consultez Migrer de ASP.NET Core 5.0 vers 6.0.
Pour plus d’informations, consultez la documentation Duende Identity Server (site web de Duende Software).
Ressources supplémentaires
Ce tutoriel crée une API web qui exécute des opérations de création, lecture, mise à jour et suppression (CRUD) sur une base de données NoSQL MongoDB.
Dans ce tutoriel, vous allez apprendre à :
- Configurer MongoDB
- Créer une base de données MongoDB
- Définir une collection et un schéma MongoDB
- Effectuer des opérations CRUD MongoDB à partir d’une API web
- Personnaliser la sérialisation JSON
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Prérequis
- SDK .NET Core 3.0 ou ultérieur
- Visual Studio 2019 avec la charge de travail ASP.NET et développement web
- MongoDB
Configurer MongoDB
Si vous utilisez Windows, MongoDB est installé par défaut dans C:\Program Files\MongoDB. Ajoutez C:\Program Files\MongoDB\Server<numéro_version>\bin à la variable d’environnement Path
. Cette modification permet d’accéder à MongoDB depuis n’importe quel emplacement sur votre ordinateur de développement.
Utilisez l’interpréteur de commandes mongo dans les étapes suivantes pour créer une base de données, des collections, et stocker des documents. Pour plus d’informations sur les commandes de l’interpréteur mongo, consultez Utilisation de l’interpréteur de commandes mongo.
Choisissez sur votre ordinateur de développement un répertoire pour le stockage des données. Par exemple, C:\BooksData sous Windows. Le cas échéant, créez le répertoire. L’interpréteur de commandes mongo ne crée pas nouveaux répertoires.
Ouvrez un interpréteur de commandes. Exécutez la commande suivante pour vous connecter à MongoDB sur le port par défaut 27017. N’oubliez pas de remplacer
<data_directory_path>
par le répertoire que vous avez choisi à l’étape précédente.mongod --dbpath <data_directory_path>
Ouvrez une autre instance de l’interpréteur de commandes. Connectez-vous à la base de données de test par défaut en exécutant la commande suivante :
mongo
Exécutez la commande suivante dans l’interpréteur de commandes :
use BookstoreDb
Une base de données nommée BookstoreDb est créée si elle n’existe pas déjà. Si la base de données existe déjà, sa connexion est ouverte pour les transactions.
Créez une collection
Books
à l’aide de la commande suivante :db.createCollection('Books')
Le résultat suivant s’affiche :
{ "ok" : 1 }
Définissez un schéma pour la collection
Books
et insérez deux documents à l’aide de la commande suivante :db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson'}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin'}])
Le résultat suivant s’affiche :
{ "acknowledged" : true, "insertedIds" : [ ObjectId("5bfd996f7b8e48dc15ff215d"), ObjectId("5bfd996f7b8e48dc15ff215e") ] }
Remarque
Les ID indiqués dans cet article ne correspondent pas aux ID obtenus quand vous exécutez cet exemple.
Affichez les documents de la base de données à l’aide de la commande suivante :
db.Books.find({}).pretty()
Le résultat suivant s’affiche :
{ "_id" : ObjectId("5bfd996f7b8e48dc15ff215d"), "Name" : "Design Patterns", "Price" : 54.93, "Category" : "Computers", "Author" : "Ralph Johnson" } { "_id" : ObjectId("5bfd996f7b8e48dc15ff215e"), "Name" : "Clean Code", "Price" : 43.15, "Category" : "Computers", "Author" : "Robert C. Martin" }
Le schéma ajoute une propriété
_id
automatiquement générée de typeObjectId
pour chaque document.
La base de données est en lecture seule. Vous pouvez commencer à créer l’API web ASP.NET Core.
Créer le projet d’API web ASP.NET Core
Accédez à Fichier>Nouveau>Projet.
Sélectionnez le type de projet Application web ASP.NET Core, puis sélectionnez Suivant.
Nommez le projet BooksApi, puis sélectionnez Créer.
Sélectionnez le framework cible .NET Core et ASP.NET Core 3.0. Sélectionnez le modèle de projet API, puis sélectionnez Créer.
Visitez la Galerie NuGet : MongoDB.Driver pour déterminer la dernière version stable du pilote .NET pour MongoDB. Dans la fenêtre Console du Gestionnaire de Package, accédez à la racine du projet. Exécutez la commande suivante afin d’installer le pilote .NET pour MongoDB :
Install-Package MongoDB.Driver -Version {VERSION}
Ajouter un modèle d’entité
Ajoutez un répertoire Models à la racine du projet.
Ajoutez une classe
Book
au répertoire Models avec le code suivant :using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; namespace BooksApi.Models { public class Book { [BsonId] [BsonRepresentation(BsonType.ObjectId)] public string Id { get; set; } [BsonElement("Name")] public string BookName { get; set; } public decimal Price { get; set; } public string Category { get; set; } public string Author { get; set; } } }
Dans la classe précédente, la propriété
Id
est :- Requise pour mapper l’objet Common Language Runtime (CLR) à la collection MongoDB.
- Annotée avec
[BsonId]
pour faire de cette propriété la clé primaire du document. - Annotée avec
[BsonRepresentation(BsonType.ObjectId)]
pour autoriser le passage du paramètre en tant que typestring
au lieu d’une structure ObjectId. Mongo gère la conversion destring
enObjectId
.
La propriété
BookName
est annotée avec l’attribut[BsonElement]
. La valeur de l’attribut deName
représente le nom de propriété dans la collection MongoDB.
Ajouter un modèle de configuration
Ajoutez les valeurs de configuration de base de données suivantes à
appsettings.json
:{ "BookstoreDatabaseSettings": { "BooksCollectionName": "Books", "ConnectionString": "mongodb://localhost:27017", "DatabaseName": "BookstoreDb" }, "Logging": { "IncludeScopes": false, "Debug": { "LogLevel": { "Default": "Warning" } }, "Console": { "LogLevel": { "Default": "Warning" } } } }
Ajoutez un fichier
BookstoreDatabaseSettings.cs
au répertoire Models avec le code suivant :namespace BooksApi.Models { public class BookstoreDatabaseSettings : IBookstoreDatabaseSettings { public string BooksCollectionName { get; set; } public string ConnectionString { get; set; } public string DatabaseName { get; set; } } public interface IBookstoreDatabaseSettings { string BooksCollectionName { get; set; } string ConnectionString { get; set; } string DatabaseName { get; set; } } }
La classe
BookstoreDatabaseSettings
précédente est utilisée pour stocker les valeurs de propriétéBookstoreDatabaseSettings
du fichierappsettings.json
. Les noms de propriétés JSON et C# sont nommés de manière identique pour faciliter le processus de mappage.Ajoutez le code en surbrillance suivant à
Startup.ConfigureServices
:public void ConfigureServices(IServiceCollection services) { // requires using Microsoft.Extensions.Options services.Configure<BookstoreDatabaseSettings>( Configuration.GetSection(nameof(BookstoreDatabaseSettings))); services.AddSingleton<IBookstoreDatabaseSettings>(sp => sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value); services.AddControllers(); }
Dans le code précédent :
- L’instance de configuration à laquelle la section
BookstoreDatabaseSettings
du fichierappsettings.json
est liée est inscrite dans le conteneur d’injection de dépendances. Par exemple, la propriétéConnectionString
d’un objetBookstoreDatabaseSettings
est peuplée avec la propriétéBookstoreDatabaseSettings:ConnectionString
dansappsettings.json
. - L’interface
IBookstoreDatabaseSettings
est inscrite auprès de l’injection de dépendances avec une durée de vie de service de singleton. Une fois injectée, l’instance d’interface est résolue en objetBookstoreDatabaseSettings
.
- L’instance de configuration à laquelle la section
Ajoutez le code suivant en haut de
Startup.cs
pour résoudre les références àBookstoreDatabaseSettings
etIBookstoreDatabaseSettings
:using BooksApi.Models;
Ajouter un service d’opérations CRUD
Ajoutez un répertoire Services à la racine du projet.
Ajoutez une classe
BookService
au répertoire Services avec le code suivant :using BooksApi.Models; using MongoDB.Driver; using System.Collections.Generic; using System.Linq; namespace BooksApi.Services { public class BookService { private readonly IMongoCollection<Book> _books; public BookService(IBookstoreDatabaseSettings settings) { var client = new MongoClient(settings.ConnectionString); var database = client.GetDatabase(settings.DatabaseName); _books = database.GetCollection<Book>(settings.BooksCollectionName); } public List<Book> Get() => _books.Find(book => true).ToList(); public Book Get(string id) => _books.Find<Book>(book => book.Id == id).FirstOrDefault(); public Book Create(Book book) { _books.InsertOne(book); return book; } public void Update(string id, Book bookIn) => _books.ReplaceOne(book => book.Id == id, bookIn); public void Remove(Book bookIn) => _books.DeleteOne(book => book.Id == bookIn.Id); public void Remove(string id) => _books.DeleteOne(book => book.Id == id); } }
Dans le code précédent, une instance de
IBookstoreDatabaseSettings
est récupérée à partir de l’injection de dépendances via l’injection de constructeur. Cette technique permet d’accéder aux valeurs de configuration d’appsettings.json
, qui ont été ajoutées à la section Ajouter un modèle de configuration.Ajoutez le code en surbrillance suivant à
Startup.ConfigureServices
:public void ConfigureServices(IServiceCollection services) { services.Configure<BookstoreDatabaseSettings>( Configuration.GetSection(nameof(BookstoreDatabaseSettings))); services.AddSingleton<IBookstoreDatabaseSettings>(sp => sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value); services.AddSingleton<BookService>(); services.AddControllers(); }
Dans le code précédent, la classe
BookService
est inscrite auprès de l’injection de dépendances pour permettre la prise en charge de l’injection de constructeur dans les classes consommatrices. La durée de vie de service de singleton est la plus appropriée, carBookService
a une dépendance directe surMongoClient
. Selon les recommandations officielles de réutilisation de Mongo Client,MongoClient
doit être inscrit auprès de l’injection de dépendances avec une durée de vie de service de singleton.Ajoutez le code suivant en haut de
Startup.cs
pour résoudre la référence àBookService
:using BooksApi.Services;
La classe BookService
utilise les membres MongoDB.Driver
suivants pour exécuter des opérations CRUD dans la base de données :
MongoClient : Lit l’instance de serveur qui permet d’exécuter des opérations de base de données. Le constructeur de cette classe reçoit la chaîne de connexion MongoDB :
public BookService(IBookstoreDatabaseSettings settings) { var client = new MongoClient(settings.ConnectionString); var database = client.GetDatabase(settings.DatabaseName); _books = database.GetCollection<Book>(settings.BooksCollectionName); }
IMongoDatabase : Représente la base de données Mongo qui permet d’exécuter des opérations. Ce tutoriel utilise la méthode générique GetCollection<TDocument>(collection) sur l’interface pour accéder aux données d’une collection spécifique. Exécutez des opérations CRUD sur la collection, après l’appel de cette méthode. Dans l’appel à la méthode
GetCollection<TDocument>(collection)
:collection
représente le nom de la collection.TDocument
représente le type d’objet CLR stocké dans la collection.
GetCollection<TDocument>(collection)
retourne un objet MongoCollection représentant la collection. Dans ce didacticiel, les méthodes suivantes sont appelées sur la collection :
- DeleteOne : Supprime un seul document correspondant aux critères de recherche fournis.
- Find<TDocument> : Retourne tous les documents de la collection correspondant aux critères de recherche fournis.
- InsertOne : Insère l’objet fourni en tant que nouveau document dans la collection.
- ReplaceOne : Remplace le seul document correspondant aux critères de recherche fournis par l’objet indiqué.
Ajout d'un contrôleur
Ajoutez une classe BooksController
au répertoire Contrôleurs avec le code suivant :
using BooksApi.Models;
using BooksApi.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace BooksApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class BooksController : ControllerBase
{
private readonly BookService _bookService;
public BooksController(BookService bookService)
{
_bookService = bookService;
}
[HttpGet]
public ActionResult<List<Book>> Get() =>
_bookService.Get();
[HttpGet("{id:length(24)}", Name = "GetBook")]
public ActionResult<Book> Get(string id)
{
var book = _bookService.Get(id);
if (book == null)
{
return NotFound();
}
return book;
}
[HttpPost]
public ActionResult<Book> Create(Book book)
{
_bookService.Create(book);
return CreatedAtRoute("GetBook", new { id = book.Id.ToString() }, book);
}
[HttpPut("{id:length(24)}")]
public IActionResult Update(string id, Book bookIn)
{
var book = _bookService.Get(id);
if (book == null)
{
return NotFound();
}
_bookService.Update(id, bookIn);
return NoContent();
}
[HttpDelete("{id:length(24)}")]
public IActionResult Delete(string id)
{
var book = _bookService.Get(id);
if (book == null)
{
return NotFound();
}
_bookService.Remove(id);
return NoContent();
}
}
}
Le contrôleur d’API web précédent :
- Utilise la classe
BookService
pour exécuter des opérations CRUD. - Contient des méthodes d’action pour prendre en charge les requêtes HTTP GET, POST, PUT et DELETE.
- Appelle CreatedAtRoute dans la méthode d’action
Create
pour retourner une réponse HTTP 201. Le code d’état 201 est la réponse standard d’une méthode HTTP POST qui crée une ressource sur le serveur.CreatedAtRoute
ajoute également un en-têteLocation
à la réponse. L’en-têteLocation
spécifie l’URI du livre qui vient d’être créé.
Tester l’API web
Générez et exécutez l'application.
Accédez à
https://localhost:<port>/api/books
pour tester la méthode d’actionGet
sans paramètre du contrôleur. La réponse JSON suivante apparaît :[ { "id":"5bfd996f7b8e48dc15ff215d", "bookName":"Design Patterns", "price":54.93, "category":"Computers", "author":"Ralph Johnson" }, { "id":"5bfd996f7b8e48dc15ff215e", "bookName":"Clean Code", "price":43.15, "category":"Computers", "author":"Robert C. Martin" } ]
Accédez à
https://localhost:<port>/api/books/{id here}
pour tester la méthode d’actionGet
surchargée du contrôleur. La réponse JSON suivante apparaît :{ "id":"{ID}", "bookName":"Clean Code", "price":43.15, "category":"Computers", "author":"Robert C. Martin" }
Configurer les options de sérialisation JSON
Vous devez changer deux détails concernant les réponses JSON retournées dans la section Tester l’API web :
- Vous devez changer la casse mixte par défaut des noms de propriétés pour qu’elle corresponde à la casse Pascal des noms de propriétés de l’objet CLR.
- La propriété
bookName
doit être retournée sous la formeName
.
Pour satisfaire les exigences précédentes, apportez les changements suivants :
Json.NET a été supprimé du framework partagé ASP.NET. Ajoutez une référence de package à
Microsoft.AspNetCore.Mvc.NewtonsoftJson
.Dans
Startup.ConfigureServices
, ajoutez le code en surbrillance suivant à l’appel de méthodeAddControllers
:public void ConfigureServices(IServiceCollection services) { services.Configure<BookstoreDatabaseSettings>( Configuration.GetSection(nameof(BookstoreDatabaseSettings))); services.AddSingleton<IBookstoreDatabaseSettings>(sp => sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value); services.AddSingleton<BookService>(); services.AddControllers() .AddNewtonsoftJson(options => options.UseMemberCasing()); }
À la suite du changement effectué, les noms de propriétés de la réponse JSON sérialisée de l’API web correspondent aux noms de propriétés équivalents du type d’objet CLR. Par exemple, la propriété
Author
de la classeBook
est sérialisée en tant queAuthor
.Dans
Models/Book.cs
, annotez la propriétéBookName
avec l’attribut[JsonProperty]
suivant :[BsonElement("Name")] [JsonProperty("Name")] public string BookName { get; set; }
La valeur de l’attribut
[JsonProperty]
deName
représente le nom de propriété dans la réponse JSON sérialisée de l’API web.Ajoutez le code suivant en haut de
Models/Book.cs
pour résoudre la référence d’attribut[JsonProperty]
:using Newtonsoft.Json;
Répétez les étapes définies dans la section Tester l’API web. Notez la différence des noms de propriétés JSON.
Ajouter la prise en charge de l’authentification à une API web
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. Duende IdentityServer est un produit tiers.
Duende IdentityServer est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende IdentityServer active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Federation Gateway
Pour plus d’informations, consultez la section Vue d’ensemble de Duende IdentityServer.
Pour plus d’informations sur les autres fournisseurs d’authentification, consultez Options d’authentification de la communauté Open Source pour ASP.NET Core
Étapes suivantes
Pour plus d’informations sur la création d’API web ASP.NET Core, consultez les ressources suivantes :