2016-01-06 5 views
20

Ich habe versucht, Daten auf eine Aktion nach einer Umleitung von TempData passieren wie so mit:Shop komplexes Objekt in TempData in MVC 6

if (!ModelState.IsValid) 
{ 
    TempData["ErrorMessages"] = ModelState; 
    return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode }); 
} 

aber leider mit der folgenden Meldung es andernfalls:

Ich habe ein Problem in the MVC project in Github gefunden, aber während es erklärt, warum ich diesen Fehler bekomme, kann ich nicht sehen, was eine brauchbare Alternative wäre.

Eine Option wäre, das Objekt zu einem JSON-String zu serialisieren und es dann wieder zu deserialisieren und das ModelState zu rekonstruieren. Ist das der beste Ansatz? Gibt es potenzielle Leistungsprobleme, die ich berücksichtigen muss?

Und schließlich, gibt es irgendwelche Alternativen für die Serialisierung eines komplexen Objekts oder die Verwendung eines anderen Musters, das keine Verwendung von TempData beinhaltet?

+0

Sie sollten das nicht tun. Wenn der Modellstatus nicht gültig ist, wird standardmäßig nur die gleiche Ansicht mit dem ungültigen Modell zurückgegeben. Sie sollten also nur diese Rückkehr Ansicht (Modell); und nicht zu Aktion umleiten – hjgraca

+0

Dies ist nur ein Beispiel, ich suche nach einer Möglichkeit, jedes komplexe Objekt in TempData, nicht unbedingt ModelState zu speichern. Es kann auch Situationen geben, in denen Sie Ihrem Rat nicht folgen können, dem ich zustimme. – elolos

+1

@hjgraca Der Anwendungsfall für diese Art von Situation ist eine Ansicht mit mehreren Teilansichten zum Hinzufügen und Bearbeiten einer Datenliste. Zum Beispiel ist das Modell für die Ansicht tatsächlich eine Liste der Modelle, dann gibt es ein Inline-Add-Formular, das sein eigenes Modell hat (dessen Fehler zurückgesendet werden müssen) und dann wird jedes Element ebenfalls inline bearbeitet (jede hat ihre eigenen Fehler)). Dies ist leicht mit clientseitigen Frameworks wie Angular möglich, aber nicht so einfach mit Razor. –

Antwort

38

Sie können die Erweiterungsmethoden wie folgt erstellen:

public static class TempDataExtensions 
{ 
    public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class 
    { 
     tempData[key] = JsonConvert.SerializeObject(value); 
    } 

    public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class 
    { 
     object o; 
     tempData.TryGetValue(key, out o); 
     return o == null ? null : JsonConvert.DeserializeObject<T>((string)o); 
    } 
} 

Und, können Sie sie wie folgt verwendet werden:

objectA ist vom Typ

Say ClassA. Sie können dies auf das Wörterbuch temporären Daten fügen Sie die oben genannten Erweiterungsmethode wie folgt aus:

TempData.Put("key", objectA);

Und es abzurufen Sie können dies tun:

var value = TempData.Get<ClassA>("key") wo value wird ClassA vom Typ sein abgerufen

+0

netter! klappt wunderbar – Danilow

0

Ich kann nicht kommentieren, aber ich fügte auch einen PEEK hinzu, der nett ist, zu überprüfen, ob dort oder gelesen und nicht für den folgenden GET entfernt werden.

public static T Peek<T>(this ITempDataDictionary tempData, string key) where T : class 
{ 
    object o = tempData.Peek(key); 
    return o == null ? null : JsonConvert.DeserializeObject<T>((string)o); 
} 

Beispiel

var value = TempData.Peek<ClassA>("key") where value retrieved will be of type ClassA