¿Te gustaría aprender ASP.NET Core Empresarial?
Tenemos lo que necesitas .¡Haz clic aquí!
Este tutorial enseña los conceptos básicos de la creación de una API web con ASP.NET Core. En este tutorial, aprenderás a:
– Crear un proyecto de API web.
– Agregar una clase de modelo y un contexto de base de datos.
– Andamia un controlador con métodos CRUD.
– Configurar el enrutamiento, las rutas de URL y los valores de retorno.
– Llamar a la API web con Postman.
Al final, tiene una API web que puede administrar elementos «pendientes» almacenados en una base de datos.
Descripción general
Este tutorial crea la siguiente API:
API | Descripción | Cuerpo de la solicitud | Cuerpo de respuesta |
---|---|---|---|
GET /api/TodoItems | Obtener todos los elementos pendientes | Ninguno | Matriz de tareas pendientes |
GET /api/TodoItems/{id} | Obtener un artículo por ID | Ninguno | Elemento de tarea |
POST /api/TodoItems | Agregar un artículo nuevo | Elemento de tarea | Elemento de tarea |
PUT /api/TodoItems/{id} | Actualizar un artículo existente | Elemento de tarea | Ninguno |
DELETE /api/TodoItems/{id} | Eliminar un elemento | Ninguno | Ninguno |
El siguiente diagrama muestra el diseño de la aplicación.
Prerrequisitos
- Visual Studio 2019 16.8 o posterior con ASP.NET y la carga de trabajo de desarrollo web
- .NET 5.0 SDK o posterior
Crea un proyecto web
- En el menú Archivo , seleccione Nuevo > Proyecto .
- Seleccione la plantilla de API web ASP.NET Core y haga clic en Siguiente .
- Nombra el proyecto TodoApi y haz clic en Crear .
- En el cuadro de diálogo Crear una nueva aplicación web ASP.NET Core , confirme que .NET Core y ASP.NET Core 5.0 están seleccionados. Seleccione la plantilla de API y haga clic en Crear .
Prueba el proyecto
La plantilla del proyecto crea una WeatherForecast
API compatible con Swagger .
Presione Ctrl + F5 para ejecutar sin el depurador.
Visual Studio muestra el siguiente cuadro de diálogo:
Seleccione Sí si confía en el certificado SSL de IIS Express.
Aparece el siguiente cuadro de diálogo:
Seleccione Sí si acepta confiar en el certificado de desarrollo.
Para obtener información sobre cómo confiar en el navegador Firefox, consulte Error de certificado SEC_ERROR_INADEQUATE_KEY_USAGE de Firefox .
Lanzamiento de Visual Studio:
- El servidor web IIS Express.
- El navegador predeterminado y navega hacia
https://localhost:<port>/swagger/index.html
, donde<port>
es un número de puerto elegido al azar.
Se /swagger/index.html
muestra la página Swagger . Seleccione OBTENER > Pruébelo > Ejecutar . La página muestra:
- El comando Curl para probar la API WeatherForecast.
- La URL para probar la API WeatherForecast.
- El código de respuesta, el cuerpo y los encabezados.
- Un cuadro de lista desplegable con tipos de medios y el valor y el esquema de ejemplo.
Si la página Swagger no aparece, vea este problema de GitHub .
Swagger se utiliza para generar documentación útil y páginas de ayuda para API web. Este tutorial se centra en la creación de una API web. Para obtener más información sobre Swagger, consulte la documentación de la API web de ASP.NET Core con Swagger / OpenAPI .
Copie y pegue la URL de solicitud en el navegador: https://localhost:<port>/WeatherForecast
Se devuelve JSON similar al siguiente:JSONDupdo
[
{
"date": "2019-07-16T19:04:05.7257911-06:00",
"temperatureC": 52,
"temperatureF": 125,
"summary": "Mild"
},
{
"date": "2019-07-17T19:04:05.7258461-06:00",
"temperatureC": 36,
"temperatureF": 96,
"summary": "Warm"
},
{
"date": "2019-07-18T19:04:05.7258467-06:00",
"temperatureC": 39,
"temperatureF": 102,
"summary": "Cool"
},
{
"date": "2019-07-19T19:04:05.7258471-06:00",
"temperatureC": 10,
"temperatureF": 49,
"summary": "Bracing"
},
{
"date": "2019-07-20T19:04:05.7258474-06:00",
"temperatureC": -1,
"temperatureF": 31,
"summary": "Chilly"
}
]
Actualiza launchUrl
En Propiedades \ launchSettings.json , actualice launchUrl
de "swagger"
a "api/TodoItems"
:JSONDupdo
"launchUrl": "api/TodoItems",
Debido a que Swagger se ha eliminado, el marcado anterior cambia la URL que se inicia al método GET del controlador agregado en las siguientes secciones.
Agregar una clase de modelo
Un modelo es un conjunto de clases que representan los datos que administra la aplicación. El modelo de esta aplicación es de una sola TodoItem
clase.
- En el Explorador de soluciones , haga clic con el botón derecho en el proyecto. Seleccione Agregar > Nueva carpeta . Nombra la carpeta Modelos .
- Haga clic con el botón derecho en la carpeta Modelos y seleccione Agregar > Clase . Nombre la clase TodoItem y seleccione Agregar .
- Reemplace el código de la plantilla con lo siguiente:
C#Dupdo
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
}
La Id
propiedad funciona como clave única en una base de datos relacional.
Las clases de modelo pueden ir a cualquier parte del proyecto, pero la carpeta Modelos se usa por convención.
Agregar un contexto de base de datos
El contexto de la base de datos es la clase principal que coordina la funcionalidad de Entity Framework para un modelo de datos. Esta clase se crea derivando de la clase Microsoft.EntityFrameworkCore.DbContext .
Agregar paquetes NuGet
- En el menú Herramientas , seleccione Administrador de paquetes NuGet> Administrar paquetes NuGet para la solución .
- Seleccione la pestaña Examinar y luego ingrese
Microsoft.EntityFrameworkCore.InMemory
en el cuadro de búsqueda. - Seleccione
Microsoft.EntityFrameworkCore.InMemory
en el panel izquierdo. - Seleccione la casilla de verificación Proyecto en el panel derecho y luego seleccione Instalar .
Agregar el contexto de la base de datos de TodoContext
- Haga clic con el botón derecho en la carpeta Modelos y seleccione Agregar > Clase . Nombra la clase TodoContext y haz clic en Agregar .
- Ingrese el siguiente código:C#Dupdo
using Microsoft.EntityFrameworkCore; namespace TodoApi.Models { public class TodoContext : DbContext { public TodoContext(DbContextOptions<TodoContext> options) : base(options) { } public DbSet<TodoItem> TodoItems { get; set; } } }
Registrar el contexto de la base de datos
En ASP.NET Core, los servicios como el contexto de base de datos deben registrarse con el contenedor de inyección de dependencia (DI) . El contenedor proporciona el servicio a los controladores.
Actualice Startup.cs con el siguiente código:C#Dupdo
// Unused usings removed
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using TodoApi.Models;
namespace TodoApi
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TodoContext>(opt =>
opt.UseInMemoryDatabase("TodoList"));
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
El código anterior:
- Elimina las llamadas Swagger.
- Elimina las
using
declaraciones no utilizadas . - Agrega el contexto de la base de datos al contenedor DI.
- Especifica que el contexto de la base de datos utilizará una base de datos en memoria.
Andamio de un controlador
- Haga clic con el botón derecho en la carpeta Controladores .
- Seleccione Agregar > Nuevo elemento con andamio .
- Seleccione API Controller con acciones, usando Entity Framework , y luego seleccione Agregar .
- En el Agregar controlador de API con acciones, usando el cuadro de diálogo Entity Framework :
- Seleccione TodoItem (TodoApi.Models) en la clase Model .
- Seleccione TodoContext (TodoApi.Models) en la clase de contexto de datos .
- Seleccione Agregar .
El código generado:
- Marca la clase con el
[ApiController]
atributo. Este atributo indica que el controlador responde a las solicitudes de la API web. Para obtener información sobre los comportamientos específicos que habilita el atributo, consulte Crear API web con ASP.NET Core . - Utiliza DI para inyectar el contexto de la base de datos (
TodoContext
) en el controlador. El contexto de la base de datos se utiliza en cada uno de los métodos CRUD en el controlador.
Las plantillas ASP.NET Core para:
- Los controladores con vistas se incluyen
[action]
en la plantilla de ruta. - Los controladores de API no se incluyen
[action]
en la plantilla de ruta.
Cuando el [action]
token no está en la plantilla de ruta, el nombre de la acción se excluye de la ruta. Es decir, el nombre del método asociado a la acción no se usa en la ruta coincidente.
Actualizar el método de creación de PostTodoItem
Actualice la declaración de retorno en el PostTodoItem
para usar el operador nameof :C#Dupdo
// POST: api/TodoItems
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
//return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
return CreatedAtAction(nameof(GetTodoItem), new { id = todoItem.Id }, todoItem);
}
El código anterior es un método HTTP POST, como lo indica el [HttpPost]
atributo. El método obtiene el valor de la tarea pendiente del cuerpo de la solicitud HTTP.
Para obtener más información, consulte Enrutamiento de atributos con atributos Http [Verb] .
El método CreatedAtAction :
- Devuelve un código de estado HTTP 201 si tiene éxito. HTTP 201 es la respuesta estándar para un método HTTP POST que crea un nuevo recurso en el servidor.
- Agrega un encabezado de ubicación a la respuesta. El
Location
encabezado especifica el URI de la tarea pendiente recién creada. Para obtener más información, consulte 10.2.2 201 Creado . - Hace referencia a la
GetTodoItem
acción para crear elLocation
URI del encabezado. Lanameof
palabra clave C # se usa para evitar codificar el nombre de la acción en laCreatedAtAction
llamada.
Instalar cartero
Este tutorial utiliza Postman para probar la API web.
- Instalar cartero
- Inicie la aplicación web.
- Inicie Postman.
- Desactivar la verificación del certificado SSL
- En Archivo > Configuración ( pestaña General ), desactive la verificación del certificado SSL . AdvertenciaVuelva a habilitar la verificación del certificado SSL después de probar el controlador.
Probar PostTodoItem con Postman
- Crea una nueva solicitud.
- Establezca el método HTTP en
POST
. - Establezca el URI en
https://localhost:<port>/api/TodoItems
. Por ejemplohttps://localhost:5001/api/TodoItems
,. - Seleccione la pestaña Cuerpo .
- Seleccione la prima botón de radio.
- Establezca el tipo en JSON (aplicación / json) .
- En el cuerpo de la solicitud, ingrese JSON para una tarea pendiente:JSONDupdo
{ "name":"walk dog", "isComplete":true }
- Seleccione Enviar .
Prueba el URI del encabezado de ubicación
El URI del encabezado de ubicación se puede probar en el navegador. Copie y pegue el URI del encabezado de la ubicación en el navegador.
Para probar en Postman:
- Seleccione la pestaña Encabezados en el panel Respuesta .
- Copie el valor del encabezado de la ubicación :
- Establezca el método HTTP en
GET
. - Establezca el URI en
https://localhost:<port>/api/TodoItems/1
. Por ejemplohttps://localhost:5001/api/TodoItems/1
,. - Seleccione Enviar .
Examine los métodos GET
Se implementan dos puntos finales GET:
GET /api/TodoItems
GET /api/TodoItems/{id}
Pruebe la aplicación llamando a los dos puntos finales desde un navegador o Postman. Por ejemplo:
https://localhost:5001/api/TodoItems
https://localhost:5001/api/TodoItems/1
La llamada a GetTodoItems
: produce una respuesta similar a la siguiente :JSONDupdo
[
{
"id": 1,
"name": "Item1",
"isComplete": false
}
]
Prueba Get with Postman
- Crea una nueva solicitud.
- Establezca el método HTTP en GET .
- Establezca el URI de la solicitud en
https://localhost:<port>/api/TodoItems
. Por ejemplohttps://localhost:5001/api/TodoItems
,. - Establezca la vista de dos paneles en Postman.
- Seleccione Enviar .
Esta aplicación utiliza una base de datos en memoria. Si la aplicación se detiene e inicia, la solicitud GET anterior no devolverá ningún dato. Si no se devuelven datos, POST los datos a la aplicación.
Rutas de enrutamiento y URL
El [HttpGet]
atributo denota un método que responde a una solicitud HTTP GET. La ruta URL para cada método se construye de la siguiente manera:
- Comience con la cadena de plantilla en el
Route
atributo del controlador :C#Dupdo[Route("api/[controller]")] [ApiController] public class TodoItemsController : ControllerBase { private readonly TodoContext _context; public TodoItemsController(TodoContext context) { _context = context; }
- Reemplácelo
[controller]
con el nombre del controlador, que por convención es el nombre de la clase del controlador menos el sufijo «Controlador». Para esta muestra, el nombre de la clase del controlador es TodoItems Controller, por lo que el nombre del controlador es «TodoItems». El enrutamiento de ASP.NET Core no distingue entre mayúsculas y minúsculas. - Si el
[HttpGet]
atributo tiene una plantilla de ruta (por ejemplo,[HttpGet("products")]
), agréguela a la ruta. Esta muestra no usa una plantilla. Para obtener más información, consulte Enrutamiento de atributos con atributos Http [Verb] .
En el siguiente GetTodoItem
método, "{id}"
es una variable de marcador de posición para el identificador único de la tarea pendiente. Cuando GetTodoItem
se invoca, el valor de "{id}"
en la URL se proporciona al método en su id
parámetro.C#Dupdo
// GET: api/TodoItems/5
[HttpGet("{id}")]
public async Task<ActionResult<TodoItem>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return todoItem;
}
Valores devueltos
El tipo de retorno de los métodos GetTodoItems
y GetTodoItem
es el tipo ActionResult <T> . ASP.NET Core serializa automáticamente el objeto en JSON y escribe el JSON en el cuerpo del mensaje de respuesta. El código de respuesta para este tipo de retorno es 200 OK , asumiendo que no hay excepciones no controladas. Las excepciones no controladas se traducen en errores 5xx.
ActionResult
Los tipos de retorno pueden representar una amplia gama de códigos de estado HTTP. Por ejemplo, GetTodoItem
puede devolver dos valores de estado diferentes:
- Si ningún elemento coincide con el ID solicitado, el método devuelve un código de error NotFound de estado 404 .
- De lo contrario, el método devuelve 200 con un cuerpo de respuesta JSON. La devolución
item
da como resultado una respuesta HTTP 200.
El método PutTodoItem
Examine el PutTodoItem
método:C#Dupdo
// PUT: api/TodoItems/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTodoItem(long id, TodoItem todoItem)
{
if (id != todoItem.Id)
{
return BadRequest();
}
_context.Entry(todoItem).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!TodoItemExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
PutTodoItem
es similar a PostTodoItem
, excepto que usa HTTP PUT. La respuesta es 204 (Sin contenido) . Según la especificación HTTP, una solicitud PUT requiere que el cliente envíe toda la entidad actualizada, no solo los cambios. Para admitir actualizaciones parciales, use HTTP PATCH .
Si recibe una llamada de error PutTodoItem
, llame GET
para asegurarse de que haya un elemento en la base de datos.
Pruebe el método PutTodoItem
Esta muestra usa una base de datos en memoria que debe inicializarse cada vez que se inicia la aplicación. Debe haber un elemento en la base de datos antes de realizar una llamada PUT. Llame a GET para asegurarse de que haya un elemento en la base de datos antes de realizar una llamada PUT.
Actualice la tarea pendiente que tiene Id = 1 y establezca su nombre en "feed fish"
:JSONDupdo
{
"Id":1,
"name":"feed fish",
"isComplete":true
}
La siguiente imagen muestra la actualización de Postman:
El método DeleteTodoItem
Examine el DeleteTodoItem
método:C#Dupdo
// DELETE: api/TodoItems/5
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
Pruebe el método DeleteTodoItem
Utilice Postman para eliminar una tarea pendiente:
- Establezca el método en
DELETE
. - Establezca el URI del objeto a eliminar (por ejemplo
https://localhost:5001/api/TodoItems/1
). - Seleccione Enviar .
Evitar la publicación excesiva
Actualmente, la aplicación de muestra expone todo el TodoItem
objeto. Las aplicaciones de producción suelen limitar los datos que se ingresan y devuelven mediante un subconjunto del modelo. Hay varias razones detrás de esto y la seguridad es una de las principales. El subconjunto de un modelo generalmente se denomina Objeto de transferencia de datos (DTO), modelo de entrada o modelo de vista. En este artículo se utiliza DTO .
Un DTO se puede utilizar para:
- Evite la publicación excesiva.
- Ocultar propiedades que los clientes no deben ver.
- Omita algunas propiedades para reducir el tamaño de la carga útil.
- Aplanar gráficos de objetos que contienen objetos anidados. Los gráficos de objetos aplanados pueden ser más convenientes para los clientes.
Para demostrar el enfoque DTO, actualice la TodoItem
clase para incluir un campo secreto:C#Dupdo
namespace TodoApi.Models
{
public class TodoItem
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
public string Secret { get; set; }
}
}
El campo secreto debe estar oculto para esta aplicación, pero una aplicación administrativa podría optar por exponerlo.
Verifique que pueda publicar y obtener el campo secreto.
Cree un modelo DTO:C#Dupdo
public class TodoItemDTO
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsComplete { get; set; }
}
Actualice el TodoItemsController
para usar TodoItemDTO
:C#Dupdo
// GET: api/TodoItems
[HttpGet]
public async Task<ActionResult<IEnumerable<TodoItemDTO>>> GetTodoItems()
{
return await _context.TodoItems
.Select(x => ItemToDTO(x))
.ToListAsync();
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
return ItemToDTO(todoItem);
}
[HttpPut("{id}")]
public async Task<IActionResult> UpdateTodoItem(long id, TodoItemDTO todoItemDTO)
{
if (id != todoItemDTO.Id)
{
return BadRequest();
}
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
todoItem.Name = todoItemDTO.Name;
todoItem.IsComplete = todoItemDTO.IsComplete;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException) when (!TodoItemExists(id))
{
return NotFound();
}
return NoContent();
}
[HttpPost]
public async Task<ActionResult<TodoItemDTO>> CreateTodoItem(TodoItemDTO todoItemDTO)
{
var todoItem = new TodoItem
{
IsComplete = todoItemDTO.IsComplete,
Name = todoItemDTO.Name
};
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
return CreatedAtAction(
nameof(GetTodoItem),
new { id = todoItem.Id },
ItemToDTO(todoItem));
}
[HttpDelete("{id}")]
public async Task<IActionResult> DeleteTodoItem(long id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null)
{
return NotFound();
}
_context.TodoItems.Remove(todoItem);
await _context.SaveChangesAsync();
return NoContent();
}
private bool TodoItemExists(long id) =>
_context.TodoItems.Any(e => e.Id == id);
private static TodoItemDTO ItemToDTO(TodoItem todoItem) =>
new TodoItemDTO
{
Id = todoItem.Id,
Name = todoItem.Name,
IsComplete = todoItem.IsComplete
};
Verifique que no pueda publicar ni obtener el campo secreto.
Llame a la API web con JavaScript
Agregar soporte de autenticación a una API web 2.1
ASP.NET Core Identity agrega la funcionalidad de inicio de sesión de la interfaz de usuario (UI) a las aplicaciones web ASP.NET Core. Para proteger las API web y las SPA, utilice uno de los siguientes:
IdentityServer4 es un marco OpenID Connect y OAuth 2.0 para ASP.NET Core. IdentityServer4 habilita las siguientes características de seguridad:
- Autenticación como servicio (AaaS)
- Inicio y cierre de sesión único (SSO) en varios tipos de aplicaciones
- Control de acceso para API
- Puerta de enlace de la federación
Para obtener más información, consulte Bienvenido a IdentityServer4 .
Te esperamos en los siguientes artículos en donde hablaremos mas acerca de estos temas, los cuales hoy en día son de vital importancia en el mundo de la tecnología.
¿Te gustaría aprender ASP.NET Core Empresarial?
Tenemos lo que necesitas .¡Haz clic aquí!