2009-08-29 4 views
8

Ich versuche, ein Objekt von einer Controller-Aktion an eine andere zu übergeben. Das Objekt, das ich vorbei bin schaut sich um mehr oder weniger wie folgt aus:RedirectToAction (..) mit komplexem Deep-Objekt schlägt fehl

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

mein Controller sieht wie folgt aus:

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(); 
    } 
} 

Das Ergebnis Methode mit einem Null-Zeiger-Ausnahme fehlschlägt, da die Liste ist plötzlich Phonenumbers null, nachdem die Aktion Result mit der RedirectToAction() -Methode aufgerufen wurde.

Hat jemand diese Art von Verhalten schon einmal gesehen?

Cheers,

Peter

Antwort

5

Ich stimme @Dennis zu - es sei denn, Sie möchten die Url ändern, dann müssen Sie an etwas anderes denken. Der Grund dafür ist, dass RedirectToAction die Daten nicht serialisiert, sondern einfach über die Eigenschaften im Objekt route values ​​iteriert und eine Abfragezeichenfolge erstellt, deren Schlüssel die Eigenschaftsnamen und die Werte die Zeichenfolgendarstellung der Eigenschaftswerte sind. Wenn Sie möchten, dass sich die Url ändert, ist die Verwendung von TempData wahrscheinlich der einfachste Weg, dies zu tun, obwohl Sie das Element auch in der Datenbank speichern, die ID an die Result-Methode übergeben und von dort aus wiederherstellen können.

+0

Hallo T, Ich endete mit dem TempDaata-Trick, um Objekte von einer Aktion auf die andere zu übertragen. Vielen Dank für die Klärung der Funktionsweise von RedirectToAction. Das war der wirklich verwirrende Teil für mich. –

7

Haben Sie auf die andere Aktion umleiten müssen wirklich? RedirectToAction verursacht eine brandneue http-Anfrage, weshalb TempData funktioniert. Könnten Sie die Aktion Result nicht direkt so aufrufen?

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

    return Result(person); 

} 

bearbeiten Es sei denn, Ihre Anwendung mehr als zu tun ist, was man in der Frage gezeigt haben, es sieht nicht wie Sie wirklich den Index Handlungsbedarf. Sie können den Code, der eine neue Person erstellt, in eine private -Methode verschieben. Wenn person in Ihrer Result Aktion null ist, rufen Sie die Methode CreatePerson auf. Die Aktion Index könnte komplett entfallen, aber dazu müssten Sie Ihre Routen ändern. Oder lass einfach return RedirectToAction("Result", "Dialog"); die einzige Codezeile in deiner Index Aktion sein.

Eigentlich, nach MVC Trennung von Bedenken, sollte diese Methode wahrscheinlich eine Methode in Ihrem Modellcode sein. Der Controller sollte nicht die Logik zum Erstellen eines neuen Person enthalten müssen. Das gehört wirklich in das Modell.

+0

Hallo Dennis, Danke für die Antwort. Sie haben völlig Recht mit der Erstellung der Person-Objekte. Danke! –

2

Obwohl dies eine alte Frage ist, fand ich eine great answer to it in was ich glaube, ist eine doppelte Frage. Der Schlüssel ist der RouteValueDictionary Konstruktor.

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

Da Sie Sammlungen haben, macht es ein bisschen tricker, but this other answer covers this very nicely.

0

Für alle, die wirklich einige Aktion aufrufen müssen und die Ansicht von einem anderen Controller mit komplexem Objekt zurückgeben und nicht Objekt in TempData übergeben möchten (oder können).Ich verwende in meiner app sehr hässlich, aber funktionierende Lösung:

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()); 
} 

von Antwort Inspired finden Sie hier: https://stackoverflow.com/a/4360019/1341409