Ich habe versucht, Daten nach einer Umleitung an eine Aktion zu übergeben, indem ich TempData wie folgt verwendet habe:
if (!ModelState.IsValid)
{
TempData["ErrorMessages"] = ModelState;
return RedirectToAction("Product", "ProductDetails", new { code = model.ProductCode });
}
aber leider schlägt es mit folgender Meldung fehl:
‚
System.InvalidOperationException
DasMicrosoft.AspNet.Mvc.SessionStateTempDataProvider'
kann nicht ein Objekt vom Typ serialisiert'ModelStateDictionary'
zu Sitzungszustand.‘
Ich habe ein Problem im MVC-Projekt in Github gefunden , aber obwohl es erklärt, warum ich diesen Fehler erhalte, kann ich nicht sehen, was eine praktikable Alternative wäre.
Eine Möglichkeit wäre, das Objekt in einen JSON-String zu serialisieren und es dann wieder zu deserialisieren und das zu rekonstruieren ModelState
. Ist das der beste Ansatz? Gibt es potenzielle Leistungsprobleme, die ich berücksichtigen muss?
Und schließlich gibt es Alternativen, um komplexe Objekte zu serialisieren oder ein anderes Muster zu verwenden, bei dem keine Verwendung erforderlich ist TempData
?
quelle
Antworten:
Sie können die Erweiterungsmethoden folgendermaßen 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 Sie können sie wie folgt verwenden:
Sprich
objectA
ist vom TypClassA
. Sie können dies mit der oben genannten Erweiterungsmethode wie folgt zum temporären Datenwörterbuch hinzufügen:TempData.Put("key", objectA);
Und um es abzurufen, können Sie Folgendes tun:
var value = TempData.Get<ClassA>("key")
wovalue
abgerufen wird vom Typ seinClassA
quelle
Serializable
Attributs zu der Klasse markiert habe, die ich für das Objekt verwendet habe, in das gelegt wurdeTempData
Ich kann nicht kommentieren, aber ich habe auch ein PEEK hinzugefügt, das schön ist zu überprüfen, ob es vorhanden ist oder zu lesen und nicht für das nächste GET zu entfernen.
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
quelle
Verwenden von System.Text.Json in .Net Core 3.1 und höher
using System.Text.Json; public static class TempDataHelper { public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class { tempData[key] = JsonSerializer.Serialize(value); } public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class { tempData.TryGetValue(key, out object o); return o == null ? null : JsonSerializer.Deserialize<T>((string)o); } public static T Peek<T>(this ITempDataDictionary tempData, string key) where T : class { object o = tempData.Peek(key); return o == null ? null : JsonSerializer.Deserialize<T>((string)o); } }
quelle