Das Post-Redirect-Get-Pattern (Teil 2)
Kommentare

GET- und POST-Aktionen
ASP.NET MVC unterstützt das Attribut AcceptVerbs, das – auf eine Controller-Methode angewandt – die eingehenden Anforderungen filtert und diejenigen überspringt, die über ein

GET- und POST-Aktionen

ASP.NET MVC unterstützt das Attribut AcceptVerbs, das – auf eine Controller-Methode angewandt – die eingehenden Anforderungen filtert und diejenigen überspringt, die über ein nicht übereinstimmendes Verb eintreffen. Es sind zwei Versionen der Edit-Aktion erforderlich: eine für GET und eine für POST. Diese kodieren Sie mit zwei getrennten Methoden in der Customer-Controller-Klasse und binden sie an die gleiche Aktion. Der Code sieht folgendermaßen aus:

[ActionName("Edit")] [AcceptVerbs(HttpVerbs.Post)] public ActionResult EditViaPost(String ddCustomers) { : } [ActionName("Edit")] [AcceptVerbs(HttpVerbs.Get)] public ActionResult EditViaGet(String id) { : }

Das PRG-Pattern schlägt vor, dass Sie den größten Teil Ihres Codes im GET Handler unterbringen und dann jede POST-Anforderung an die GET-Methode weiterleiten. Im Ergebnis ist die Methode EditViaPost ziemlich einfach:

public ActionResult EditViaPost(String ddCustomers) { var customerId = ddCustomers; return RedirectToAction("Edit", new RouteValueDictionary(new { id = customerId })); }

Dieser Code erstellt einfach eine Kopie des Eingabearguments und leitet diese an die Edit-Aktion weiter. Die Weiterleitung löst eine GET-Anforderung aus, die durch die Methode EditViaGet aufgelöst wird. An dieser Stelle drängt sich folgende Frage auf: Warum umleiten, wenn ein einfacher direkter Aufruf der Methode EditViaGet aus EditViaPost die gleichen Ergebnisse liefert und zudem einen Roundtrip spart?

Der Vorzug des Patterns

Wenn Sie die Methode EditViaGet aus dem POST Handler heraus aufrufen, steht im Speicher des Browsers ein POST als letzte Operation. Sollte der Benutzer die Ansicht aktualisieren (über Menübefehl oder F5), würde POST wiederholt ausgeführt und das bekannte Fenster wie in Abbildung 1 angezeigt. Allerdings ist das Erscheinen des Fensters noch nicht das Schlimmste, was passieren kann. Ein POST ist eine Operation, die Daten an den Server sendet – und gesendete Daten können eine Serveroperation auslösen. Nicht alle diese Operationen (z. B. das Hinzufügen eines Datensatzes) sind idempotent – d. h. erzeugen die gleiche Wirkung unabhängig davon, wann sie aufgerufen werden. Wenn Sie eine POST-Aktion wiederholen, die z. B. einen Datensatz hinzufügt, werden im Ergebnis mehrere Datensätze in den Speicher hinzugefügt. Das PRG-Pattern verhindert derartige unangenehme Situationen und passt obendrein noch den URL in der Adressleiste perfekt an den Inhalt der Seite an. Wenn Sie also einen Kunden aus der Liste auswählen und die POST-Operation auslösen, spiegelt der URL die Auswahl wieder. Und wenn Sie einen kundenspezifischen URL in die Adressleiste eintippen und dafür eine GET-Operation auslösen, spiegelt die angezeigte Seite die Informationen im URL wider (Abb. 2).

Abb. 2: URL und Inhalt werden synchron gehalten
Abb. 2: URL und Inhalt werden synchron gehalten

In Bezug auf das Select-Edit-Save-Modell bietet sich das PRG-Pattern auch an, wenn Sie eine Aktualisierung ausführen und dann einen Folgebildschirm anzeigen müssen, der eine Erfolgsmeldung ausgibt und/oder den aktualisierten Datensatz wiedergibt. Durch eine Umleitung zur GET-Aktion lässt sich diese Aufgabe leicht und effektiv implementieren. Praktisch muss der GET Handler den Datensatz erneut laden und anzeigen. Wie sieht es mit einer möglichen Nachricht aus? Eine derartige Nachricht, die vom POST Handler festgelegt wird, geht in der Umleitung verloren und gehört ohnehin nicht zu den Informationen, die Sie über die Abfragezeichenfolge übermitteln wollen. In ASP.NET MVC ist die Auflistung TempData vorhanden, die dieses Szenario abdeckt. Die Auflistung ist ein Container, der auf dem Sitzungsstatus basierend seinen Inhalt nach zwei Anforderungen verwirft. Um eine Nachricht (oder irgendwelche serialisierbaren Daten) über zwei aufeinanderfolgende Anforderungen zu senden, speichern Sie sie einfach im POST Handler in TempData und lesen vom GET Handler aus zurück. Das ASP.NET MVC kümmert sich darum, die Informationen aus dem Sitzungsstatus sobald wie möglich zu entfernen.

In einem Framework wie ASP.NET MVC, das Einfachheit verkündet, ist das PRG-Pattern der Weg, den es sich einzuschlagen lohnt. Angesichts der damit gewonnenen Vorteile lassen sich die geringen Mehrkosten für die Umleitung durchaus verschmerzen.

Dino Esposito ist R&D Director bei Crionet, einer Firma, die sich auf webbasierte Lösungen für Sportereignisse in ganz Europa spezialisiert hat. Außerdem ist Dino der Autor von „Programming ASP.NET MVC“, Microsoft Press, 2010.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -