Frage

Wie kann ich das umsetzen? Post-Redirect-Get Muster mit ASP.NET?

Durch Klicken auf eine Schaltfläche wird eine Verarbeitung ausgeführt:

<asp:Button id="bbLaunch" OnCommand="bbLaunch_Click" />

Der Benutzer klickt auf die Schaltfläche, das Raumschiff wird gestartet und die Webseite wird erneut angezeigt.Wenn der Benutzer F5 drückt, erhält er die Warnung:

enter image description here

Die Lösung des Problems ist die Post-Redirect-Get Muster.

Was ist die Methode, mit der PRG kann in ASP.NET implementiert werden?


Die Frage dreht sich um folgende Probleme:

  • wie kann das <asp:Button> a durchführen POST an einen Ort, der nicht seine ursprüngliche Form hat?
  • was wird aus dem Sichtzustand wenn Sie in einem Formular posten, das den Ansichtsstatus nicht liest?
  • was wird aus dem Sichtzustand wenn Sie zum „echten“ ASPX-Webformular umleiten?
  • Ist Sichtzustand grundsätzlich unvereinbar mit ASP.net Post-Redirect-Get?
  • ist ASP.net grundsätzlich nicht kompatibel mit Post-Redirect – Get?
  • Wie (d. h.Welcher Code) leiten Sie zum „echten“ ASPX-Webformular weiter?
  • Wie (d. h.Welche URL leiten Sie zum „echten“ ASPX-Webformular weiter?Eine Beziehungsfrage erwähnt Response.Redirect(Request.RawUrl);
  • Wann (d. h.In welchem ​​Event-Handler leiten Sie zum „echten“ ASPX-Webformular weiter?
  • Die damit verbundenen Fragen werfen Fragen auf Wie Sie veröffentlichen Formulardaten.Es besteht die Implikation, dass HTML Formen kann nicht verwendet werden – und alle Formulardaten müssen zur Abfragezeichenfolge hinzugefügt werden.Ist das wahr?Wenn ja warum?Wenn nicht, warum nicht? Kann Ein Browser hat Formulardaten in eine Abfragezeichenfolge eingefügt?
  • Eine verwandte Frage erwähnt Server.Transfer.Benutzen Server.Transfer ist völlig falsch und löst in keiner Weise das Post-Redirect-Get-Problem (weil es keine gibt). Umleiten).Richtig?
  • Welche Codeänderung muss in der erfolgen aspx oder aspx.cs Datei zur Unterstützung von PRG?Vermutlich muss zumindest der Code geändert werden post irgendwo anders MyPage.aspx.

Mit anderen Worten: Wie führen Sie Post-Redirect-Get in ASP.net durch?

Notiz:ASP.net (d. h.nicht ASP.net MVC)

Siehe auch

War es hilfreich?

Lösung

Normalerweise würden Sie dies tun, indem Sie ein ASPX-Webformular erstellen, das die Abfragezeichenfolge verwendet, um zu signalisieren, welcher Datensatz geladen/verarbeitet werden soll.

Nehmen wir an, Sie haben eine Seite, auf der Sie einige Kundeninformationen aktualisieren können:

http://www.mysite.com/customer.aspx

Sie würden das Formular mit einer ID im Abfragestring laden:

http://www.mysite.com/customer.aspx?CustomerId=42

Im Codebehind hätten Sie etwa Folgendes:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        int customerId = 0;
        if (!string.IsNullOrEmpty(Request.QueryString["CustomerId"]))
        {
            int.TryParse(Request.QueryString["CustomerId"], out customerId );
        }
        if (customerId == 0) 
        {
            //handle case when no valid customer id was passed in the qs here
        }
        else 
        {
            //load customer details, bind controls etc
            //make sure to handle the case when no customer was found using the id in the qs
        }
    }
}

Dann hätten Sie irgendwo auf Ihrer Seite eine Schaltfläche, die die Änderungen speichert.Diese Schaltfläche hätte einen OnClick-Handler im Code dahinter:

protected void SaveClicked(object sender, EventArgs e)
{
    //save changes to database here

    //Redirect if all went well
    Response.Redirect("http://www.mysite.com/customer.aspx?CustomerId=" 
        + idOfSavedCustomer.ToString());
}

Das sollte es im Prinzip sein.Die Umleitung führt dazu, dass der Browser eine neue GET-Anfrage für die URL in Redirect(...) ausgibt.Es wird die Seite laden, die if (!IsPostBack) wird die Seite ausführen und mit den neuen Werten initialisieren, die Sie gerade im vorherigen Beitrag gespeichert haben.

Für diesen gesamten Prozess würde der Datenverkehr zwischen Browser und Server etwa so aussehen:

Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send back some html)

Browser: POST http://www.mysite.com/customer.aspx?CustomerId=42 (post data sent in request)
Server: 302 (point to http://www.mysite.com/customer.aspx?CustomerId=42)

Browser: GET http://www.mysite.com/customer.aspx?CustomerId=42
Server: 200 (send html)

Im mittleren Schritt sagt der Server im Wesentlichen:

„Mit der Post-Anfrage, die Sie mir geschickt haben, bin ich fertig.Gehen Sie jetzt bitte zu dieser anderen Seite hier ...“

Die Tatsache, dass die URL tatsächlich auf dieselbe Seite verweist, ist nicht wichtig.


Einige Überlegungen als Antwort auf Ihre Liste mit Stichpunkten:

  • Wie kann der einen Beitrag an einen Ort ausführen, der nicht seine ursprüngliche Form ist?

Sie können dies tun, indem Sie die festlegen action Attribut auf dem Formular, oder Sie können das festlegen PostBackUrl auf dem Knopf.

  • Was wird aus dem ViewState, wenn Sie in einem Formular posten, in dem der Ansichtszustand nicht gelesen wird?

Kommt darauf an.Wenn Sie das Formular einfach auf einer anderen Seite veröffentlichen, können Sie die Anweisung <%@ PreviousPageType .../> verwenden, um der „neuen“ Seite mitzuteilen, woher der Beitrag stammt.Dadurch wird die Arbeit mit den veröffentlichten Daten auf der neuen Seite vereinfacht.Sehen Weitere Informationen finden Sie unter diesem Link.

  • Was wird aus dem ViewState, wenn Sie zum "echten" ASPX -Webformular umleiten?

Der Ansichtsstatus wird in der Post-Anfrage gesendet.Bei der Umleitung lädt der Browser eine neue Seite und erstellt eine eigene Seite.

  • Ist ViewState mit ASP.NET post-redirect-Get grundsätzlich nicht kompatibel?

Kommt darauf an, wie man es betrachtet.Nach der Umleitung hat die neue Seite keinen Zugriff mehr auf den Ansichtsstatus der Seite zuvor.

  • Ist ASP.net grundsätzlich nicht mit Post-Redirect--Get kompatibel?

NEIN.Siehe Beispiel oben.

  • wie (d. h.Welcher Code) leiten Sie zum „echten“ ASPX-Webformular weiter?

Response.Redirect(URL).Dadurch wird eine Antwort an den Browser gesendet, die ihn auffordert, eine neue Get-Anfrage zu stellen.

  • wann (d. h.In welchem ​​Event -Handler) leiten Sie das "echte" ASPX -Webformular aus?

Wenn Sie alle zur Bearbeitung der Postanforderung erforderlichen Arbeiten durchgeführt haben.

  • Die damit verbundenen Fragen werfen Fragen dazu auf, wie Sie Formulardaten veröffentlichen.Es besteht die Implikation, dass HTML -Formulare nicht verwendet werden können - und alle Formulardaten müssen der Abfragezeichenfolge hinzugefügt werden.Ist das wahr?Wenn ja warum?Wenn nicht, warum nicht?Kann ein Browser Formulardaten in eine Abfragezeichenfolge einfügen?

Das Umleiten einer Post-Anfrage wird nicht gut unterstützt und sollte wahrscheinlich vermieden werden.Dies kann (mit einigen Browsern) mithilfe der http-Antwort 307 erfolgen.Dabei teilt der Server dem Browser effektiv mit, dass „Ich werde Ihre Postanfrage nicht bearbeiten. Bitte posten Sie sie stattdessen auf dieser anderen Seite".

  • Eine verwandte Frage erwähnt Server.Transfer.Die Verwendung von server.transfer ist völlig falsch und löst in keiner Weise das Problem der Post-Redirect-GET (da es keine Weiterleitung gibt).Richtig?

Server.Transfer(...) findet auf der Serverseite statt.Der Browser ist sich dessen nicht bewusst.Grundsätzlich kann eine Seite Server.Transfer verwenden, damit eine andere Seite etwas verarbeitet, und diese Seite ist für das Zurücksenden einer Antwort an den Browser verantwortlich.Der Browser geht jedoch davon aus, dass es sich um die Originalseite handelte, auf die geantwortet wurde.

  • Welche Codeänderung muss in der ASPX- oder ASPX.CS -Datei geschehen, um PRG zu unterstützen?Vermutlich muss der Code zumindest so geändert werden, dass sie irgendwo neben myPage.aspx veröffentlichen.

Nein, es kann ein normaler Post-Back verwendet werden.Der Trick besteht darin, einen (oder mehrere) spezifische Event-Handler auf der Seite zu haben, der nach der Verarbeitung der geposteten Daten einen Repsonse.Redirect ausführt.

Andere Tipps

F) Wie kann ein POST an einen Ort durchgeführt werden, der nicht in seiner ursprünglichen Form vorliegt?

A) Mit PRG posten Sie nicht auf einer anderen Seite, sondern auf derselben Seite (siehe das Diagramm auf der Wikipedia-Seite, auf die Sie verlinkt haben). Die Antwort von dieser Seite MUSS jedoch eine 30-fache Antwort sein (normalerweise eine 302). .)

F) Was passiert mit dem ViewState, wenn Sie in einem Formular posten, das den Ansichtsstatus nicht liest?

A) Der Ansichtsstatus ist vorhanden, wenn Sie posten, aber für die neue Seite, auf der Sie ein GET durchführen, ist der Ansichtsstatus nicht vorhanden.

F) Was passiert mit dem ViewState, wenn Sie zum „echten“ ASPX-Webformular umleiten?

A) Gemäß oben gibt es keinen weiteren Ansichtsstatus, der auf die Seite umleitet.

F) Ist ViewState grundsätzlich nicht mit ASP.net kompatibel?

A) ViewState ist nicht mit ASP.NET inkompatibel.Es ist für P/R/G (meistens) nutzlos, die Seite darzustellen, zu der Sie weitergeleitet werden.

F) Ist ASP.net grundsätzlich nicht mit Post-Redirect--Get kompatibel?

A) Nein – aber Sie können sich nicht übermäßig darauf verlassen, eine Seite zu verwenden und Ihren gesamten Status im Ansichtsstatus zu behalten, wie oben beschrieben.Allerdings lässt sich ASP.MVC viel besser auf P/R/G abbilden

F) wie (d. h.Welcher Code) leiten Sie zum „echten“ ASPX-Webformular um?

A) Response.Redirect("new_page_you_are_redirecting_to.aspx") in der bbLaunch_Click-Methode von old_page_you_are_posting_from.aspx

F) wie (d. h.Welche URL leiten Sie zum „echten“ ASPX-Webformular weiter?Eine Beziehungsfrage erwähnt Response.Redirect(Request.RawUrl);

A) Siehe oben

F) wann (d. h.In welchem ​​Event-Handler leiten Sie zum „echten“ ASPX-Webformular weiter?

A) Nachdem Sie den Tastendruck verarbeitet, die Daten in der Datenbank (oder Sitzung usw.) gespeichert haben und bevor Sie etwas anderes in den Antwortstream geschrieben haben.

F) Die damit verbundenen Fragen werfen Probleme bei der Veröffentlichung von Formulardaten auf.Dies bedeutet, dass HTML-Formulare nicht verwendet werden können und alle Formulardaten zur Abfragezeichenfolge hinzugefügt werden müssen.Ist das wahr?

A) Nein – durch Drücken der Taste in ASP.NET WebForms wird ein POST auf die Seite zurückgesendet.

F) Wenn ja, warum?Wenn nicht, warum nicht?

A) Es ist einfacher als das, deshalb nicht.Abbildung zweier Seiten:first_page.asp und second_page.aspx.Auf First_page.aspx befindet sich die Schaltfläche (zusammen mit anderen ASP.NET-Websteuerelementen wie Textfeldern usw., die der Benutzer ausgefüllt hat). Wenn er auf die Schaltfläche drückt, wird ein POST an first_page.aspx gesendet.Nach der Verarbeitung der Daten (die sich wahrscheinlich im Viewstate befinden, obwohl diese abstrahiert sind) leiten Sie den Benutzer mithilfe von Response.redirect zu second_page.aspx um.Second_page.aspx kann anzeigen, was Sie wollen.Wenn Sie eine Benutzeroberfläche anzeigen möchten (oder müssen), die der auf first_page.aspx ähnelt, einschließlich der Steuerelemente und ihrer Eingaben, möchten Sie dies in der Sitzung speichern, ein Cookie und die URL als Abfragezeichenfolgenparameter festlegen diese Steuerelemente auf second_page.aspx.(Aber möglicherweise müssen Sie auf second_page.aspx nichts anzeigen, was first_page.aspx ähnelt – daher gibt es hier keine allgemeine Regel.)

F) Kann ein Browser Formulardaten in eine Abfragezeichenfolge einfügen?

A) Ja, wenn Sie die Methode auf GET statt auf POST setzen.Sie können WebForms hierfür nicht überschreiben, und dies ist für PRG auch nicht erforderlich

F) In einer verwandten Frage wird Server.Transfer erwähnt.Die Verwendung von Server.Transfer ist völlig falsch und löst das Post-Redirect-Get-Problem in keiner Weise (da es keine Umleitung gibt).Richtig?

A) Im Wesentlichen

F) Welche Codeänderung muss in der Datei aspx oder aspx.cs vorgenommen werden, um PRG zu unterstützen?Vermutlich muss zumindest der Code geändert werden, um irgendwo anders als MyPage.aspx zu posten.

A) Der Code sollte immer noch zurückgesendet werden (wie oben erwähnt). Dann sollte Mypage.aspx jedoch auf eine neue Seite im Schaltflächenhandler umleiten.

Das Post-Redirect-Get-Muster kann in Web Forms verwendet werden.Ich habe gezeigt, wie dies durch die Konvertierung der MVC NerdDinner-Anwendung in Web Forms erreicht werden kann. http://navigationnerddinner.codeplex.com/ .Ich habe die Navigationsdetails genau gleich beibehalten, sodass es viele Beispiele für das PRG-Muster gibt.

Es gibt jedoch eine andere Möglichkeit, das F5/Aktualisieren-Problem zu vermeiden.Wenn Sie Ihre Seite in ein UpdatePanel (Teil von ASP.NET Ajax) einschließen, werden alle Postbacks in Teilseitenanforderungen umgewandelt.Das heißt, wenn F5 gedrückt wird, wird nur die ursprüngliche GET-Anfrage aktualisiert (da keine nachfolgenden POSTs stattgefunden haben) und Sie erhalten daher keine Warnung.(Hinweis: Wenn JavaScript deaktiviert ist, wird die Warnung weiterhin angezeigt.)

Die genauen Schritte des Post Redirect Get sind diese:

Sie haben das Formular, das Sie mit Daten ausfüllen, und nach Ihrer gültigen Übermittlung (POST) fügen Sie diese in Ihre Datenbank ein und geben ihnen eine Bestätigungs-ID. Anschließend leiten Sie den Benutzer auf die Seite mit dieser Bestätigungs-ID als verwendetem URL-Parameter weiter als (GET) Nach der Umleitung werden bei jedem F5-Refresh die Daten nur gelesen und nicht erneut eingefügt.

Der Code zum Einfügen unterscheidet sich von dem Code, der die Bestätigung anzeigt. Sie können sogar unterschiedliche Seiten erstellen – Sie können dieselbe Seite mit schreibgeschützten Textfeldern erstellen.

Die Weiterleitung ist einfach Responce.Redirect Funktion von asp.net

Nach dem POST und der Durchführung der Weiterleitung ist der einzige Gedanke, der Sie mit der vorherigen Aktion verbindet, der Bestätigungscode (nicht der Ansichtsstatus).

Der Nachteil dieser Methode besteht darin, dass sie die Aktualisierung tatsächlich nicht erkennt, sondern lediglich einen zusätzlichen Schritt ausführt, der dafür sorgt, dass bei der Aktualisierung nicht erneut dieselben Daten eingefügt werden, sondern zusätzlicher Code für den Datenabruf erforderlich ist.

Die Alternative besteht darin, die Aktualisierung zu erkennen und keine Umleitung vorzunehmen.Indem Sie die Aktualisierung beim Zurücksenden erkennen, können Sie vermeiden, dass dieselben Daten in einer einzigen Nachricht an den Benutzer eingefügt werden.Dafür gibt es einige Beispiele im Internet, und ich habe eines mit Erfolg umgesetzt.

Ein Beispiel: http://www.codeproject.com/Tips/319955/How-to-prevent-Re-Post-action-caused-by-pressing-b

Sie können die aufrufen Antwort.Umleitung Methode, um zu einem anderen Ort zu gelangen.

Es gibt ein paar Dinge, die dabei eine Rolle spielen.

  1. Stellen Sie die ein Aktion Attribut des Formulars auf der Hauptseite (nennen wir es LaunchForm.aspx) entspricht der URL der „Proxy“-Seite (ProxyLaunchForm.aspx).

    <form id="form1" runat="server" action="ProxyLaunchForm.aspx" method="POST">

  2. (optional) Fügen Sie eine versteckte Eingabe mit dem Namen hinzu RedirectUrl zum Formular und geben Sie den Wert der URL ein, die dies mitteilt ProxyLaunchForm.aspx wohin umgeleitet werden soll, sobald der Start abgeschlossen ist (der R-Teil von PRG).

  3. Jetzt weiter ProxyLaunchForm.aspx, die Implementierung sollte innerhalb des erfolgen Page_Load Event-Handler, da dieser Zugriff auf Formular-Post-Daten hat.Führen Sie den Start hier aus.

  4. Anschließend (auch in Page_Load), führen Sie die Umleitung durch (entweder mit der RedirectUrl aus #2, oder einfach die URL der verweisenden Seite verwenden):

    Response.Redirect(Request.Params["redirectUrl"] ??Request.UrlReferrer.AbsoluteUri);

    Da bleibt noch die Frage des Ansichtsstatus.Ich denke, der einfachste Weg, damit umzugehen, besteht darin, die Art und Weise zu ändern, wie der Ansichtsstatus beibehalten wird.Normalerweise wird es in einem versteckten Eingabeelement auf der Seite gespeichert und beim Postback abgerufen (was natürlich bedeutet, dass es nach der Umleitung aufgrund der zustandslosen Natur von HTTP verloren geht).Sie können jedoch die von ASP.net verwendeten Methoden überschreiben und es verwenden lassen Sitzung stattdessen (auf diese Weise ist es auch nach der PRG-Proxy-Aktion noch vorhanden).So endlich...

  5. In LaunchForm.aspx.cs, verwenden Sie als Basisklasse eine Unterklasse Seite das überschreibt die SavePageStateToPersistenceMedium Und LoadPageStateFromPersistenceMedium Methoden zum Speichern/Abrufen aus der Sitzung und nicht aus einem versteckten Formularfeld.Siehe unten (und Hier finden Sie weitere Informationen dazu, wie das funktioniert.).

*

public class PersistViewStateToSession : Page
{
    protected override void SavePageStateToPersistenceMedium(object viewState)
    {
        // serialize the view state into a base-64 encoded string
        LosFormatter los = new LosFormatter();
        StringWriter writer = new StringWriter();
        los.Serialize(writer, viewState);
        // save the string to session
        Session["LaunchViewState"] = writer.ToString();
    }

    protected override object LoadPageStateFromPersistenceMedium()
    {
       if (!Session["LaunchViewState"] == null)
           return null;
       else
       {
          string sessionString = (string)Session["LaunchViewState"];
          // deserialize the string
          LosFormatter los = new LosFormatter();
          return los.Deserialize(viewStateString);
       }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top