Thomas Bandt

Über mich | Kontakt | Archiv

ASP.NET MVC - TempData sinnvoll einsetzen

Ein nettes Feature von ASP.NET MVC ist das TempData-Dictionary. Damit kann man Dinge wie zum Beispiel Statusmeldungen temporär speichern und einmal abrufen - danach sind sie automatisch gelöscht.

Sinnvoll ist das zum Beispiel für Formulare, bei denen etwas gespeichert wird, und wo dem Benutzer nach erfolgreicher Speicherung eine Meldung ausgegeben werden soll. Dafür hat man grundsätzlich seit jeher und mal unabhängig von ASP.NET MVC zwei Möglichkeiten:

  1. Man gibt die Meldung nach Abarbeitung des (POST-) Requests direkt aus.
  2. Man erzeugt einen neuen Request durch eine Weiterleitung, entweder auf sich selbst oder auf eine Bestätigungsseite.

Der einfachste Weg ist schon immer der erste gewesen, gleichwohl er nicht der beste ist. Der Grund: die per POST gesendeten und ggf. erfolgreich gespeicherten Daten werden beim nächsten Aufruf durch den Client erneut gesendet. Aktualisiert der Benutzer z.B. nach "dem Speichern" die Seite in seinem Browser, erhält er zum einen eine blöde Frage, ob die Daten erneut gesendet werden sollen, zum anderen kann es dann bei schlechter Programmierung dazu kommen, dass einfach nochmal gespeichert wird. Ist der Nutzer nun gelangweilt oder anderweitig motiviert, kann er so einfach durch schlichtes F5/Enter in kürzester Zeit hunderte Datensätze speichern ...

Um das zu vermeiden bietet sich ebenfalls seit jeher der zweite Weg an. D.h. nach erfolgreicher Speicherung macht man einfach einen Redirect und zeigt dem Nutzer entsprechend die Erfolgsmeldung an. Mit ASP.NET MVC gibt's dafür grundsätzlich 2 Wege.

Man kann erstens auf eine andere View weiterleiten, also z.B.

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Create(string test)
   3:  {
   4:      // Speichern
   5:      // ...
   6:      return RedirectToAction("CreateSuccessfull");
   7:  }

Das macht Sinn, wenn der Prozess abgeschlossen ist, z.B. nach einer Benutzerregistrierung.

Man kann aber auch die gleiche View zurückliefern, was sinnvoll ist, wenn der Benutzer beispielsweise in der Lage sein soll, mehrere Datensätze nacheinander anzulegen. An diese View muss man nun irgendwie den Status übergeben, d.h. ihr mitteilen, dass der Datensatz bei der letzten Aktion erfolgreich erstellt wurde.

Üblicherweise macht man das z.B. mit ASP.NET WebForms entweder mit einem angehängten QueryString-Parameter oder einer "Session-Variable". Erstes sieht nicht schön aus, bei Zweitem muss man sicherstellen, dass der Session-Wert auch nur ein einziges Mal abgerufen und dann sicher gelöscht wird, will man keine ungewollten Seiteneffekte erzeugen.

Das MVC-Team von Microsoft hat hier mitgedacht und mit dem TempData-Dictionary eine Lösung geschaffen. TempData verwaltet seine Daten intern nämlich in einer Session und sorgt gleichzeitig dafür, dass ein Wert nach dem ersten und einzig möglichen Abruf auch sauber wieder gelöscht wird. Damit entfällt das manuelle Handling, was vorher nötig gewesen ist.

Der eleganteste Weg ist also der Redirect auf sich selbst und die Übergabe des Status via TempData:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public ActionResult Create(string test)
   3:  {
   4:      // Speichern
   5:      // ...
   6:      TempData["CreationSuccessfull"] = true;
   7:      return RedirectToAction("Create");
   8:  }

Dann kann man innerhalb der View ganz einfach eine nette Meldung ausgeben:

   1:  <% if(TempData["CreationSuccessfull"] != null) { %>
   2:   
   3:  <div style="background: green;">
   4:      Deine Einladung wurde erfolgreich verschickt.
   5:  div>
   6:   
   7:  <% } %>

Aktualisiert man nun die Seite, erhält man sie im Urzustand zurück - denn der Wert aus TempData wurde mit dem Aufruf bereits gelöscht. Im Ergebnis erzielt man damit eine gute "User Experience" und erhält obendrein wieder ein sauberes Formular ohne die Gefahr, dass der Benutzer ungewollt oder gewollt die Daten immer und immer wieder abschickt.



« Zurück  |  Weiter »