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 Controladores en Visual Studio Code y agregue un nuevo archivo denominado PizzaController.cs.

    Captura de pantalla de Visual Studio Code de la incorporación de un nuevo archivo a la carpeta Controladores.

    Se crea un archivo de clase vacío de nombre ProductsController.cs en el directorio Controllers. El nombre del directorio Controladores 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 ContosoPizza.Models;
    using ContosoPizza.Services;
    using Microsoft.AspNetCore.Mvc;
    
    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 se 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]. Dado que esta clase de controlador se denomina PizzaController, este controlador controla las solicitudes a https://localhost:{PORT}/pizza.

Obtención de todas las pizzas

El primer verbo REST que hay que implementar es GET, con el que un cliente puede 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].
  • Devuelve una instancia ActionResult de tipo List<Pizza>. El tipo ActionResult es la clase base para todos los resultados de acción en ASP.NET Core.
  • 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 un parámetro 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. A continuación, puede 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 [HttpGet], tal y como indica el atributo GET.
  • Requiere que se incluya el valor del parámetro id en el segmento de URL después de pizza/. Recuerde que el atributo /pizza de nivel de controlador ha definido el patrón [Route].
  • Consulta la base de datos en busca de una pizza que coincida con el parámetro id proporcionado.

Cada instancia ActionResult usada 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 ejecución del nuevo controlador

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

dotnet run

Prueba del controlador con un archivo http

  1. Abra ContosoPizza.http.

  2. Agregue un nuevo GET para llamar al Pizza punto de conexión en el ### separador:

    GET {{ContosoPizza_HostAddress}}/pizza/
    Accept: application/json
    
    ###
    
  3. Seleccione el comando Enviar solicitud encima de esta nueva llamada GET.

    El comando anterior devuelve una lista de todas las pizzas de JSON:

    HTTP/1.1 200 OK
    Connection: close
    Content-Type: application/json; charset=utf-8
    Date: Wed, 17 Jan 2024 16:57:09 GMT
    Server: Kestrel
    Transfer-Encoding: chunked
    
    [
        {
            "id": 1,
            "name": "Classic Italian",
            "isGlutenFree": false
        },
        {
            "id": 2,
            "name": "Veggie",
            "isGlutenFree": true
        }
    ]   
    
  4. 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 {{ContosoPizza_HostAddress}}/pizza/1
    Accept: application/json
    
    ###
    

    El comando anterior devuelve Classic Italian con la salida siguiente.

    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
    }
    
  5. La API también controla situaciones en las que el elemento no existe. Llame a la API de nuevo, pero pase un parámetro id de pizza no válido con el siguiente comando:

    GET {{ContosoPizza_HostAddress}}/pizza/5
    Accept: application/json
    
    ###
    

    El comando anterior 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"
    }
    

Ahora que ha terminado de implementar los verbos GET. En la unidad siguiente, puede agregar más acciones a PizzaController para admitir operaciones CRUD en datos de pizza.

Opcional: Prueba del controlador con la línea de comandos HTTP REPL (read–eval–print loop)

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

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

    httprepl https://localhost:{PORT}
    

    Como alternativa, ejecute el siguiente comando en cualquier momento mientras HttpRepl se ejecuta:

    connect https://localhost:{PORT}
    
  3. Para ver el punto de conexión de Pizza 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 el código siguiente:

     https://localhost:{PORT}/> ls
     .                 []
     Pizza             [GET]
     WeatherForecast   [GET]
    
  4. Ejecute el comando siguiente para ir al punto de conexión Pizza:

    cd Pizza
    

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

    https://localhost:{PORT}/> cd Pizza
    /Pizza    [GET]
    
  5. Realice una solicitud GET en HttpRepl usando el comando siguiente:

    get
    

    El comando anterior 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
          }
      ]
    
  6. 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
    

    El comando anterior devuelve Classic Italian con la salida siguiente.

    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
    }
    
  7. La API también controla situaciones en las que el elemento no existe. Llame a la API de nuevo, pero pase un parámetro id de pizza no válido con el siguiente comando:

    get 5
    

    El comando anterior 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"
    }
    
  8. Vuelva al terminal dotnet en la lista desplegable de Visual Studio Code y apague la API web presionando CTRL+C en el teclado.

Ahora que ha terminado de implementar los verbos GET. En la unidad siguiente, puede agregar más acciones a PizzaController para admitir operaciones CRUD en datos de pizza.