Ejercicio: Adición de un controlador
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
Seleccione la carpeta Controladores en Visual Studio Code y agregue un nuevo archivo denominado PizzaController.cs.
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.
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 denominaPizzaController
, este controlador controla las solicitudes ahttps://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 tipoList<Pizza>
. El tipoActionResult
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
esapplication/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 atributoGET
. - Requiere que se incluya el valor del parámetro
id
en el segmento de URL después depizza/
. 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
Abra ContosoPizza.http.
Agregue un nuevo GET para llamar al
Pizza
punto de conexión en el ### separador:GET {{ContosoPizza_HostAddress}}/pizza/ Accept: application/json ###
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 } ]
Para consultar en busca de una sola pizza, se puede realizar otra solicitud
GET
, pero pase un parámetroid
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 }
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)
Abra el terminal
httprepl
existente o uno nuevo integrado desde Visual Studio Code seleccionando Terminal>Nuevo terminal en el menú principal.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}
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]
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]
Realice una solicitud
GET
enHttpRepl
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 } ]
Para consultar en busca de una sola pizza, se puede realizar otra solicitud
GET
, pero pase un parámetroid
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 }
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" }
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.