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!!