123 votes

Comment rediriger vers une action en ASP.NET MVC sans perdre les données de la requête ?

Avec ASP.NET MVC, certaines situations (comme la soumission d'un formulaire) peuvent nécessiter l'utilisation d'une fonction RedirectToAction .

C'est le cas lorsque vous rencontrez des erreurs de validation après la soumission d'un formulaire et que vous devez rediriger vers le formulaire, mais que vous souhaitez que l'URL corresponde à l'URL du formulaire et non à la page d'action à laquelle il est soumis.

Comme j'ai besoin que le formulaire contienne à l'origine POST pour la commodité de l'utilisateur et à des fins de validation, comment puis-je faire passer les données par la fonction RedirectToAction() ? Si j'utilise le paramètre viewData, mon POST sont remplacés par les paramètres suivants GET paramètres.

0 votes

Voici une question similaire (sur le même sujet), mais différente de celle-ci. Quoi qu'il en soit, elle peut toujours intéresser ceux qui s'intéressent à cette question : http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get

0 votes

Pourquoi ne renvoyez-vous pas simplement la même vue en cas d'erreur ? RedirectToAction est généralement appelé si le modèle est valide - ou est-ce que j'ai raté quelque chose ?

81voto

Matt Mitchell Points 17005

La solution consiste à utiliser la propriété TempData pour stocker les composants de requête souhaités.

Par exemple :

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Ensuite, dans votre action "Formulaire", vous pouvez aller :

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}

1 votes

RedirectToAction(a => a.Form()) ne compile pas pour moi avec MVCv2, utilisez-vous MVCv3 ?

1 votes

C'était avant MVC1 (2008). Les lambdas ont été supprimés à un moment donné je crois (il y a un projet codeplex MVCContrib qui les réintroduit, bien que vous puissiez aussi bien utiliser leur attribut d'aide à ce stade : stackoverflow.com/questions/1936/ ). Dans mvc2, vous devriez pouvoir utiliser RedirectToAction("Form"), c'est-à-dire le nom en tant que chaîne, bien que je me souvienne vaguement que MVC 2 ou 3 a introduit un attribut d'aide similaire à celui de MVCContrib si vous souhaitez faire des recherches.

37voto

Haacked Points 31070

N'oubliez pas que TempData stocke la collection de formulaires dans la session. Si vous n'aimez pas ce comportement, vous pouvez implémenter la nouvelle interface ITempDataProvider et utiliser un autre mécanisme pour stocker les données temporaires. Je ne ferais pas cela à moins que vous ne sachiez pertinemment (grâce à des mesures et à un profilage) que l'utilisation de l'état de session vous nuit.

13voto

Dan Points 12178

Jetez un coup d'œil à MVCContrib vous pouvez le faire :

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}

8voto

thedeeno Points 12553

Il existe une autre méthode qui permet d'éviter les données tempdata. Le modèle que j'aime consiste à créer une action pour le rendu original et le nouveau rendu du formulaire invalide. Voici comment cela se passe :

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

C'est plus ou moins le cas. Un peu de pseudo. Avec cela, vous pouvez créer 1 vue pour gérer le rendu du formulaire, le réaffichage des valeurs (puisque le formulaire sera rempli avec les valeurs précédentes), et l'affichage des messages d'erreur.

Lorsque l'enregistrement est effectué dans cette action, si celle-ci est valide, le contrôle est transféré à une autre action.

J'essaie de faire en sorte que ce modèle soit facile à mettre en œuvre. Cadre de validation .net au fur et à mesure que nous développons le support pour MVC.

0 votes

J'utilise également TempData. Le problème, tel que je le comprends, avec votre solution Deeno, est que si l'utilisateur rafraîchit la page après avoir envoyé des données invalides, il recevra une confirmation "Souhaitez-vous soumettre à nouveau les données du formulaire". L'utilisation de la solution TempData, comme le dit MattMitchell, élimine ce problème.

0 votes

Cool. Il semble que quelqu'un ait aussi remarqué cette idée de base avec la preview 5.

2voto

lzlstyle Points 98

Si vous souhaitez transmettre des données à l'action redirigée, la méthode que vous pouvez utiliser est la suivante :

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X