2012-06-26 17 views
40

Nello RedirectToAction di seguito, vorrei passare un viewmodel. Come posso passare il modello al reindirizzamento?Come includere un modello con RedirectToAction?

Ho impostato un punto di interruzione per verificare i valori del modello per verificare che il modello sia stato creato correttamente. È corretto ma la vista risultante non contiene i valori trovati nelle proprietà del modello.

// 
// model created up here... 
// 
return RedirectToAction("actionName", "controllerName", model); 

ASP.NET MVC 4 RC

+2

ho preso un approccio semplice come questo => Return ("ActionName ", modello); – xameeramir

risposta

66

RedirectToAction restituisce una risposta 302 al browser del client e quindi il browser farà una nuova richiesta GET per l'URL nella posizione valore dell'intestazione della risposta è venuto alla browser.

Se si sta tentando di passare un semplice modello di visualizzazione lean-flat al secondo metodo di azione, è possibile utilizzare this overload del metodo RedirectToAction.

protected internal RedirectToRouteResult RedirectToAction(
    string actionName, 
    string controllerName, 
    object routeValues 
) 

Il RedirectToAction convertirà l'oggetto passato (routeValues) in una stringa di query e aggiungere che all'URL (generato dai primi 2 parametri siamo passati) e incorporerà l'URL risultante nel location nell'intestazione della risposta .

Supponiamo che il modello di vista è come questo

public class StoreVm 
{ 
    public int StoreId { get; set; } 
    public string Name { get; set; } 
    public string Code { set; get; } 
} 

E voi nel vostro primo metodo di azione, è possibile passare un oggetto di questo al metodo RedirectToAction come questo

var m = new Store { StoreId =101, Name = "Kroger", Code = "KRO"}; 
return RedirectToAction("Details","Store", m); 

Questo codice inviare una risposta 302 al browser con il valore dell'intestazione di posizione come

Store/Details?StoreId=101&Name=Kroger&Code=KRO 

Supponendo che il parametro del metodo di azione Details sia di tipo StoreVm, i valori param di querystring verranno mappati correttamente alle proprietà del parametro.

public ActionResult Details(StoreVm model) 
{ 
    // model.Name & model.Id will have values mapped from the request querystring 
    // to do : Return something. 
} 

che questo funzionerà per passare vista piccola modello piatto magra. Ma se vuoi passare un oggetto complesso, dovresti provare a seguire il modello PRG.

PRG modello

PRG sta per POST - REDIRECT - GET. Con questo approccio, si invierà una risposta di reindirizzamento con un ID univoco nella query querys, utilizzando il quale il secondo metodo di azione GET può interrogare nuovamente la risorsa e restituire qualcosa alla vista.

int newStoreId=101; 
return RedirectToAction("Details", "Store", new { storeId=newStoreId}); 

Questo creerà l'url Store/Details?storeId=101 e nella vostra azione Dettagli GET, utilizzando lo storeId passata in, si otterrà/costruire l'oggetto StoreVm da qualche parte (di un servizio o interrogare il database, ecc)

public ActionResult Details(string storeId) 
{ 
    // from the storeId value, get the entity/object/resource 
    var store = yourRepo.GetStore(storeId); 
    if(store!=null) 
    { 
     // Map the the view model 
     var storeVm = new StoreVm { Id=storeId, Name=store.Name,Code=store.Code}; 
     return View(storeVm); 
    } 
    return View("StoreNotFound"); // view to render when we get invalid store id 
} 

TempData

seguito della PRG pattern è una soluzione migliore per gestire questo caso d'uso. Ma se non si vuole farlo e voglia di passare alcuni dati complessi in tutto Stateless HTTP richieste, è possibile utilizzare un meccanismo di stoccaggio temporaneo come TempData

TempData["NewCustomer"] = model; 
return RedirectToAction("Index", "Users"); 

e leggerlo nel metodo d'azione GET di nuovo .

public ActionResult Index() 
{  
    var model=TempData["NewCustomer"] as Customer 
    return View(model); 
} 

TempData utilizza Session oggetto dietro la scena per memorizzare i dati. Ma una volta letti i dati, i dati sono terminati.

Rachel ha scritto un bel blog post che spiega quando utilizzare TempData/ViewData. Vale la pena leggere

Utilizzando TempData per passare i dati del modello ad una richiesta di reindirizzamento in Asp.Net Nucleo

Nel nucleo Asp.Net, non è possibile passare i tipi complessi in TempData. È possibile passare tipi semplici come string, int, Guid ecc.

Se si desidera passare un oggetto di tipo complesso tramite TempData, sono disponibili 2 opzioni.

1) Serializzare l'oggetto su una stringa e passarlo.

Ecco un esempio utilizzando Json.NET per serializzare l'oggetto in una stringa

var s = Newtonsoft.Json.JsonConvert.SerializeObject(createUserVm); 
TempData["newuser"] = s; 
return RedirectToAction("Index", "Users"); 

Ora nel tuo metodo di azione Index, leggere questo valore dal TempData e deserializzare al vostro oggetto CreateUserViewModel classe.

public IActionResult Index() 
{ 
    if (TempData["newuser"] is string s) 
    { 
     var newUser = JsonConvert.DeserializeObject<CreateUserViewModel>(s); 
     // use newUser object now as needed 
    } 
    // to do : return something 
} 

2) Impostare un dizionario di tipi semplici per TempData

var d = new Dictionary<string, string> 
{ 
    ["FullName"] = rvm.FullName, 
    ["Email"] = rvm.Email; 
}; 
TempData["MyModelDict"] = d; 
return RedirectToAction("Index", "Users"); 

e leggere in un secondo momento

public IActionResult Index() 
{ 
    if (TempData["MyModelDict"] is Dictionary<string,string> dict) 
    { 
     var name = dict["Name"]; 
     var email = dict["Email"]; 
    } 
    // to do : return something 
} 
Problemi correlati