Come RedirectToAction in ASP.NET MVC senza perdere i dati della richiesta


123

Utilizzando ASP.NET MVC esistono situazioni (come l'invio di moduli) che potrebbero richiedere un file RedirectToAction.

Una di queste situazioni è quando si verificano errori di convalida dopo l'invio di un modulo e si deve reindirizzare nuovamente al modulo, ma si desidera che l'URL rifletta l'URL del modulo, non la pagina di azione a cui viene inviato.

Poiché richiedo che il modulo contenga i POSTdati originariamente modificati , per comodità dell'utente e per scopi di convalida, come posso passare i dati attraverso il RedirectToAction()? Se utilizzo il parametro viewData, i miei POSTparametri verranno modificati in GETparametri.


Ecco una domanda simile (sullo stesso argomento), ma diversa da questa. Ad ogni modo, potrebbe ancora interessare chi è interessato a questa domanda: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann

Perché non restituisci la stessa visualizzazione se c'è un errore? RedirectToAction viene solitamente chiamato se il modello è valido o mi manca qualcosa ?!
niico

Risposte:


81

La soluzione è utilizzare la proprietà TempData per archiviare i componenti Request desiderati.

Per esempio:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Quindi nella tua azione "Modulo" puoi:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}

1
RedirectToAction (a => a.Form ()) non si compila per me usando MVCv2, stai usando MVCv3?
ChrisAnnODell

1
Questo era pre-MVC1 (2008). I lambda sono stati rimossi ad un certo punto, credo (esiste un progetto codeplex MVCContrib che li reintroduce, anche se puoi anche usare il loro attributo helper in quella fase: stackoverflow.com/questions/1936/… ). In mvc2 dovresti essere in grado di andare su RedirectToAction ("Form"), cioè name come una stringa, anche se ricordo vagamente che MVC 2 o 3 ha introdotto un attributo helper simile a quello in MVCContrib se vuoi andare a cercare.
Matt Mitchell

37

Tieni presente che TempData archivia la raccolta di moduli nella sessione. Se non ti piace questo comportamento, puoi implementare la nuova interfaccia ITempDataProvider e utilizzare qualche altro meccanismo per archiviare i dati temporanei. Non lo farei a meno che tu non sappia per certo (tramite misurazione e profilazione) che l'uso dello stato di sessione ti fa male.


13

Dai un'occhiata a MVCContrib , puoi farlo:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}

8

C'è un altro modo che evita tempdata. Il modello che mi piace implica la creazione di 1 azione sia per il rendering originale che per il riesecuzione del modulo non valido. Funziona in questo modo:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

Questo è lo schema più o meno. Un po 'di pseudonimo. Con questo puoi creare 1 vista per gestire il rendering del modulo, rivisualizzare i valori (poiché il modulo verrà riempito con i valori precedenti) e mostrare i messaggi di errore.

Quando la registrazione a questa azione, se valida, trasferisce il controllo a un'altra azione.

Sto cercando di semplificare questo modello nel framework di convalida .net mentre sviluppiamo il supporto per MVC.


Uso anche TempData, il problema a quanto ho capito, con la tua soluzione Deeno è che se l'utente aggiornasse la pagina dopo aver inserito dati non validi riceverebbe una conferma "Desideri inviare nuovamente i dati del modulo". L'uso della soluzione TempData come dice MattMitchell elimina questo problema.
user10479

Freddo. Sembra che qualcuno abbia notato questa idea di base anche con l'anteprima 5.
Matt Mitchell

2

Se vuoi passare i dati all'azione reindirizzata, il metodo che potresti usare è:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);

0

TempData è la soluzione che mantiene i dati dall'azione all'azione.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.