Ejercicio: Adición de un controlador

Completado

Un controlador es una clase pública con uno o varios métodos públicos llamados acciones. Por convención, se coloca un controlador en el directorio Controllers de la raíz del proyecto. Las acciones se exponen como puntos de conexión HTTP dentro del controlador de API web.

Creación de un controlador

  1. Seleccione la carpeta Controllers en Visual Studio Code y agregue un nuevo archivo de nombre PizzaController.cs.

    Imagen de Visual Studio Code de la incorporación de un nuevo archivo a la carpeta Controllers.

    Se crea un archivo de clase vacío de nombre ProductsController.cs en el directorio Controllers. El nombre del directorio Controllers es una convención. El nombre del directorio procede de la arquitectura Modelo-Vista-Controlador que usa la API web.

    Nota

    Por convención, los nombres de clase de los controladores llevan el sufijo Controller.

  2. Agregue el código siguiente a Controllers/PizzaController.cs. Guarde los cambios.

    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.AspNetCore.Mvc;
    using ContosoPizza.Models;
    using ContosoPizza.Services;
    
    namespace ContosoPizza.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class PizzaController : ControllerBase
        {
            public PizzaController()
            {
            }
    
            // GET all action
    
            // GET by Id action
    
            // POST action
    
            // PUT action
    
            // DELETE action
        }
    }
    

    Como ha aprendido anteriormente, esta clase deriva de ControllerBase, la clase base para trabajar con solicitudes HTTP de ASP.NET Core. También incluye los dos atributos estándar sobre los que ha aprendido, [ApiController] y [Route]. Como antes, el atributo [Route] define una asignación al token [controller]. Puesto que esta clase de controlador se denomina PizzaController, este controlador controla las solicitudes a http://localhost:5000/pizza.

Obtención de todas las pizzas

El primer verbo REST que hay que implementar es GET, con el que un cliente podría obtener todas las pizzas de la API. Se puede usar el atributo integrado [HttpGet] para definir un método que devuelva las pizzas del servicio.

Reemplace el comentario // GET all action de Controllers/ProductsController.cs por el siguiente código:

[HttpGet]
public ActionResult<List<Pizza>> GetAll() =>
    PizzaService.GetAll();

La acción anterior:

  • Responde solo al verbo HTTP GET, tal y como indica el atributo [HttpGet].
  • Consulta el servicio en busca de todas las pizzas y devuelve automáticamente los datos cuyo Content-Type es application/json.

Recuperación de una única pizza

Es posible que el cliente también quiera solicitar información sobre una pizza específica en lugar de toda la lista. Se puede implementar otra acciónGET que requiera id. Se puede usar el atributo integrado [HttpGet("{id}")] para definir un método que devuelva las pizzas del servicio. La lógica de enrutamiento registra [HttpGet] (sin id) y [HttpGet("{id}")] (con id) como dos rutas diferentes, lo que permite escribir una acción independiente para recuperar un solo elemento.

Reemplace el comentario // GET by Id action de Controllers/ProductsController.cs por el siguiente código:

[HttpGet("{id}")]
public ActionResult<Pizza> Get(int id)
{
    var pizza = PizzaService.Get(id);

    if(pizza == null)
        return NotFound();

    return pizza;
}

La acción anterior:

  • Responde solo al verbo HTTP GET, tal y como indica el atributo [HttpGet].
  • Requiere que se incluya el valor del parámetro id en el segmento de URL después de pizza/. Recuerde que el atributo [Route] de nivel de controlador ha definido el patrón /pizza.
  • Consulta la base de datos en busca de una pizza que coincida con el parámetro id proporcionado.

Cada valor ActionResult usado en la acción anterior se asigna al código de estado HTTP correspondiente en la tabla siguiente.

Resultado de la acción
de ASP.NET Core
Código de estado HTTP Descripción
Ok está implícito 200 Hay un producto que coincide con el parámetro id proporcionado en la caché en memoria.
El producto se incluye en el cuerpo de la respuesta en el tipo multimedia que se define en el encabezado de solicitud HTTP accept (JSON de forma predeterminada).
NotFound 404 No hay ningún producto que coincida con el parámetro id proporcionado en la caché en memoria.

Compilación y prueba del controlador

  1. Ejecute el siguiente comando para compilar e iniciar la API web:

    dotnet run
    
  2. Abra el terminal httprepl existente o uno nuevo integrado desde Visual Studio Code seleccionando Terminal > Nuevo terminal en el menú principal.

  3. Conéctese a la API web mediante el comando siguiente:

httprepl http://localhost:5000

Alternatively, run the following command at any time while the HttpRepl is running:

For example:

```dotnetcli
(Disconnected)> connect http://localhost:5000
  1. Para ver el punto de conexión de pizzas ya disponible, ejecute el siguiente comando:
ls

El comando anterior detecta todas las API disponibles en el punto de conexión conectado. Debería mostrar lo siguiente:

 http://localhost:5000/> ls
 .                 []
 Pizza             [GET]
 WeatherForecast   [GET]
  1. Vaya al punto de conexión Pizza ejecutando el siguiente comando:
cd Pizza

El comando anterior muestra las API disponibles para el punto de conexión Pizza:

http://localhost:5000/> cd Pizza
/Pizza    [GET]
  1. Realice una solicitud GET en HttpRepl usando el comando siguiente:
get

El comando siguiente realiza una solicitud GET y devuelve una lista de todas las pizzas de json:

  HTTP/1.1 200 OK
  Content-Type: application/json; charset=utf-8
  Date: Fri, 02 Apr 2021 21:55:53 GMT
  Server: Kestrel
  Transfer-Encoding: chunked

  [
      {
          "id": 1,
          "name": "Classic Italian",
          "isGlutenFree": false
      },
      {
          "id": 2,
          "name": "Veggie",
          "isGlutenFree": true
      }
  ]
  1. Para consultar en busca de una sola pizza, se puede realizar otra solicitud GET, pero pase un parámetro id usando el comando siguiente:

    get 1
    

    Esto devuelve Classic Italian con la siguiente salida:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Date: Fri, 02 Apr 2021 21:57:57 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "id": 1,
        "name": "Classic Italian",
        "isGlutenFree": false
    }
    
  2. La API también controla situaciones en las que el elemento no existe. Vamos a llamar a la API de nuevo, pero pase una pizza no válida id con el siguiente comando.

    get 5
    

    Esto devuelve un error 404 Not Found con la siguiente salida:

    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json; charset=utf-8
    Date: Fri, 02 Apr 2021 22:03:06 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    {
        "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
        "title": "Not Found",
        "status": 404,
        "traceId": "00-ec263e401ec554b6a2f3e216a1d1fac5-4b40b8023d56762c-00"
    }
    
  3. Vuelva al terminal dotnet en la lista desplegable de Visual Studio Code y apague la API web al presionar CTRL+C en el teclado.

Ya se ha terminado de implementar los verbos GET y se pueden agregar más acciones a PizzaController para admitir operaciones CRUD en los datos de pizzas de la unidad siguiente.