Question Post-Redirect Obtenir dans ASP.NET MVC et la validation avec les URL Restful


J'ai une URL reposante pour l'action d'édition d'une page. Ceci est implémenté sur le contrôleur en tant que méthode Edit, qui accepte les requêtes GET et une méthode Edit qui accepte les requêtes POST.

Cela signifie que vous pouvez visiter l'URL Edit et afficher un formulaire pour un GET ou enregistrer un formulaire pour un POST.

[HttpGet]
public ActionResult Edit(int id) {
    ...
}

[HttpPost]
public ActionResult Edit(EditModel model) {
    ...
}

Le modèle Post-Redirect-Get (PRG) semble assez noir et blanc, car il redirige essentiellement chaque POST vers une action GET. Cependant, je dois être convaincu que c'est la bonne chose à faire.

Mon plan est que dans l'action POST, si le modèle est valide, j'utiliserai le modèle Post-Redirect-Get pour envoyer l'utilisateur vers un emplacement raisonnable (probablement l'action Index ou Details).

Cependant, s'il y a un problème de validation de modèle, je veux toujours simplement afficher la vue. Je ne veux pas rediriger l'utilisateur, car cela signifie mettre le modèle et ModelState dans des données temporaires et les rediriger vers l'action GET - puis ajouter de la logique à l'action GET pour gérer les données temporaires. Je pourrais éviter tout cela en affichant simplement la vue.

Oui, si l'utilisateur appuie sur F5, il soumettra à nouveau le formulaire et il sera présenté avec l'avertissement de resoumission, mais la même page (lui demandant de corriger les erreurs de validation). Cependant, il semble peu probable qu'ils atteignent F5 et il n'y a pas non plus de risque de double soumission car le formulaire échouera simplement une fois de plus.

Si la validation réussit, l'utilisateur sera redirigé et sera à l'abri des doubles soumissions.

Alors, devrais-je implémenter des données de code et de données supplémentaires dans les données temporaires afin de suivre strictement le modèle PRG, ou est-il plus judicieux d'utiliser le modèle PRG lorsque le formulaire est valide et que les données sont stockées?


17
2018-04-04 11:48


origine


Réponses:


Vous ne devez effectuer la redirection que si les informations du formulaire sont valides. dans le cas d'erreurs de soumission, renvoyez la vue à partir de la même méthode Edit.

Faire comme ça est conforme à PRG, car si votre modèle n'est pas valide, vous ne permettez aucune modification à l'état des objets sur le serveur. PRG est conçu principalement pour empêcher plusieurs publications susceptibles de modifier l'état des objets du serveur (objets métier, tables de base de données, etc.) de manière imprévisible. Dans votre exemple de validation, toutefois, l'utilisateur peut renvoyer autant de fois qu'il le souhaite et il sera toujours renvoyé à la vue initiale avec des erreurs de validation - rien sur le serveur ne change. Par conséquent, vous avez raison: n'émettez que la redirection si votre modèle réussit la validation dans votre niveau de présentation.


21
2018-04-04 12:49



Même si La réponse de Ken met en évidence un fait important - PRG ne signifie pas nécessairement "retourner aveuglément une redirection lors de la publication" - il se peut que vous souhaitiez toujours faire une redirection et préserver parfois state_state.

La manière la plus simple de gérer ce scénario consiste à utiliser des filtres d'action pour exporter modelstate vers la session (avant la redirection), puis à importer modelstate (avant d'exécuter la nouvelle action). Kazi Manzur Rashid a quelques excellents billets de blog (Partie 1  Partie 2) sur les meilleures pratiques dans ASP.NET MVC. Ils sont assez vieux, mais beaucoup de conseils sont encore très applicables. Astuce numéro 13 dans le Premier article est exactement ce que vous recherchez.


10
2018-04-04 13:03



La PRG est la bonne chose à faire.

Vous effectuez un test POST vers l'action et si modelstate n'est pas valide, il vous suffit d'exporter vos données d'états de modèle dans une variable et de les rediriger vers l'action get.

Cela présente l'avantage, contrairement à la réponse acceptée, que vous n'avez pas besoin de réécrire le code sur l'action [Publier] pour recréer la vue.

sur l'action get, vous chargez le ModelState exporté depuis le post.

TempData est un excellent endroit pour faire ce genre de choses, le code sera quelque chose comme ceci:

[HttpGet]
public ActionResult Edit(int id) {
    // import model state from tempdata
    ...
}

[HttpPost]
public ActionResult Edit(EditModel model) {
    // if modelstate is invalid
    // save modelstate in tempdata
    // redirect to Edit/{id}
    // else 
    ...
    RedirectToAction("List")
}

cela peut être automatisé en utilisant AttributeFilters, il y a un excellent post créer par @ ben-foster ici:

Validation automatique du Modelstate


-1
2018-06-13 19:00