Una acción es un método dentro de un controlador que procesa una solicitud entrante y devuelve una respuesta de un tipo determinado.
El tipo de retorno de la acción determina cómo el framework va a serializar y enviar la respuesta al cliente, afectando directamente el formato, código de estado HTTP y cabeceras de la respuesta.
- Los códigos de estado HTTP comunican el resultado de la operación
- Los tipos de retorno definen la estructura de los datos devueltos
Juntos, forman el lenguaje universal que las aplicaciones cliente (como frontends o móviles) van a usar para entender como procesar nuestras respuestas.
Retornando resultados en un método de acción
El tipo de retorno más común en ASP.NET para los métodos de acción es ActionResult
y derivados,
Tipo de Retorno | Descripción |
---|---|
ActionResult | Clase base flexible para respuesta HTTP |
ActionResult<T> | Combina datos con códigos HTTP |
IActionResult | Interfaz que permite retornar cualquier tipo de resultado |
Dependiendo del tipo de resultado que queremos enviar, podemos usar varias clases y objetos. Vamos a ver las opciones más comunes.
Es útil cuando no necesitas devolver un objeto específico, sino comunicar simplemente el resultado de una operación.
[HttpPost("login")]
public ActionResult Login(UserLoginDto loginDto)
{
if (!_authService.IsValidUser(loginDto))
return Unauthorized(); // 401 si credenciales inválidas
var token = _authService.GenerateToken(loginDto.Username);
return Ok(new { token }); // 200 OK con token JWT
}
Este enfoque es muy común en endpoints que manejan autenticación, operaciones de estado, o respuestas simples sin un modelo fijo.
Cuando necesitas devolver datos junto con un estado HTTP adecuado, usamos ActionResult<T>
.
Permite devolver tanto el objeto T
como códigos de estado HTTP específicos:
[HttpGet("products/{id}")]
public ActionResult<ProductDto> GetProduct(int id)
{
var product = _productService.GetById(id);
if (product == null)
return NotFound(); // 404 Not Found
return product; // 200 OK + JSON del producto
}
Este patrón es ideal para APIs RESTful modernas que deben comunicar el éxito o fracaso de la operación junto con el contenido.
IActionResult
es la opción más flexible, y se usa típicamente cuando el tipo exacto de respuesta puede variar mucho dependiendo de la lógica del método.
Cuando necesitamos devolver diferentes tipos de objetos en un mismo endpoint, IActionResult
es la opción:
[HttpGet("report")]
public IActionResult GetReport(bool detailed)
{
if (detailed)
return Ok(_reportService.GetDetailedReport()); // 200 OK con JSON
return Content(_reportService.GetSummary(), "text/plain"); // 200 OK con texto plano
}
Este enfoque permite una lógica más dinámica, aunque con menos control de tipos.
Tipos derivados
Estos métodos son derivados de ActionResult y encapsulan tanto el contenido de la respuesta como el código de estado HTTP adecuado.
Utilizarlos permite expresar con claridad la intención del controlador y mantener la semántica HTTP correcta en nuestras APIs.
Tipo | Código HTTP | Cuándo usarlo |
---|---|---|
Ok | 200 OK | Operaciones GET exitosas |
Created | 201 Created | POST exitoso |
Accepted | 202 Accepted | Procesamiento en segundo plano |
NoContent | 204 No Content | DELETE/PUT exitosos sin datos de retorno |
return Ok(product); // HTTP 200
return Created($"/products/{id}", product); // HTTP 201
return Accepted(); // HTTP 202
return NoContent(); // HTTP 204
Tipo | Código HTTP | Cuándo usarlo |
---|---|---|
BadRequestObject | 400 Bad Request | Validaciones fallidas o datos inválidos |
Unauthorized | 401 Unauthorized | Falta de autenticación |
Forbid | 403 Forbidden | Usuario autenticado pero sin permisos |
NotFound | 404 Not Found | GET/PUT/DELETE de un recurso inexistent |
return BadRequest("Mensaje detallado"); // HTTP 400
return Unauthorized(); // HTTP 401
return Forbid(); // HTTP 403
return NotFound(); // HTTP 404
Tipo | Código HTTP | Cuándo usarlo |
---|---|---|
StatusCode | Personalizable | Casos especiales (ej: 429 Too Many Requests) |
return StatusCode(429); // Código personalizado
return File(bytes, "image/png"); // Descarga de archivos
return PhysicalFile("/path", "text/csv"); // Archivo físico
Otros tipos de retorno
Además de ActionResult
y IActionResult
, los métodos de acción en ASP.NET pueden retornar directamente valores simples.
Tipo de Retorno | Descripción |
---|---|
Retorno directo | Retorno simple que se serializa automáticamente |
View() | Retorno de vista en aplicaciones MVC |
En algunos casos, puede ser necesario retornar un valor directamente desde un método de acción.
public int Sumar(int a, int b)
{
return a + b; // Retorna el valor directamente
}
O incluso devolver directamente un objeto (como ProductDto
).
public IEnumerable<ProductDto> GetAllProducts()
{
return _productService.GetAll();
}
En este caso, ASP.NET convierte automáticamente el valor es automáticamente convertido en una respuesta HTTP (siempre retorna 200).
Evita el retorno de tipo directo, ya que perdemos la flexibilidad para representar errores u otros estados HTTP.
En aplicaciones MVC (Modelo-Vista-Controlador) es utilizado en aplicaciones web.
En este tipo de aplicaciones, para devolver una vista desde un método de acción, utilizamos el método View()
.
public View Detalles(int id)
{
var producto = ObtenerProductoPorId(id);
return View(producto); // Retorna la vista "Detalles" con un modelo de producto
}
Aquí, el método Detalles
recibe un parámetro id
y busca el producto correspondiente. Luego, retorna una vista con los detalles del producto, usando el modelo de datos producto
.
Redirecciones
En algunas situaciones, una acción no necesita devolver contenido directamente, sino redirigir al cliente a otra ubicación.
ASP.NET ofrece métodos para realizar redirecciones, ya sea hacia URLs externas o hacia otras acciones dentro de la propia aplicación.
Tipo de Retorno | Descripción |
---|---|
Redirect(string url) | Redirección a URL externa |
RedirectToAction(...) | Redirección a otro método de acción |
En algunas situaciones, es necesario redirigir al usuario a una URL específica fuera de la aplicación.
Esto se puede hacer usando Redirect
.
public ActionResult IrAGoogle()
{
return Redirect("https://www.google.com"); // Redirige al usuario a Google
}
En algunas ocasiones, es necesario redirigir la solicitud a otro método de acción, ya sea dentro del mismo controlador o a otro controlador diferente.
Esto se puede hacer mediante la instrucción RedirectToAction
.
public ActionResult CrearProducto(Product producto)
{
// Lógica para crear el producto en la base de datos
return RedirectToAction("Index"); // Redirige al método Index
}
En este ejemplo, el método CrearProducto
procesa la solicitud de crear un producto. Después de realizar la operación, redirige al usuario al método Index
.
Estas respuestas suelen usar el código de estado HTTP 302 (Found), aunque también pueden personalizarse para usar otros códigos como 301 (Moved Permanently) o 307 (Temporary Redirect).