Pregunta

Un problema con el que me enfrento una y otra vez es el manejo de la redirección a la página anterior después de que un usuario ejecuta alguna acción como hacer clic en el enlace 'Volver a...' o guardar el registro que está editando.

Anteriormente, cuando necesitaba saber a qué página regresar, proporcionaba una returnURL parámetro a mi vista actual.

http://blah.com/account/edit/1?returnURL="account/index"

Esta no es una forma muy clara de manejar esta situación, ya que a veces la URL de retorno contiene parámetros como cadenas de búsqueda, etc., que deben incluirse en la URL.

http://blah.com/account/edit/1?returnURL="account/index?search="searchTerm""

Además, esto crea un problema cuando un usuario puede avanzar otra página antes de regresar a la página con el returnURL porque tienes que pasar el returnURL a través de todas las páginas visitadas.

Simplemente llamar a la función Atrás del navegador tampoco es suficiente, porque es posible que desee que la página se actualice, p.para mostrar las ediciones que acaba de guardar en la página anterior.

Entonces mi pregunta es: ¿alguien ha encontrado una manera inteligente de manejar este tipo de situación, específicamente en un entorno MVC?

Nota:Estoy usando ASP .NET MVC, así que, si es posible, me gustaría obtener respuestas al respecto; sin embargo, cualquier idea es bienvenida.

¿Fue útil?

Solución

¿Qué tiene de malo configurar una cookie o usar una variable de sesión?La única razón por la que no lo haría es si no controla la página que lo llama, en cuyo caso sus únicas opciones son cadenas de consulta, valores de publicación o referencia.

Otros consejos

Pensé que podría agregar mi respuesta a la pregunta para ver si otros piensan que es una buena idea.

Simplemente lo estoy pasando al controlador usando TempViewData:

@{
   TempData["returnURL"] = Request.Url.AbsoluteUri;
}

y luego accediendo a él de manera similar a esta (en mi versión real verifico que la clave está en TempData y que returnURL es una URL real):

return Redirect(TempData["returnURL"].ToString());

Si debe continuar después del primer cambio de página (es decir, página de búsqueda -> Editar página -> Editar página de sección), lo agregaré nuevamente

TempData["returnURL"] = TempData["returnURL"];

Consulte la publicación de mi blog: Usocookies para controlar la página de retorno después de iniciar sesión en asp.net mvc 3

Tal como lo mencionó @Mystere Man, puede usar una cookie o una sesión para ello.Fui por las galletas cuando tuve una situación similar hace un tiempo.

Intente registrar una nueva ruta cuya URL sea /{controller}/{action}/{id}/returnurl/{*url} y luego usar un RedirectToAction en la acción que acepta URL como parámetro

Request.UrlReferrer.AbsoluteUri

aunque todavía diría que no debería crear su propio botón "Atrás".

Utilice un interceptor o un aspecto:

  1. Intercepte cada solicitud de alguna manera (p. ej., un aspecto de código de etiqueta general) y guarde la URL solicitada en la sesión, sobrescribiéndola cada vez
  2. En su capa de vista, acceda a ese objeto de sesión según sea necesario, en su caso para el vínculo de retroceso.

Este tipo de diseño le permite tener siempre disponible la solicitud más reciente si desea utilizarla. Aquí hay unejemplo para escribir un aspecto / interceptor en .NET.Además, PostSharp es un proyecto de aspecto .NET.

En la actualidad, se me ha escapado un método rápido y sucio ... así que estoy usando un método práctico.

A nivel conceptual, la "capacidad de retroceso" de una página debe estar determinada por la página en la que se encuentra actualmente. La vista puede inferir esto (en la mayoría de los casos) si los parámetros capturados en el controlador se le pasan a través del modelo de vista.

<×Ejemplo:

Habiendo visitado Foo, voy a Bar para ver algunas cosas, y el botón de retroceso debería volver a Foo.

Controlador

public ActionResult Foo(string fooId) // using a string for your Id, good idea; Encryption, even better.
{
    FooModel model = new FooModel() { fooId = fooId }; // property is passed to the Model - important.
    model.Fill();
    return View("FooView", model);
}

public ActionResult Bar(string fooId, string barId)
{
    BarModel model = new BarModel() { fooId = fooId; barId = barId };
    model.Fill()
    return View("BarView", model)
}

VerModelos

public class FooModel
{
    public string fooId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

public class BarModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        // Get info from Repository.
    }
}

Ver (parcial) // No pun intended... or maybe it was. :)

Su BarView ahora puede interpretar desde su modelo a dónde necesita regresar (usando fooId).

En su BarView (usando la sintaxis MVC2):

<a href="<%= string.Format("/Foo?fooId={0}", Model.fooId) %>">Back</a>

También puede utilizar Html.ActionLink.

<×Alternativamente:

Puede heredar sus ViewModels de un BaseViewModel, que puede tener una propiedad protegida returnURL. Configure esto donde sea necesario.

<×Ejemplo:

En su ViewModel:

public class BarModel : BaseViewModel
{
    public string fooId { get; set; }
    public string barId { get; set; }

    public void Fill()
    {
        returnURL = string.Format("/Foo?fooId={0}", fooId)
        // Get info from Repository.
    }
}

A la vista:

<a href="<%=returnURL %>">Back</a>

¿Esto se manejaría mejor con acciones parciales que se muestran sin salir de la página y usando JQuery para crear un flujo de trabajo de diálogo / asistente?

Entonces solo necesita reaccionar al botón 'Finalizar' en el diálogo para actualizar la vista original.

Para la parte de su pregunta sobre "guardar el registro que están editando", creo que el patrón post-redirect-get (PGR) se aplicaría a usted.

Este podría ser un buen lugar para leer sobre él si no está familiarizado con él.

  1. Codifique returnUrl utilizando Url.Encode(returnUrl) para incluirlo en la URL.
  2. Cuando esté listo para redireccionar, use Url.Decode(returnUrl) y use el valor para el redireccionamiento real.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top