Question

Comment puis-je mettre en œuvre le post-Redirect-Get modèle ASP .NET?

cliquez sur le bouton effectue un traitement:

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

L'utilisateur clique sur le bouton, le vaisseau spatial est lancé, les réaffiche de page Web. Si l'utilisateur appuie sur la touche F5, ils obtiennent l'avertissement:

entrer image description ici

La solution au problème est le modèle post-Redirect-Get .

Quelle est la méthode par laquelle PRG peut être mis en œuvre en ASP. NET?


Les centres d'interrogation autour des problèmes de:

  • comment le <asp:Button> effectuer une POST à un endroit qui n'a pas sa forme originale?
  • ce qui est de la ViewState lorsque vous publiez sur un formulaire qui ne l'état d'affichage lit pas?
  • ce qui est de la ViewState lorsque vous redirigez vers le formulaire Web ASPX "réel"?
  • ViewState fondamentalement incompatible avec ASP.net Post-Redirect-Get?
  • est ASP.net fondamentalement incompatible avec Post-Redirect - Get
  • comment (à savoir quel code) vous rediriger vers le formulaire Web ASPX "réel"?
  • comment (à savoir ce que url) vous rediriger vers le formulaire Web ASPX "réel"? Une question de relation mentionne Response.Redirect(Request.RawUrl);
  • lorsque (à savoir dans quel gestionnaire d'événements) vous rediriger vers le formulaire Web ASPX "réel"?
  • questions connexes soulèvent des questions de comment forme post données. Il y a l'implication que HTML formes ne peut pas être utilisé - et toutes les données de formulaire doit être ajouté à la chaîne de requête. Est-ce vrai? Si oui, pourquoi? Sinon, pourquoi pas? peut données de formulaire de vente du navigateur dans une chaîne de requête?
  • une question connexe mentionne Server.Transfer. L'utilisation Server.Transfer est complètement faux, et pas résout la façon dont le problème post-Redirect-Get (car il n'y a pas Redirect ). Correct?
  • quel changement de code doit se produire dans le fichier aspx ou aspx.cs pour soutenir PRG? On peut supposer que, à tout le moins, le code doit être changé quelque part de post en plus MyPage.aspx.

En d'autres termes: Comment faites-vous post-Redirect-Get dans ASP.net

Remarque : ASP.net (à savoir pas ASP.net MVC)

Voir aussi

Était-ce utile?

La solution

En général, vous ferait cela en faisant un formulaire Web ASPX qui utilise le signal qui querystring pour enregistrement à charge / processus.

Le mot Let vous avez une page qui vous permettent de mettre à jour des informations est client:

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

Vous chargerait le formulaire en utilisant un identifiant dans le querystring:

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

Dans le codebehind vous auriez quelque chose comme ceci:

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
        }
    }
}

Ensuite, quelque part dans votre page que vous avez un bouton qui enregistre les modifications. Ce bouton aurait un gestionnaire OnClick dans le code sous-jacent:

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());
}

Cela devrait essentiellement que ce soit. La redirection que le navigateur d'émettre une nouvelle requête GET pour l'URL dans la zone Rediriger (...). Il va charger la page, le if (!IsPostBack) fonctionnera et initialiser la page avec les nouvelles valeurs que vous venez d'enregistrer dans le dos post précédent.

Pour tout ce processus, le trafic entre le navigateur et le serveur ressemblerait à quelque chose comme ceci:

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)

Dans l'étape intermédiaire, le serveur revient à dire:

"Cette demande après vous me avez envoyé, je suis fait avec ça. Maintenant, s'il vous plaît arrivé à cette autre page ici ..."

Le fait l'url dans referrs de fait à la même page n'a pas d'importance.


Quelques réflexions en réponse à votre liste de puce de questions:

  • comment l'effectuer un POST à ??un endroit qui ne lui appartient pas forme originale?

Vous pouvez le faire en définissant l'attribut action sur la forme, ou vous pouvez régler le PostBackUrl sur le bouton.

  • ce qui est de la ViewState lorsque vous publiez sur un formulaire qui ne lire l'état d'affichage?

Cela dépend. Si vous publiez simplement le formulaire à une autre page, vous pouvez utiliser la directive <% @ PreviousPageType ... /> pour dire la page « nouveau » où le poste est venu. Cela simplyfy travailler avec les données affichées sur la nouvelle page. Voir ce lien pour plus de détails .

  • ce qui est de l'ViewState lorsque vous redirigez la ASPX « vrai » formulaire web?

Afficher l'état est envoyé dans la demande de poste. Lors de la redirection, le navigateur va charger une nouvelle page et il va créer son propre viestate.

  • est ViewState fondamentalement incompatible avec ASP.net Post-Redirect-Get?

Cela dépend de la façon dont vous regardez. Après la redirection de la nouvelle page ne sera pas avoir accès à l'état d'affichage de la page avant.

  • est ASP.net fondamentalement incompatible avec post-Redirect - Get
Non

. Voir l'exemple ci-dessus.

  • comment (à savoir quel code) vous rediriger vers le formulaire Web ASPX "réel"?

Response.Redirect (url). Cela enverra une réponse au navigateur, lui disant de faire une nouvelle demande de get.

  • quand (à savoir dans quel gestionnaire d'événements) redirigez-vous à la ASPX « vrai » formulaire web?

Lorsque vous avez effectué tous les travaux nécessaires pour traiter la demande après.

  • questions connexes soulèvent des questions de la façon dont vous affichez les données de formulaire. Là est l'implication que les formes HTML ne peuvent pas être utilisés - et toutes les données de formulaire doit être ajouté à la chaîne de requête. Est-ce vrai? Si oui, pourquoi? Si non, pourquoi pas? Peut-données de formulaire de vente du navigateur dans une chaîne de requête?

Réorientation une demande après est pas bien supporté et devrait probablement être évitée. Il peut être fait (avec un certain navigateur) en utilisant la réponse http 307. Quand vous faites cela, le serveur indique effectivement le navigateur que « Je ne vais pas vous traiter la demande après, s'il vous plaît publiez sur cette autre page à la place ».

  • une question connexe mentionne Server.Transfer. Server.Transfer est l'aide complètement faux, et ne résout en rien le post-Redirect-Get problème (Parce qu'il n'y a pas Redirect). Correct?

Server.Transfer (...) est quelque chose qui se déroule sur le côté serveur. Le navigateur n'est pas au courant. Fondamentalement, une page peut utiliser Server.Transfer afin d'avoir som autres pagesfaire un peu de traitement, et que la page sera responsable de l'envoi d'un retour de réponse au navigateur. Mais le navigateur pense que c'était la page originale du répondu.

  • quel changement de code doit se produire dans le ASPX ou aspx.cs fichier support PRG? On peut supposer que, à tout le moins, le code doit être modifié pour poster quelque part en plus MyPage.aspx.

Non, un retour de la poste peut être utilisé. L'astuce est d'avoir un (ou plusieurs) gestionnaire d'événements spécifique (s) sur la page qui fait un Repsonse.Redirect après le traitement des données affichées.

Autres conseils

Q) comment l'effectuer un POST à ??un endroit qui n'a pas sa forme originale?

A) Avec PRG, vous ne POST à ??une autre page, vous postez à la même page (voir le diagramme sur la page wikipedia vous lié.) Mais la réponse de cette page doit être une réponse 30X ( typiquement 302).

Q) que devient le ViewState lorsque vous publiez sur un formulaire qui ne lit pas l'état d'affichage?

A) L'état d'affichage est là quand vous POST, mais l'état d'affichage ne sera pas là pour la nouvelle page que vous faites une requête GET sur.

Q) que devient le ViewState lorsque vous redirigez vers le formulaire Web ASPX "réel"?

A) Par-dessus, il n'y a pas d'état plus de vue réorientent à la page.

Q) est ViewState fondamentalement incompatible avec ASP.net?

A) ViewState est pas incompatible avec ASP.NET. Il est (la plupart du temps) inutile P / R / G pour rendre la page que vous êtes redirigé vers.

Q) est ASP.net fondamentalement incompatible avec post-Redirect - Get

A) Non - mais vous ne pouvez pas compter trop sur l'utilisation d'une page et de garder tout votre état en état d'affichage, comme ci-dessus. Cela dit, ASP.MVC est beaucoup mieux cartes à P / R / G

Q) comment (à savoir quel code) vous rediriger vers le formulaire Web ASPX "réel"?

A) Response.Redirect ( "new_page_you_are_redirecting_to.aspx") dans le procédé de bbLaunch_Click old_page_you_are_posting_from.aspx

Q) comment (à savoir ce que l'url) vous rediriger vers le formulaire Web ASPX "réel"? Une question de rapport mentionne Response.Redirect (Request.RawUrl);

A) Voir ci-dessus

Q) quand (à savoir dans quel gestionnaire d'événements) vous rediriger vers le formulaire Web ASPX "réel"?

A) Une fois que vous avez traité la pression d'un bouton, enregistré les données DB (ou session, etc.), et avant que vous avez écrit quoi que ce soit d'autre au flux de réponse.

Q) questions connexes soulèvent des questions de la façon dont vous affichez les données de formulaire. Il y a l'implication que les formes HTML ne peuvent pas être utilisés - et toutes les données du formulaire doivent être ajoutées à la chaîne de requête. Est-ce vrai?

A) Non -. La presse bouton dans ASP.NET WebForms va republier à la page

Q) Si oui, pourquoi? Sinon, pourquoi pas?

A) Il est plus simple que cela, pourquoi pas. Imager deux pages: first_page.asp et second_page.aspx. First_page.aspx a le bouton sur elle (ainsi que d'autres contrôles Web ASP.NET, comme des zones de texte, etc que l'utilisateur a rempli.) Quand ils appuyez sur le bouton, un POST est faite à first_page.aspx. Après le traitement des données (ce qui est à l'intérieur viewstate probable, bien que cela est loin abstraire), vous redirigez l'utilisateur à l'aide second_page.aspx Response.redirect. Second_page.aspx peut afficher ce que vous voulez. Si vous voulez (ou besoin) pour afficher l'interface utilisateur est similaire à ce qui était first_page.aspx, y compris les contrôles et ce qu'ils en entrée, vous souhaitez stocker que dans la session, un cookie, l'URL comme params queryString, pour définir ces contrôles sur second_page.aspx. (Mais vous ne pouvez pas besoin de quoi que ce soit d'affichage sur second_page.aspx qui est similaire à first_page.aspx -. Il n'y a pas de règle générale ici)

Q) Est-ce qu'un des données de formulaire de vente du navigateur dans une chaîne de requête?

A) Oui, si vous définissez la méthode GET au lieu de POST. Vous ne pouvez pas remplacer WebForms pour ce faire, et ce n'est pas nécessaire pour PRG

Q) une question connexe mentionne Server.Transfer. L'utilisation Server.Transfer est complètement faux, et ne résout en rien le problème post-Redirect-Get (car il n'y a pas Redirect). Correct?

A) Essentiellement

Q) quel changement de code doit se produire dans le ASPX ou aspx.cs fichier pour soutenir PRG? On peut supposer que, à tout le moins, le code doit être changé quelque part poste en plus MyPage.aspx.

A) Le code doit encore revenir après (comme mentionné ci-dessus.) Mais MyPage.aspx devrait rediriger vers une nouvelle page dans le gestionnaire de bouton.

Le modèle post-Redirect-Get peut être utilisé dans les formulaires Web. Je l'ai montré comment cela peut être fait en convertissant l'application MVC NerdDinner aux formulaires Web, http://navigationnerddinner.codeplex.com / . J'ai gardé les détails de navigation exactement de la même façon il y a beaucoup d'exemples du modèle PRG.

Cependant, il y a une autre façon d'éviter le problème F5 / Actualiser. Si vous enveloppez votre page dans un UpdatePanel (une partie de ASP.NET Ajax), puis tous les dossiers post seront converties en demandes de pages partielles. Cela signifie que lorsque la touche F5 est enfoncé, il ne rafraîchira la demande GET originale (car il n'y a pas eu de POSTs ultérieures), et donc vous ne serez pas l'avertissement. (Remarque Si JavaScript est désactivé, l'avertissement apparaît encore).

Les étapes exactement de la Poste Redirect Obtenez sont celui-ci:

Vous avez la forme que vous remplissez les données, et après votre valide soumettre (POST) vous les insérez dans votre base de données, et de leur donner un identifiant de confirmation, vous rediriger l'utilisateur vers la page avec cet identifiant de confirmation en tant que paramètre URL qui est utilisé comme (GET) Après la redirection chaque F5-refresh est en lecture seule les données et non les insérer à nouveau.

Le code pour insérer est différent du code qui montre la confirmation, vous pouvez même les faire différentes pages -. Vous pouvez faire la même page avec des zones de texte uniquement lu

La redirection est simple la fonction Responce.Redirect de asp.net

Après le POST et la réalisation du redirect la seule chose que vous connecter avec l'action précédente est le code de confirmation (pas viewstate)

Le moins de cette méthode est qu'il est réellement reconnaît pas l'actualisation, est de faire juste une étape supplémentaire qui rend l'actualisation ne l'insérer à nouveau les mêmes données -. Mais a besoin du code supplémentaire pour les données Get

L'alternative est de reconnaître l'actualisation et ne pas faire redirect. En reconnaître le rafraîchissement sur le post en arrière, vous pouvez éviter d'insérer les mêmes données avec un seul message à l'utilisateur. Il y a quelques exemples sur Internet pour cela, et je dois mettre en œuvre un avec succès.

Un exemple:

Vous pouvez invoquer la Response.Redirect méthode pour aller à un autre endroit.

Il y a deux choses qui vont dans ce.

  1. Définir les Action attribut de la forme sur la page principale (Appelons-le LaunchForm.aspx ) égal à l'URL de la page "proxy" ( ProxyLaunchForm.aspx ).

  2. (facultatif) Ajouter une entrée cachée avec le nom redirectUrl à la forme et la valeur de l'URL qui indique ProxyLaunchForm.aspx où rediriger une fois qu'il est terminé effectuer le lancement (la partie R de PRG).

  3. sur ProxyLaunchForm.aspx , la mise en œuvre devrait avoir lieu à l'intérieur du Page_Load gestionnaire d'événements, parce que cela a accès à former des données post. Exécutez le lancement ici.

  4. Par la suite (aussi dans Page_Load ), effectuer la redirection (soit en utilisant le redirectUrl de # 2, ou en utilisant simplement l'URL de page de référence):

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

    Il y a encore la question de la vue Etat. Je pense que la meilleure façon de traiter ce problème est de changer la façon dont se persista l'état d'affichage. Normalement, il est enregistré dans un élément d'entrée caché sur la page et récupérée lors de la publication (qui de moyens de cours, il serait perdu après la redirection, en raison de la nature sans état de HTTP). Cependant, vous pouvez remplacer les méthodes que les utilisations ASP.net, et l'ont utiliser Session au lieu (cette façon, il sera toujours présent, même après l'action proxy PRG). Alors, enfin ...

  5. LaunchForm.aspx.cs , utiliser comme la classe de base d'un sous-classé Page qui remplace le SavePageStateToPersistenceMedium et LoadPageStateFromPersistenceMedium méthodes pour stocker / les récupérer de la session, plutôt que d'un champ de formulaire caché. Voir ci-dessous (et voici plus d'informations sur la façon dont cela fonctionne. ) .

*

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);
       }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top