El Controlador en ASP.NET MVC 4 (II): Action Results


Hemos visto hasta ahora que nuestras acciones (recordemos que las acciones son los métodos públicos de un controlador) deben devolver un objeto de la clase ActionResult.

En ejemplos anteriores hemos utilizado los métodos View() y Content() para generar un objeto de este tipo, pero estos no son los únicos métodos que generan un resultado de una acción (ActionResult).

Dependiendo de la respuesta que queramos dar podremos hacer uso de los siguientes métodos, con sus correspondientes ActionResults, que generan desde texto plano (como Content()) hasta la lectura de un fichero (método File()) o la redirección a una nueva URL (método Redirect()):

MÉTODO ACTION RESULT DESCRIPCIÓN
Content() ContentResult Devuelve una cadena de texto.
EmptyResult (sin respuesta)
File() FileContentResult
FilePathResult
FileStreamResult
Devuelve el contenido de un fichero.
HttpUnauthorizedResult Devuelve un error de autorización (403)
JavaScript() JavaScriptResult Devuelve un fragmento de código JavaScript a ejecutar.
Json() JsonResult Devuelve datos en formato JSON.
Redirect() RedirectResult Redirecciona a una nueva URL.
RedirectToRoute()
RedirectToAction()
RedirectToRouteResult Redirecciona a otra acción.
View()
PartialView()
ViewResult
PartialViewResult
Traspasa el control a una vista.

A continuación echaremos un vistazo por encima a los elementos más importantes de esta tabla.

Content

El método Content() genera directamente una respuesta consistente en el parámetro que le pasemos a la función. Puede ser tanto texto plano como código HTML. Por ejemplo:


        public ActionResult ContentHtml()
        {
            string contenidoHtml = "<html><head><title>Prueba de Content</title></head><body><p>Esto es una respuesta Content HTML</p></body></html>";
            return Content(contenidoHtml);
        }

La ejecución de este código mostrará el siguiente resultado (mostrando también el código fuente generado):

JavaScript y Json

Ejecutar código de cliente desde el servidor está considerado como un antipatrón de diseño y no se recomienda en absoluto. Puede que en ocasiones puntuales puede llegar a considerarse útil, pero debemos intentar evitar estos Responses todo lo que podamos.

La idea de JavaScriptResponse es la de ejecutar en el cliente, vía AJAX, funcionalidad JavaScript previamente codificada en la vista que tiene activa el cliente. Sin embargo, no profundizaremos mucho más en estos dos tipos de respuesta, sino que lo dejaremos para posteriores artículos. Sólo destacaremos que las respuestas Json codifican un conjunto de datos en un formato manejable por Javascript, lo cual nos servirá para intercambiar datos entre servidor (ASP.NET) y cliente (JavaScript) de forma que éste último pueda formatearlos de la forma adecuada.

File

Podemos hacer que el controlador devuelva directamente un fichero del tipo que indiquemos mediante el método File, que puede devolver desde un fichero físico real hasta un objeto stream (que será convertido en el objeto de descarga). Para ver cómo realizar este tipo de operaciones, podéis echar un ojo al artículo Utilizar la base de datos como repositorio de imágenes (II).

Para comenzar, añadiremos a nuestro proyecto un nuevo fichero, por ejemplo, de extensión PDF. Comencemos creando una carpeta haciendo click derecho sobre el proyecto y seleccionando la opción Add… > New Folder. Llamaremos Files a nuestro nuevo directorio.

Acto seguido haremos click sobre la recién creada carpeta y buscaremos el fichero que queremos añadir mediante click derecho > Add > Existing Item… Llamaremos a nuestro fichero prueba.pdf.

Si todo ha ido bien, nuestro fichero se encontrará en la ruta ~/Files/prueba.pdf

Ahora codificaremos la acción correspondiente. Usaremos el método Server.MapPath() para transformar la ruta relativa y devolveremos el fichero cuyo nombre (sin extensión) será pasado como parámetro.


        public ActionResult ObtenerPdf(string id)
        {
            // Obtiene el fichero especificado
            return File(Server.MapPath("~/Files/" + id + ".pdf"), "application/pdf");
        }

El resultado de invocar esta acción lo vemos a continuación:

Redirect

Una de las respuestas que nuestro controlador puede ofrecer es una redirección (Redirect). Así, si agregamos el siguiente código a nuestro Controller:


        public ActionResult RedireccionHttp(string server, string domain)
        {
            // Redirección a una URL
            return Redirect("http://" + server + "." + domain);
        }

La siguiente llamada hará que nuestra aplicación fuerce una redirección a la web server.domain, del siguiente modo:

En este caso, la petición tendría el siguiente contenido:

  • Controller: Productos
  • Action: RedireccionHttp
  • server: google
  • domain: es

Sin embargo, existe un tipo de redirección más útil que la redirección absoluta: la redirección a una acción concreta de la aplicación. Si por ejemplo quisiéramos invocar una acción desde otra, lo tendríamos tan sencillo como usar el método RedirectToAction() como respuesta, del siguiente modo:


        public ActionResult BuscarComic(string id)
        {
            // Redirección a la acción Productos/Buscar/Comics/id
            return RedirectToAction("Buscar", "Productos", new { tipoProducto = "Comics", nombreProducto = id });
        }

Lo que le estamos diciendo a ASP.NET es: “si recibes una petición del tipo /Productos/BuscarComic/id, realiza una redirección a la acción /Productos/Buscar/Comics/id”. El resultado, como podemos ver, es el siguiente:

Como observamos, la ruta mostrada en la caja de direcciones se corresponde con Buscaar/Comics/ en lugar de Productos/Buscar/Comics. ¿Por qué se produce esto? Recordemos que en artículo anterior definimos una ruta que filtraba este tipo de peticiones:


            routes.MapRoute(
                name: "Buscar",
                url: "Buscar/{tipoProducto}/{nombreProducto}",
                defaults: new { controller = "Productos", action = "Buscar", tipoProducto = UrlParameter.Optional, nombreProducto = UrlParameter.Optional });

Y con esto, nuestra introducción acerca de los tipos de respuesta que puede proporcionar un controlador estaría más o menos completa.

Como último apunte, haremos un pequeño inciso acerca de los tipos de petición que una acción puede manejar.

GET vs. POST

Es posible limitar el tipo de peticiones que una acción puede responder, limitando su ejecución a verbos concretos, como GET, HEAD o POST. Una pequeña introducción a los métodos de petición puede consultarse aquí.

Si queremos que nuestra acción responda únicamente a una petición GET, bastará con especificar el atributo [HttpGet] sobre el método, haciendo lo propio con el resto de verbos de petición. En caso de que no se realice la petición correcta, se generará un error, como si el método no existiera.

Métodos de petición

Anuncios

2 comments

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s