2012-10-22 11 views
10

Ecco quello che sto cercando di fare:Passare un oggetto modello a RedirectToAction senza inquinare l'URL?

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

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return RedirectToAction("Gracias", model); 
    } 

    return View(model); 
} 

public ActionResult Gracias(ContactModel model) 
{ 
    return View(model); 
} 

Tutti e tre i metodi di azione sono nello stesso controller. Fondamentalmente, un utente digita alcuni dati nel modulo di contatto e voglio reindirli a una pagina di ringraziamento usando il loro nome nell'oggetto Modello.

Poiché il codice è, funziona, ma l'URL è passato insieme alle variabili GET. Non ideale

http://localhost:7807/Contacto/Gracias?Nombre=Sergio&Apellidos=Tapia&Correo=opiasdf&Telefono=oinqwef&Direccion=oinqef&Pais=oinqwef&Mensaje=oinqwef 

Qualche suggerimento?

risposta

24

Sembra una soluzione per TempData!

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
    // Send email using Model information. 
    TempData["model"] = model; 
    return RedirectToAction("Gracias"); 
    } 

    return View(model); 
} 

public ActionResult Gracias() 
{ 
    ContactModel model = (ContactModel)TempData["model"]; 
    return View(model); 
} 
+0

Non avevo idea che si potrebbe risparmiare tipi complessi al dizionario TempData. TIL. Grazie! – sergserg

+1

Solo fino a quando sono serializzabili !! TempData è archiviato in sessione, che consente solo oggetti/classi serializzabili. –

+2

I dati temporanei potrebbero certamente funzionare qui, ma perché non mostrare solo la vista "Gracias" direttamente da Index (dove il modello è già in ambito). Si salva anche un round trip del server che è essenzialmente un reindirizzamento inutile. –

0

La risposta più immediata è non passare l'intero modello, ma alcuni identificatore che è possibile utilizzare per recuperare il modello dal repository:

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return RedirectToAction("Gracias", model.ID); 
    } 

    return View(model); 
} 

public ActionResult Gracias(int contactID) 
{ 
    ContactModel model = new ContractRepository().GetContact(contactID); 
    return View(model); 
} 
+0

Questo non funziona come pensi. Se passo in un modello aggiornato nel metodo 'HttpPost Index()', tutte quelle modifiche sono * perse * perché tutti i valori nel metodo 'Gracias()' provengono dal database, non dall'utente. –

0

Invece di fare

return RedirectToAction("Gracias", model); 

Potresti fare

[HttpPost] 
public ActionResult Index(ContactModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // Send email using Model information. 

     return View("Gracias", model); 
    } 

    return View(model); 
} 

e rimuovere l'azione del controller Gracias. Usando sopra la vista "Gracias" verrà visualizzato con il tuo modello ContactModel.

Non vedo la necessità di avere un'azione di controllo separata se utilizza lo stesso modello ed è una parte di blocco del flusso di lavoro ex. "un POST to Index di successo risulterà sempre nella visualizzazione Gracias visualizzata"

Si potrebbe anche memorizzare il modello in TempData (che è come uno stato di sessione 1 richiesta) ma non vedo alcun punto nel farlo in la tua situazione in quanto complica semplicemente le cose

Pensieri?

+0

L'url sarebbe simile a 'http: // localhost: 7807/Contacto/Index', se questo è accettabile, questo è il modo più semplice. –

+0

Sì, non è accettabile, ecco perché non ho seguito questa strada. – sergserg

+0

Ora spero solo che qualcuno non tocchi "http: // localhost: 7807/Contacto/Gracias" in un altro momento (o se colpiscano il pulsante Indietro e la pagina non venga memorizzata nella cache) perché tornerà con una vista con campi vuoti e forse anche un'eccezione a seconda di come appare la tua vista. Considerando che potresti non volere davvero che venga visualizzato un altro URL. –

0

Non è possibile farlo facilmente senza un reindirizzamento?

Ecco quello che ho:

[HttpGet] 
    public ActionResult Contact() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Contact(EmailResponse response) 
    { 
     if(ModelState.IsValid){ 
      return View("Thanks", response); 
     } 
     else 
     { 
      return View(); 
     } 
    } 

La vista "Thanks" è fortemente tipizzato per EmailResponse

Problemi correlati