2009-08-29 18 views
8

Sto provando a passare un oggetto da un'azione del controller a un altro. L'oggetto che sto passando intorno sembra più o meno così:RedirectToAction (..) con il complesso oggetto profondo non riesce

public class Person 
{ 
    public string Name { get; set; } 
    public List<PhoneNumber> PhoneNumbers {get; set; } 
    public List<Address> Addresses { get; set; } 
} 

mio controller è simile al seguente:

public class DialogController : Controller 
{ 
    public ActionResult Index() 
    { 
     // Complex object structure created 
     Person person = new Person(); 
     person.PhoneNumbers = new List(); 
     person.PhoneNumbers.Add("12341324"); 

     return RedirectToAction("Result", "Dialog", person); 

    } 

    public ActionResult Result(Person person) 
    { 
     string number = person.PhoneNumbers[0].ToString(); 
     return View(); 
    } 
} 

Il metodo seguito non riesce con un'eccezione di puntatore nullo in quanto l'elenco PhoneNumbers è improvvisamente null dopo aver richiamato l'azione Result con il metodo RedirectToAction().

Qualcuno ha già visto questo tipo di comportamento?

Cheers,

Peter

risposta

5

Sono d'accordo con @Dennis - a meno che tu non voglia che l'Url cambi, allora dovrai pensare a qualcos'altro. Il motivo è che RedirectToAction non serializza i dati, semplicemente itera sulle proprietà nell'oggetto dei valori di instradamento che costruisce una stringa di query con le chiavi come nomi di proprietà e i valori della rappresentazione di stringa dei valori di proprietà. Se vuoi che l'Url cambi, usare TempData è probabilmente il modo più semplice per farlo, sebbene tu possa anche archiviare l'elemento nel database, passare l'id al metodo Result e ricostituirlo da lì.

+0

Hi T, Ho finito per usare il trucco TempDaata per trasferire oggetti da un'azione all'altra. Grazie per aver chiarito come funziona RedirectToAction. Questa è stata la vera parte confusa per me. –

7

Avete veramente bisogno di reindirizzare l'altra azione? RedirectToAction causa una nuova richiesta http, motivo per cui TempData funziona. Non potresti semplicemente chiamare l'azione Result direttamente in questo modo?

public ActionResult Index() 
{ 
    // Complex object structure created 
    Person person = new Person(); 
    person.PhoneNumbers = new List(); 
    person.PhoneNumbers.Add("12341324"); 

    return Result(person); 

} 

Modifica A meno che la vostra applicazione sta facendo più di quello che hai mostrato nella questione, non sembra come si ha realmente bisogno l'azione Index. È possibile spostare il codice che crea una nuova persona in un metodo privato CreatePerson. Nell'azione person se person è nullo, quindi chiamare il metodo CreatePerson. L'azione Index potrebbe essere eliminata del tutto, ma ciò richiederebbe la modifica dei percorsi. Oppure lascia che sia return RedirectToAction("Result", "Dialog"); l'unica linea di codice nell'azione Index.

In realtà, a seguito della separazione dei problemi di MVC, il metodo CreatePerson dovrebbe probabilmente essere un metodo all'interno del codice del modello. Il controller non deve contenere la logica della creazione di un nuovo Person. Questo appartiene davvero alla modella.

+0

Hi Dennis, Grazie per la risposta. Hai completamente ragione sulla creazione degli oggetti Person. Grazie! –

2

Sebbene si tratti di una vecchia domanda, ho trovato un great answer to it in quella che credo sia una domanda duplicata. La chiave è il costruttore RouteValueDictionary.

return RedirectToAction("Result", "Dialog", new RouteValueDictionary(person)) 

Dal momento che hai collezioni, lo rende una tricker po ', but this other answer covers this very nicely.

0

Per tutti, è davvero necessario richiamare un'azione e restituire la vista da un altro controller con un oggetto complesso e non si desidera (o non può) passare l'oggetto in TempData.Che uso nel mio app molto brutto, ma la soluzione di lavoro:

protected ActionResult InternalRedirectToAction(string action, string controller, object model) 
{ 
    var htmlHelper = new HtmlHelper(new ViewContext(
           ControllerContext, 
           new WebFormView(ControllerContext, "HACK"), 
           new ViewDataDictionary(), 
           TempData, //for sharing TempData between Actions 
           new StringWriter()), 
         new ViewPage()); 

    var otherViewHtml = htmlHelper.Action(action, controller, model); 
    return Content(otherViewHtml.ToString()); 
} 

Ispirato risposta trovato qui: https://stackoverflow.com/a/4360019/1341409

Problemi correlati