Créer une API web avec ASP.NET Core et Visual StudioCreate a Web API with ASP.NET Core and Visual Studio

Par Rick Anderson et Mike WassonBy Rick Anderson and Mike Wasson

Ce didacticiel génère une API web de gestion d’une liste de tâches.This tutorial builds a web API for managing a list of "to-do" items. Aucune interface utilisateur n’est créée.A user interface (UI) isn't created.

Il existe trois versions de ce didacticiel :There are three versions of this tutorial:

Vue d'ensembleOverview

Ce didacticiel crée l’API suivante :This tutorial creates the following API:

APIAPI DescriptionDescription Corps de la requêteRequest body Corps de réponseResponse body
GET /api/todoGET /api/todo Obtenir toutes les tâchesGet all to-do items Aucun.None Tableau de tâchesArray of to-do items
GET /api/todo/{id}GET /api/todo/{id} Obtenir un élément par IDGet an item by ID Aucun.None TâcheTo-do item
POST /api/todoPOST /api/todo Ajouter un nouvel élémentAdd a new item TâcheTo-do item TâcheTo-do item
PUT /api/todo/{id}PUT /api/todo/{id} Mettre à jour un élément existant  Update an existing item   TâcheTo-do item Aucun.None
DELETE /api/todo/{id}    DELETE /api/todo/{id}     Supprimer un élément    Delete an item     Aucun.None Aucun.None

Le diagramme suivant illustre la conception de base de l’application.The following diagram shows the basic design of the app.

Le client, représenté par une zone située à gauche, soumet une requête et reçoit une réponse de l’application, représentée par une zone dessinée sur la droite.

  • Le client correspond à tout ce qui consomme l’API web (application mobile, navigateur, etc.).The client is whatever consumes the web API (mobile app, browser, etc.). Ce didacticiel ne crée pas de client.This tutorial doesn't create a client. Postman ou curl est utilisé comme client pour tester l’application.Postman or curl is used as the client to test the app.

  • Un modèle est un objet qui représente les données de l’application.A model is an object that represents the data in the app. Dans le cas présent, le seul modèle est une tâche.In this case, the only model is a to-do item. Les modèles sont représentés sous forme de classes C#, également appelées objets POCO (Plain Old CLR Object).Models are represented as C# classes, also known as Plain Old CLR Object (POCOs).

  • Un contrôleur est un objet qui gère les requêtes HTTP et crée la réponse HTTP.A controller is an object that handles HTTP requests and creates the HTTP response. Cette application comporte un seul contrôleur.This app has a single controller.

  • Pour que le didacticiel reste simple, l’application n’utilise pas une base de données persistante.To keep the tutorial simple, the app doesn't use a persistent database. L’exemple d’application stocke des tâches dans une base de données en mémoire.The sample app stores to-do items in an in-memory database.

PrérequisPrerequisites

Visual Studio 2017 version 15.7.3 ou ultérieure avec les charges de travail suivantes :Visual Studio 2017 version 15.7.3 or later with the following workloads:

  • Développement web et ASP.NETASP.NET and web development
  • Développement multiplateforme .NET Core.NET Core cross-platform development

Créer le projetCreate the project

Suivez ces étapes dans Visual Studio :Follow these steps in Visual Studio:

  • Dans le menu Fichier, sélectionnez Nouveau > Projet.From the File menu, select New > Project.
  • Sélectionnez le modèle Application web ASP.NET Core.Select the ASP.NET Core Web Application template. Nommez le projet TodoApi, puis cliquez sur OK.Name the project TodoApi and click OK.
  • Dans la boîte de dialogue Nouvelle application web ASP.NET Core - TodoApi, choisissez la version ASP.NET Core.In the New ASP.NET Core Web Application - TodoApi dialog, choose the ASP.NET Core version. Sélectionnez le modèle API et cliquez sur OK.Select the API template and click OK. Ne sélectionnez pas Activer la prise en charge de Docker.Do not select Enable Docker Support.

Lancer l’applicationLaunch the app

Dans Visual Studio, appuyez sur Ctrl+F5 pour lancer l’application.In Visual Studio, press CTRL+F5 to launch the app. Visual Studio lance un navigateur et accède à http://localhost:<port>/api/values, où <port> est un numéro de port choisi de manière aléatoire.Visual Studio launches a browser and navigates to http://localhost:<port>/api/values, where <port> is a randomly chosen port number. Chrome, Microsoft Edge et Firefox affichent la sortie suivante :Chrome, Microsoft Edge, and Firefox display the following output:

["value1","value2"]

Si vous utilisez Internet Explorer, vous êtes invité à enregistrer un fichier values.json.If using Internet Explorer, you'll be prompted to save a values.json file.

Ajouter une classe de modèleAdd a model class

Un modèle est un objet qui représente les données de l’application.A model is an object representing the data in the app. Dans le cas présent, le seul modèle est une tâche.In this case, the only model is a to-do item.

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet.In Solution Explorer, right-click the project. Sélectionnez Ajouter > Nouveau dossier.Select Add > New Folder. Nommez le dossier Models.Name the folder Models.

Note

Les classes de modèles vont n’importe où dans le projet.The model classes can go anywhere in the project. Le dossier Models est utilisé par convention pour les classes de modèles.The Models folder is used by convention for model classes.

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Models et sélectionnez Ajouter > Classe.In Solution Explorer, right-click the Models folder and select Add > Class. Nommez la classe TodoItem et cliquez sur Ajouter.Name the class TodoItem and click Add.

Ajoutez le code suivant à la classe TodoItem :Update the TodoItem class with the following code:

namespace TodoApi.Models
{
    public class TodoItem
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public bool IsComplete { get; set; }
    }
}

La base de données génère la valeur Id quand un TodoItem est créé.The database generates the Id when a TodoItem is created.

Créer le contexte de base de donnéesCreate the database context

Le contexte de base de données est la classe principale qui coordonne les fonctionnalités d’Entity Framework pour un modèle de données spécifié.The database context is the main class that coordinates Entity Framework functionality for a given data model. Cette classe est créée en dérivant de la classe Microsoft.EntityFrameworkCore.DbContext.This class is created by deriving from the Microsoft.EntityFrameworkCore.DbContext class.

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Models et sélectionnez Ajouter > Classe.In Solution Explorer, right-click the Models folder and select Add > Class. Nommez la classe TodoContext et cliquez sur Ajouter.Name the class TodoContext and click Add.

Remplacez la classe par le code suivant :Replace the class with the following code:

using Microsoft.EntityFrameworkCore;

namespace TodoApi.Models
{
    public class TodoContext : DbContext
    {
        public TodoContext(DbContextOptions<TodoContext> options)
            : base(options)
        {
        }

        public DbSet<TodoItem> TodoItems { get; set; }
    }
}

Inscrire le contexte de base de donnéesRegister the database context

À cette étape, le contexte de base de données est inscrit auprès du conteneur Injection de dépendances.In this step, the database context is registered with the dependency injection container. Les services (comme le contexte de base de données) qui sont inscrits auprès du conteneur d’injection de dépendances sont accessibles aux contrôleurs.Services (such as the DB context) that are registered with the dependency injection (DI) container are available to the controllers.

Inscrivez le contexte de base de données auprès du conteneur de service à l’aide de la prise en charge intégrée de l’injection de dépendances.Register the DB context with the service container using the built-in support for dependency injection. Remplacez le contenu du fichier Startup.cs par le code suivant :Replace the contents of the Startup.cs file with the following code:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt => 
                opt.UseInMemoryDatabase("TodoList"));
            services.AddMvc()
                    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }
    }
}
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using TodoApi.Models;

namespace TodoApi
{
    public class Startup
    {       
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<TodoContext>(opt => 
                opt.UseInMemoryDatabase("TodoList"));
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMvc();
        }
    }
}

Le code précédent :The preceding code:

  • Supprime le code non utilisé.Removes the unused code.
  • Spécifie qu’une base de données en mémoire est injectée dans le conteneur de service.Specifies an in-memory database is injected into the service container.

Ajouter un contrôleurAdd a controller

Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Contrôleurs.In Solution Explorer, right-click the Controllers folder. Sélectionnez Ajouter > Nouvel élément.Select Add > New Item. Dans la boîte de dialogue Ajouter un nouvel élément, sélectionnez le modèle Classe de contrôleur d’API.In the Add New Item dialog, select the API Controller Class template. Nommez la classe TodoController et cliquez sur Ajouter.Name the class TodoController, and click Add.

Boîte de dialogue Ajouter un nouvel élément avec contrôleur dans la zone de recherche et le contrôleur des API web sélectionné

Remplacez la classe par le code suivant :Replace the class with the following code:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using TodoApi.Models;

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : ControllerBase
    {
        private readonly TodoContext _context;

        public TodoController(TodoContext context)
        {
            _context = context;

            if (_context.TodoItems.Count() == 0)
            {
                _context.TodoItems.Add(new TodoItem { Name = "Item1" });
                _context.SaveChanges();
            }
        }       
    }
}

Le code précédent définit une classe de contrôleur d’API sans méthodes.The preceding code defines an API controller class without methods. Dans les sections suivantes, des méthodes sont ajoutées pour implémenter l’API.In the next sections, methods are added to implement the API.

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using TodoApi.Models;

namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoController : ControllerBase
    {
        private readonly TodoContext _context;

        public TodoController(TodoContext context)
        {
            _context = context;

            if (_context.TodoItems.Count() == 0)
            {
                // Create a new TodoItem if collection is empty,
                // which means you can't delete all TodoItems.
                _context.TodoItems.Add(new TodoItem { Name = "Item1" });
                _context.SaveChanges();
            }
        }
    }
}

Le code précédent :The preceding code:

  • Définit une classe de contrôleur d’API sans méthodes.Defines an API controller class without methods.
  • Crée un nouvel élément Todo lorsque TodoItems est vide.Creates a new Todo item when TodoItems is empty. Vous ne pourrez pas supprimer tous les éléments Todo, car le constructeur en crée un nouveau lorsque TodoItems est vide.You won't be able to delete all the Todo items because the constructor creates a new one if TodoItems is empty.

Dans les sections suivantes, des méthodes sont ajoutées pour implémenter l’API.In the next sections, methods are added to implement the API. La classe est annotée avec un attribut [ApiController] pour activer certaines fonctionnalités utiles.The class is annotated with an [ApiController] attribute to enable some convenient features. Pour plus d’informations sur les fonctionnalités activées par l’attribut, consultez Annotation avec ApiControllerAttribute.For information on features enabled by the attribute, see Annotation with ApiControllerAttribute.

Le constructeur du contrôleur utilise une injection de dépendances pour injecter le contexte de base de données (TodoContext) dans le contrôleur.The controller's constructor uses Dependency Injection to inject the database context (TodoContext) into the controller. Le contexte de base de données est utilisé dans chacune des méthodes la CRUD du contrôleur.The database context is used in each of the CRUD methods in the controller. Le constructeur ajoute un élément à la base de données en mémoire s’il n’existe pas.The constructor adds an item to the in-memory database if one doesn't exist.

Obtenir les tâchesGet to-do items

Pour obtenir les tâches, ajoutez les méthodes suivantes à la classe TodoController :To get to-do items, add the following methods to the TodoController class:

[HttpGet]
public List<TodoItem> GetAll()
{
    return _context.TodoItems.ToList();
}

[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return Ok(item);
}
[HttpGet]
public ActionResult<List<TodoItem>> GetAll()
{
    return _context.TodoItems.ToList();
}

[HttpGet("{id}", Name = "GetTodo")]
public ActionResult<TodoItem> GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return item;
}

Ces méthodes implémentent les deux méthodes GET :These methods implement the two GET methods:

  • GET /api/todo
  • GET /api/todo/{id}

Voici un exemple de réponse HTTP pour la méthode GetAll :Here's a sample HTTP response for the GetAll method:

[
  {
    "id": 1,
    "name": "Item1",
    "isComplete": false
  }
]

Dans la suite de ce tutoriel, je vous montrerai comment afficher la réponse HTTP avec Postman ou curl.Later in the tutorial, I'll show how the HTTP response can be viewed with Postman or curl.

Routage et chemins d’URLRouting and URL paths

L’attribut [HttpGet] désigne une méthode qui répond à une requête HTTP GET.The [HttpGet] attribute denotes a method that responds to an HTTP GET request. Le chemin d’URL pour chaque méthode est construit comme suit :The URL path for each method is constructed as follows:

  • Prenez le modèle de chaîne dans l’attribut Route du contrôleur :Take the template string in the controller's Route attribute:
namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    public class TodoController : ControllerBase
    {
        private readonly TodoContext _context;
namespace TodoApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoController : ControllerBase
    {
        private readonly TodoContext _context;
  • Remplacez [controller] par le nom du contrôleur qui, par convention, est le nom de la classe du contrôleur sans le suffixe « Controller ».Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. Pour cet exemple, le nom de classe du contrôleur est TodoController et le nom racine est « todo ».For this sample, the controller class name is TodoController and the root name is "todo". Le routage d’ASP.NET Core ne respecte pas la casse.ASP.NET Core routing is case insensitive.
  • Si l’attribut [HttpGet] a un modèle de route (comme [HttpGet("/products")], ajoutez-le au chemin.If the [HttpGet] attribute has a route template (such as [HttpGet("/products")], append that to the path. Cet exemple n’utilise pas de modèle.This sample doesn't use a template. Pour plus d’informations, consultez Routage par attributs avec des attributs Http[Verbe].For more information, see Attribute routing with Http[Verb] attributes.

Dans la méthode GetById suivante, "{id}" est une variable d’espace réservé pour l’identificateur unique de la tâche.In the following GetById method, "{id}" is a placeholder variable for the unique identifier of the to-do item. Quand GetById est appelée, elle affecte la valeur de "{id}" dans l’URL au paramètre id de la méthode.When GetById is invoked, it assigns the value of "{id}" in the URL to the method's id parameter.

[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return Ok(item);
}
[HttpGet("{id}", Name = "GetTodo")]
public ActionResult<TodoItem> GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return item;
}

Name = "GetTodo" crée un itinéraire nommé.Name = "GetTodo" creates a named route. Les itinéraires nommés :Named routes:

  • permettent à l’application créer une liaison HTTP à l’aide du nom de l’itinéraire ;Enable the app to create an HTTP link using the route name.
  • sont expliqués dans la suite du didacticiel.Are explained later in the tutorial.

Valeurs de retourReturn values

La méthode GetAll retourne une collection d’objets TodoItem.The GetAll method returns a collection of TodoItem objects. MVC sérialise automatiquement l’objet en JSON et écrit le JSON dans le corps du message de réponse.MVC automatically serializes the object to JSON and writes the JSON into the body of the response message. Le code de réponse pour cette méthode est 200, en supposant qu’il n’existe pas d’exception non gérée.The response code for this method is 200, assuming there are no unhandled exceptions. Les exceptions non gérées sont converties en erreurs 5xx.Unhandled exceptions are translated into 5xx errors.

En revanche, la méthode GetById retourne le type IActionResult plus général qui représente une grande variété de types de retour.In contrast, the GetById method returns the more general IActionResult type, which represents a wide range of return types. GetById a deux types de retour différents :GetById has two different return types:

  • Si aucun élément ne correspond à l’ID demandé, la méthode retourne une erreur 404.If no item matches the requested ID, the method returns a 404 error. Le retour de NotFound entraîne une réponse HTTP 404.Returning NotFound returns an HTTP 404 response.
  • Sinon, la méthode retourne 200 avec un corps de réponse JSON.Otherwise, the method returns 200 with a JSON response body. Le retour de Ok entraîne une réponse HTTP 200.Returning Ok results in an HTTP 200 response.

En revanche, la méthode GetById retourne le type ActionResult<T> qui représente une grande variété de types de retour.In contrast, the GetById method returns the ActionResult<T> type, which represents a wide range of return types. GetById a deux types de retour différents :GetById has two different return types:

  • Si aucun élément ne correspond à l’ID demandé, la méthode retourne une erreur 404.If no item matches the requested ID, the method returns a 404 error. Le retour de NotFound entraîne une réponse HTTP 404.Returning NotFound returns an HTTP 404 response.
  • Sinon, la méthode retourne 200 avec un corps de réponse JSON.Otherwise, the method returns 200 with a JSON response body. Le retour de item entraîne une réponse HTTP 200.Returning item results in an HTTP 200 response.

Lancer l’applicationLaunch the app

Dans Visual Studio, appuyez sur Ctrl+F5 pour lancer l’application.In Visual Studio, press CTRL+F5 to launch the app. Visual Studio lance un navigateur et accède à http://localhost:<port>/api/values, où <port> est un numéro de port choisi de manière aléatoire.Visual Studio launches a browser and navigates to http://localhost:<port>/api/values, where <port> is a randomly chosen port number. Accédez au contrôleur Todo à l’adresse http://localhost:<port>/api/todo.Navigate to the Todo controller at http://localhost:<port>/api/todo.

Implémenter les autres opérations CRUDImplement the other CRUD operations

Dans les sections suivantes, les méthodes Create, Update et Delete sont ajoutées au contrôleur.In the following sections, Create, Update, and Delete methods are added to the controller.

CréerCreate

Ajoutez la méthode Create suivante :Add the following Create method:

[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
    if (item == null)
    {
        return BadRequest();
    }

    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Le code précédent est une méthode HTTP POST, comme indiqué par l’attribut [HttpPost].The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. L’attribut [FromBody] indique à MVC qu’il faut obtenir la valeur de la tâche à partir du corps de la requête HTTP.The [FromBody] attribute tells MVC to get the value of the to-do item from the body of the HTTP request.

[HttpPost]
public IActionResult Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

Le code précédent est une méthode HTTP POST, comme indiqué par l’attribut [HttpPost].The preceding code is an HTTP POST method, as indicated by the [HttpPost] attribute. MVC obtient la valeur de la tâche dans le corps de la requête HTTP.MVC gets the value of the to-do item from the body of the HTTP request.

La méthode CreatedAtRoute :The CreatedAtRoute method:

  • Retourne une réponse 201.Returns a 201 response. HTTP 201 est la réponse standard d’une méthode HTTP POST qui crée une ressource sur le serveur.HTTP 201 is the standard response for an HTTP POST method that creates a new resource on the server.
  • Ajoute un en-tête Location à la réponse.Adds a Location header to the response. L’en-tête Location spécifie l’URI de l’élément d’action qui vient d’être créé.The Location header specifies the URI of the newly created to-do item. Consultez 10.2.2 201 Created.See 10.2.2 201 Created.
  • Utilise l’itinéraire nommé « GetTodo » pour créer l’URL.Uses the "GetTodo" named route to create the URL. L’itinéraire nommé « GetTodo » est défini dans GetById :The "GetTodo" named route is defined in GetById:
[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return Ok(item);
}
[HttpGet("{id}", Name = "GetTodo")]
public ActionResult<TodoItem> GetById(long id)
{
    var item = _context.TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return item;
}

Utiliser Postman pour envoyer une requête CreateUse Postman to send a Create request

  • Démarrez l'application.Start the app.
  • Ouvrez Postman.Open Postman.

Console Postman

  • Mettez à jour le numéro de port dans l’URL localhost.Update the port number in the localhost URL.
  • Définissez la méthode HTTP sur POST.Set the HTTP method to POST.
  • Cliquez sur l’onglet Body (Corps).Click the Body tab.
  • Sélectionnez la case d’option raw (données brutes).Select the raw radio button.
  • Définissez le type sur JSON (application/json).Set the type to JSON (application/json).
  • Entrez un corps de requête avec une tâche similaire au code JSON suivant :Enter a request body with a to-do item resembling the following JSON:
{
  "name":"walk dog",
  "isComplete":true
}
  • Cliquez sur le bouton Send (Envoyer).Click the Send button.

Conseil

Si vous ne recevez pas de réponse après avoir cliqué sur Send (Envoyer), désactivez l’option SSL certification verification (Vérification de la certification SSL).If no response displays after clicking Send, disable the SSL certification verification option. Celle-ci se trouve sous File (Fichier) > Settings (Paramètres).This is found under File > Settings. Cliquez à nouveau sur le bouton Send (Envoyer) une fois le paramètre désactivé.Click the Send button again after disabling the setting.

Cliquez sur l’onglet Headers (En-têtes) dans le volet Response (Réponse), puis copiez la valeur de l’en-tête Location (Emplacement) :Click the Headers tab in the Response pane and copy the Location header value:

Onglet Headers de la console Postman

L’URI d’en-tête d’emplacement permet d’accéder au nouvel élément.The Location header URI can be used to access the new item.

Mise à jourUpdate

Ajoutez la méthode Update suivante :Add the following Update method:

[HttpPut("{id}")]
public IActionResult Update(long id, [FromBody] TodoItem item)
{
    if (item == null || item.Id != id)
    {
        return BadRequest();
    }

    var todo = _context.TodoItems.Find(id);
    if (todo == null)
    {
        return NotFound();
    }

    todo.IsComplete = item.IsComplete;
    todo.Name = item.Name;

    _context.TodoItems.Update(todo);
    _context.SaveChanges();
    return NoContent();
}
[HttpPut("{id}")]
public IActionResult Update(long id, TodoItem item)
{
    var todo = _context.TodoItems.Find(id);
    if (todo == null)
    {
        return NotFound();
    }

    todo.IsComplete = item.IsComplete;
    todo.Name = item.Name;

    _context.TodoItems.Update(todo);
    _context.SaveChanges();
    return NoContent();
}

Update est similaire à Create, à la différence près qu’il utilise HTTP PUT.Update is similar to Create, except it uses HTTP PUT. La réponse est 204 (Pas de contenu).The response is 204 (No Content). D’après la spécification HTTP, une requête PUT nécessite que le client envoie toute l’entité mise à jour, et pas seulement les différences.According to the HTTP specification, a PUT request requires the client to send the entire updated entity, not just the deltas. Pour prendre en charge les mises à jour partielles, utilisez HTTP PATCH.To support partial updates, use HTTP PATCH.

Utilisez Postman pour changer le nom de la tâche en « walk cat » :Use Postman to update the to-do item's name to "walk cat":

Console Postman montrant la réponse 204 (Pas de contenu)

SupprimerDelete

Ajoutez la méthode Delete suivante :Add the following Delete method:

[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
    var todo = _context.TodoItems.Find(id);
    if (todo == null)
    {
        return NotFound();
    }

    _context.TodoItems.Remove(todo);
    _context.SaveChanges();
    return NoContent();
}

La réponse Delete est 204 (Pas de contenu).The Delete response is 204 (No Content).

Utilisez Postman pour supprimer la tâche :Use Postman to delete the to-do item:

Console Postman montrant la réponse 204 (Pas de contenu)

Appeler l’API web avec jQueryCall the Web API with jQuery

Dans cette section, une page HTML qui utilise jQuery pour appeler l’API web est ajoutée.In this section, an HTML page is added that uses jQuery to call the Web API. jQuery lance la requête et met à jour la page avec les détails de la réponse de l’API.jQuery initiates the request and updates the page with the details from the API's response.

Configurez le projet pour traiter les fichiers statiques et activer le mappage de fichier par défaut.Configure the project to serve static files and to enable default file mapping. Pour cela, appelez les méthodes d’extension UseStaticFiles et UseDefaultFiles dans Startup.Configure.This is accomplished by invoking the UseStaticFiles and UseDefaultFiles extension methods in Startup.Configure. Pour plus d’informations, consultez Fichiers statiques.For more information, see Static files.

public void Configure(IApplicationBuilder app)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
    app.UseMvc();
}

Ajoutez un fichier HTML, nommé index.html, au répertoire wwwroot du projet.Add an HTML file, named index.html, to the project's wwwroot directory. Remplacez son contenu par le balisage suivant :Replace its contents with the following markup:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>To-do CRUD</title>
    <style>
        input[type='submit'], button, [aria-label] {
            cursor: pointer;
        }

        #spoiler {
            display: none;
        }

        table {
            font-family: Arial, sans-serif;
            border: 1px solid;
            border-collapse: collapse;
        }

        th {
            background-color: #0066CC;
            color: white;
        }

        td {
            border: 1px solid;
            padding: 5px;
        }
    </style>
</head>
<body>
    <h1>To-do CRUD</h1>
    <h3>Add</h3>
    <form action="javascript:void(0);" method="POST" onsubmit="addItem()">
        <input type="text" id="add-name" placeholder="New to-do">
        <input type="submit" value="Add">
    </form>

    <div id="spoiler">
        <h3>Edit</h3>
        <form class="my-form">
            <input type="hidden" id="edit-id">
            <input type="checkbox" id="edit-isComplete">
            <input type="text" id="edit-name">
            <input type="submit" value="Save">
            <a onclick="closeInput()" aria-label="Close">&#10006;</a>
        </form>
    </div>

    <p id="counter"></p>

    <table>
        <tr>
            <th>Is Complete</th>
            <th>Name</th>
            <th></th>
            <th></th>
        </tr>
        <tbody id="todos"></tbody>
    </table>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js"
            integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>
    <script src="site.js"></script>
</body>
</html>

Ajoutez un fichier JavaScript, nommé site.js, au répertoire wwwroot du projet.Add a JavaScript file, named site.js, to the project's wwwroot directory. Remplacez son contenu par le code suivant :Replace its contents with the following code:

const uri = "api/todo";
let todos = null;
function getCount(data) {
  const el = $("#counter");
  let name = "to-do";
  if (data) {
    if (data > 1) {
      name = "to-dos";
    }
    el.text(data + " " + name);
  } else {
    el.text("No " + name);
  }
}

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

function deleteItem(id) {
  $.ajax({
    url: uri + "/" + id,
    type: "DELETE",
    success: function(result) {
      getData();
    }
  });
}

function editItem(id) {
  $.each(todos, function(key, item) {
    if (item.id === id) {
      $("#edit-name").val(item.name);
      $("#edit-id").val(item.id);
      $("#edit-isComplete")[0].checked = item.isComplete;
    }
  });
  $("#spoiler").css({ display: "block" });
}

$(".my-form").on("submit", function() {
  const item = {
    name: $("#edit-name").val(),
    isComplete: $("#edit-isComplete").is(":checked"),
    id: $("#edit-id").val()
  };

  $.ajax({
    url: uri + "/" + $("#edit-id").val(),
    type: "PUT",
    accepts: "application/json",
    contentType: "application/json",
    data: JSON.stringify(item),
    success: function(result) {
      getData();
    }
  });

  closeInput();
  return false;
});

function closeInput() {
  $("#spoiler").css({ display: "none" });
}

Vous devrez peut-être changer les paramètres de lancement du projet ASP.NET Core pour tester la page HTML localement.A change to the ASP.NET Core project's launch settings may be required to test the HTML page locally. Ouvrez launchSettings.json dans le répertoire Propriétés du projet.Open launchSettings.json in the Properties directory of the project. Supprimez la propriété launchUrl pour forcer l’utilisation du fichier index.html (fichier par défaut du projet) à l’ouverture de l’application.Remove the launchUrl property to force the app to open at index.html—the project's default file.

Il existe plusieurs façons d’obtenir jQuery.There are several ways to get jQuery. Dans l’extrait précédent, la bibliothèque est chargée à partir d’un CDN.In the preceding snippet, the library is loaded from a CDN. Cet exemple illustre une procédure CRUD complète qui appelle l’API avec jQuery.This sample is a complete CRUD example of calling the API with jQuery. Cet exemple comprend des fonctionnalités supplémentaires qui permettent d’améliorer l’expérience.There are additional features in this sample to make the experience richer. Les explications ci-dessous traitent des appels à l’API.Below are explanations around the calls to the API.

Obtenir une liste de tâchesGet a list of to-do items

Pour obtenir une liste de tâches, envoyez une requête HTTP GET à /api/todo.To get a list of to-do items, send an HTTP GET request to /api/todo.

La fonction JQuery ajax envoie une requête AJAX à l’API, qui retourne du code JSON représentant un objet ou un tableau.The jQuery ajax function sends an AJAX request to the API, which returns JSON representing an object or array. Cette fonction peut gérer toutes les formes de l’interaction HTTP en envoyant une requête HTTP à l’url spécifiée.This function can handle all forms of HTTP interaction, sending an HTTP request to the specified url. GET est utilisé comme type.GET is used as the type. La fonction de rappel success est appelée si la requête réussit.The success callback function is invoked if the request succeeds. Dans le rappel, le DOM est mis à jour avec les informations des tâches.In the callback, the DOM is updated with the to-do information.

$(document).ready(function() {
  getData();
});

function getData() {
  $.ajax({
    type: "GET",
    url: uri,
    cache: false,
    success: function(data) {
      const tBody = $("#todos");

      $(tBody).empty();

      getCount(data.length);

      $.each(data, function(key, item) {
        const tr = $("<tr></tr>")
          .append(
            $("<td></td>").append(
              $("<input/>", {
                type: "checkbox",
                disabled: true,
                checked: item.isComplete
              })
            )
          )
          .append($("<td></td>").text(item.name))
          .append(
            $("<td></td>").append(
              $("<button>Edit</button>").on("click", function() {
                editItem(item.id);
              })
            )
          )
          .append(
            $("<td></td>").append(
              $("<button>Delete</button>").on("click", function() {
                deleteItem(item.id);
              })
            )
          );

        tr.appendTo(tBody);
      });

      todos = data;
    }
  });
}

Ajouter une tâcheAdd a to-do item

Pour ajouter une tâche, envoyez une requête HTTP POST à /api/todo/.To add a to-do item, send an HTTP POST request to /api/todo/. Le corps de la requête doit contenir un objet de tâche.The request body should contain a to-do object. La fonction ajax utilise POST pour appeler l’API.The ajax function is using POST to call the API. Pour les requêtes POST et PUT, le corps de requête représente les données envoyées à l’API.For POST and PUT requests, the request body represents the data sent to the API. L’API attend un corps de requête JSON.The API is expecting a JSON request body. Les options accepts et contentType sont définies avec la valeur application/json pour classer le type de média qui est reçu et envoyé (respectivement).The accepts and contentType options are set to application/json to classify the media type being received and sent, respectively. Les données sont converties en objet JSON avec JSON.stringify.The data is converted to a JSON object using JSON.stringify. Quand l’API retourne un code d’état de réussite, la fonction getData est appelée pour mettre à jour la table HTML.When the API returns a successful status code, the getData function is invoked to update the HTML table.

function addItem() {
  const item = {
    name: $("#add-name").val(),
    isComplete: false
  };

  $.ajax({
    type: "POST",
    accepts: "application/json",
    url: uri,
    contentType: "application/json",
    data: JSON.stringify(item),
    error: function(jqXHR, textStatus, errorThrown) {
      alert("Something went wrong!");
    },
    success: function(result) {
      getData();
      $("#add-name").val("");
    }
  });
}

Mettre à jour une tâcheUpdate a to-do item

Les opérations de mise à jour et d’ajout d’une tâche s’appuient toutes les deux sur un corps de requête et sont donc très similaires.Updating a to-do item is very similar to adding one, since both rely on a request body. Voici toutefois ce qui les distingue dans ce cas : l’url change pour ajouter l’identificateur unique de l’élément, et le type est PUT.The only real difference between the two in this case is that the url changes to add the unique identifier of the item, and the type is PUT.

$.ajax({
  url: uri + "/" + $("#edit-id").val(),
  type: "PUT",
  accepts: "application/json",
  contentType: "application/json",
  data: JSON.stringify(item),
  success: function(result) {
    getData();
  }
});

Supprimer une tâcheDelete a to-do item

Pour supprimer une tâche, vous devez définir le type sur l’appel AJAX avec la valeur DELETE et spécifier l’identificateur unique de l’élément dans l’URL.Deleting a to-do item is accomplished by setting the type on the AJAX call to DELETE and specifing the item's unique identifier in the URL.

$.ajax({
  url: uri + "/" + id,
  type: "DELETE",
  success: function(result) {
    getData();
  }
});

Étapes suivantesNext steps