2010-07-29 11 views
26

Tengo un controlador que maneja tres acciones que son específicas de mi problema.Redirigir a la acción y necesidad de pasar datos

La primera es la acción de edición que devuelve una vista con un formulario HTML que el usuario puede editar las propiedades en el elemento dado.

La segunda es la acción de actualización que acepta la publicación desde el navegador y actualiza la base de datos. Cuando la actualización es exitosa hacemos un redireccionamiento a la acción.

La tercera es la acción de mostrar que muestra los detalles del artículo dado. Esta acción es donde nos redireccionan después de una actualización exitosa.

El flujo es:

Mostrar -> Editar -> Actualizar (Éxito: Y -> redirigir a Show, n -> volver Editar)

Lo que quiero lograr es tener una bandera disparado cuando la actualización fue exitosa, de modo que en la próxima vista Mostrar pueda mostrar un mensaje de confirmación para el usuario. El problema es que no estoy 100% seguro de la mejor manera de llevar esos datos a través de la llamada RedirectToAction(). ¿Un pensamiento que tuve fue utilizar una cadena de consulta? Ya estamos llevando variables con la cadena de consulta para otro propósito pero parte de mi es escéptico para abusar de eso. La llamada a la redirección está a continuación.

RouteValueDictionary dict = Foo.GetRouteValues(bar); 

RedirectToAction("Show", dict); 

He leído esta pregunta también pero estoy preocupado sobre el uso de la propiedad TempData si no es necesario.

Question

Gracias por algunas sugerencias!

Respuesta

39

EDITAR: Lo sentimos, originalmente no vimos su nota acerca de no querer usar TempData.

En pocas palabras, ¿desea que su mensaje vuelva a aparecer si el cliente actualiza/recarga la página a la que se redirigió?

Si, a continuación, utiliza la cadena de consulta, algo así como:

return(RedirectToAction("Index", new { message = "hi there!" })); 

y luego o bien definir

public ActionResult Index(string message) { } 

o explícitamente sacar Request.QueryString [ "mensaje"] y pasarlo a la Vista a través de ViewData de la manera habitual. Esto también funcionará en los navegadores que no aceptan cookies de su sitio.

Si NO desea que el mensaje vuelva a aparecer, ASP.NET MVC 1.0 proporciona la colección TempData para este propósito.

valores de las propiedades TempData se almacenan en estado de sesión hasta la siguiente petición desde el mismo navegador, después de lo cual se borran - por lo que si se pone algo en TempData inmediatamente antes de regresar RedirectToAction, que estarán disponibles en el resultado de la redirección, pero se borrará inmediatamente después.

Aquí es un simple cambio a la HomeController en el proyecto de inicio ASP.NET MVC:

public ActionResult Index() { 
    ViewData["Message"] = "Welcome to ASP.NET MVC!"; 
    return View(); 
} 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Index(string submitButton) { 
    TempData["message"] = "You clicked " + submitButton; 
return(RedirectToAction("Index")); 
} 

public ActionResult About() { 
    return View(); 
} 

y la correspondiente vista/Vistas/Home/Índice.aspx debe contener algo como esto:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server"> 
    <% if (TempData["message"] != null) { %> 
    <p><%= Html.Encode(TempData["message"]) %></p> 
    <% } %> 
    <% using (Html.BeginForm()) { %> 
    <input type="submit" name="submitButton" value="Button One" /> 
    <input type="submit" name="submitButton" value="Button Two" /> 
    <% } %> 
</asp:Content> 

Se dará cuenta el mensaje TempData se muestra inmediatamente siguiente secuencia de un POST-REDIRECT-GET, pero si actualiza la página, no se mostrará de nuevo.

Tenga en cuenta que este comportamiento ha cambiado en ASP.NET MVC 2 - consulte "Paso de estado entre métodos de acción" en this article para obtener más información.

+0

Gracias por la buena explicación. Voy a echar un vistazo al artículo ya que estamos en 2.0. Mencioné en mi publicación que quería mantenerme alejado de la propiedad TempData; sin embargo, si ese es el camino defacto, tal vez no sea tan malo. Gracias de nuevo. –

+4

Esta es una pregunta anterior, pero el enlace está roto ahora :( –

+3

Enlace de trabajo moderno (ish) para ese artículo (desplácese aproximadamente hasta la mitad): http://msdn.microsoft.com/en-us/library/dd394711 (v = vs.100) .aspx – Jaxidian

4

nunca ha sido un fan de TempData bien y, además, que no quería pasar el indicador de éxito en la URL como que no quería ver

APP/Ajustes? Savesuccess = true

en la barra de URL del navegador.

Mi solución utiliza una cookie temporal:

[HttpPost] 
public ActionResult Settings(SettingsViewModel view) 
{ 
    if (ModelState.IsValid) 
    { 
     //save 
     Response.SetCookie(new HttpCookie("SettingsSaveSuccess", "")); 
     return RedirectToAction("Settings"); 
    } 
    else 
    { 
     return View(view); 
    }  
} 

y en el correspondiente control de la acción GET para la presencia de este Cookies y eliminarlo:

[HttpGet] 
public ActionResult Settings() 
{ 
    var view = new SettingsViewModel(); 
    //fetch from db and do your mapping 
    bool saveSuccess = false; 
    if (Request.Cookies["SettingsSaveSuccess"] != null) 
    { 
     Response.SetCookie(new HttpCookie("SettingsSaveSuccess", "") { Expires = DateTime.Now.AddDays(-1) }); 
     saveSuccess = true; 
    } 
    view.SaveSuccess = saveSuccess; 
    return View(view); 
} 

nb esto puede ser bastante slipperly pendiente si comienza a pasar algo más complejo que una bandera booleana

+0

Hola - ¿Cuál es el peligro si pasa la cadena que sería el mensaje de confirmación para el valor de la cookie (p. ej., su configuración guardada está bien o la configuración no está guardada)? – Bartosz

+0

@Bartosz ¿es capaz de simplemente use un booleano y luego configure el mensaje de respuesta en función de eso. Si el mensaje de respuesta podría ser más de 2 cosas, tendrá que ser pragmático al respecto, se siente un poco equivocado, es decir, si tiene varios mensajes de error, entonces debería se mostrará antes de la redirección: si su configuración no se guardó, entonces debería manejarla la declaración else en el primer fragmento de código y no debería redireccionarse – wal

Cuestiones relacionadas