Patrón PRG (Post-Redirect-Get) para ámbito Web

Buenas a todos,

Saludos nuevamente a todos, hacia tiempo que no teneia tiempo para dadicar un rato a escribir en el blog, pero este fin de semana mira por donde no he tenido que trabajar 🙂 y aprovechando las horas libres, que he hecho?? pues navegar un poquito y mira por donde que me encontré con un post en Variable not found muy interesante sobre un patrón que no se le presta mucha atención, pero que nos puede ayudar mucho en ámbito web.

En mi caso , lo utilizo en MVC ya que es lo que mas desarrollo pero tendría la misma validez en ASP.net normal o incluso bajo otras tecnologías web.

Bueno, pasemos a lo importante :

Escenario – problema:

Un escenario muy habitual es que en un proyecto estemos desarrollando formularios o vistas que reciban mediante http-post diferentes campos que una vez tratados y validados desencadenen una modificación en nuestro repositorio de persistencia.

Hasta aquí todo normal, el problema grave es cuando al usuario decide “no sabemos el motivo” utilizar el maldito botón F5 o simplemente actualizar la página, esto provocaría dos inconvenientes:

  1. Nos saltaría una alerta realizada por el navegador informando que estamos intentando reenviar todos los datos del formulario, cosa que un usuario básico lo más probable no entienda y le asuste.
  2. Esta sería el problema importante, ya que al actualizar realmente lo que estamos haciendo es volver a ejecutar toda la lógica asociada al envío de datos.

¿Que hacemos para solucionar este inconveniente?

Esta claro que podríamos realizar toda las comprobaciones necesarias para no duplicar datos ni nada por el estilo, pero ¿podríamos encontrar alguna solución más sencilla y eficaz?

Solución , Post-Redirect-Get

Este patrón proporciona una solución muy sencilla que se basa en que cada método action que se consume mediante una petición post tiene que retornar una dirección a otro método action que será el encargado de retornar la vista con el resultado y no retornar una vista directamente.

Veamos un poco de código:

@using (Html.BeginForm())
{
    @Html.TextBox("ProductName")
    <input type="submit" value="send post" />
}

El método action que implementaríamos normalmente sería algo como esto:

[HttpPost]
        public ActionResult Index(string ProductName)
        {
            // Procesar resultados.
            if (Repository.UpdateName(ProductName)) return View();
            else return View("Error");

        }

Como podemos ver, el método action es ficticio y en sí, no tiene sentido, pero me sirve como ejemplo para situarnos en la diferencia entre una implementación normal y una bajo el patrón PRG.

Ahora el método action bajo PRG

 [HttpPost]
        public ActionResult Index(string ProductName)
        {
            // Procesar resultados.
            var id = "Identificador resultante";

            return RedirectToAction("View", new { id = id });
        }

Como vemos en la segunda implementación esta action no retorna directamente la vista en concreto, sino que procesa la petición principal , guarda en BD el producto o lo que tenga que hacer y como último redirecciona a otra vista que será la encargada de devolver el feedback al usuario final.

Como observamos , en concreto se redirecciona con un parámetro  de esta manera la vista final de feedback sabrá que mensaje mostrar o que operativa realizar.

Bajo este escenario, cuando el usuario llegue a la vista final donde recibirá el mensaje o la pantalla mostrando como queda el producto después de la modificación, ya dará igual que actualice la página o utilice F5, porque lo único que refrescara sera esa página que no tiene ninguna lógica asociada más que la de realizar un feedback.

 

Bueno y hasta aquí este pequeño post.

 

Como siempre espero que os resulte interesante, Saludos!!

Anuncios

Html Helpers ( Encapsulación )

Voy a comenzar esta entrada explicando un poco el concepto de los Helpers en ASP.NET MVC.

Los Helpers son simplemente bloques de código encapsulados para facilitar la creación y configuración de controles. Estos nos aportan también la posibilidad de la reutilización en cualquiera de nuestras vistas.

Razor, nos ofrece unos cuantos Helpers muy interesantes y que nos facilitan mucho la creación de controles típicos, pero hoy no nos centraremos en los ya definidos por Razor sino, en la creación de Helpers personalizados.

Veamos cómo crear uno:

“Antes de nada comentar que vamos a crear nuestro helper de forma global para que sea accesible desde cualquier vista, de esta forma damos mucho más sentido al principio de reutilización de estas clases.”

En el siguiente ejemplo vamos a crear un Helper para listar nuestros productos, de tal manera que en cualquier página que necesitemos realizar un listado de productos únicamente tendremos que consumirlo y tendremos como respuesta una lista ya maquetada.

@helper ListadoProductos(List<Product> Productos) {

<ul id=”LPruductos”>

@foreach( var itm in Productos) {

<li>@itm.Nombre ($@itm.Precio)</li>

}

</ul>

}

Este código lo vamos a realizar en un archivo con extensión .cshtml lo llamaremos Helpers.cshtml y lo vamos a guardar en la carpeta App_Code de nuestro proyecto, de esta
manera lo vamos a globalizar .

captura1

De esta manera, cuando queramos utilizar nuestro helper únicamente deberemos llamar a nuestros métodos de la siguiente manera.

<div>

<p>Listado de nuestros productos</p>

@Helpers.ListadoProductos(Model.Productos)

</div>

Conclusión 

Bueno, hemos visto como crear un helper aprovechando la sintaxis que nos proporciona Razor y podemos ver lo interesante que nos puede resultar para realizar lógicas globales y reutilizables .

Espero que os haya parecido interesante y de ayuda.

Ciao!