Comment RedirectToAction dans ASP.NET MVC sans perdre les données de la demande

123

À l'aide d'ASP.NET MVC, certaines situations (telles que la soumission de formulaires) peuvent nécessiter un fichier RedirectToAction.

Une telle situation est 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 reflète l'URL du formulaire, pas la page d'action à laquelle il se soumet.

Comme j'exige que le formulaire contienne les POSTdonnées initialement éditées, pour la commodité de l'utilisateur, ainsi qu'à des fins de validation, comment puis-je transmettre les données via le RedirectToAction()? Si j'utilise le paramètre viewData, mes POSTparamètres seront remplacés par des GETparamètres.

Matt Mitchell
la source
Voici une question similaire (sur le même sujet), mais différente de celle-ci. Quoi qu'il en soit, cela peut encore intéresser ceux qui s'intéressent à cette question: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Chris Pietschmann
Pourquoi ne renvoyez-vous pas simplement la même vue en cas d'erreur? RedirectToAction est généralement appelée si le modèle est valide - ou est-ce que je manque quelque chose?!
niico le

Réponses:

81

La solution consiste à utiliser la propriété TempData pour stocker les composants Request 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);
}
Matt Mitchell
la source
1
RedirectToAction (a => a.Form ()) ne compile pas pour moi en utilisant MVCv2, utilisez-vous MVCv3?
ChrisAnnODell
1
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 accéder à RedirectToAction ("Form"), c'est-à-dire le nom sous forme de chaîne, bien que je me souvienne vaguement que MVC 2 ou 3 a introduit un attribut d'assistance similaire à celui de MVCContrib si vous souhaitez faire une recherche.
Matt Mitchell
37

Gardez à l'esprit que TempData stocke la collection de formulaires en 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 avec certitude (via la mesure et le profilage) que l'utilisation de l'état de session vous fait mal.

Haacked
la source
13

Jetez un œil à MVCContrib , vous pouvez le faire:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
Dan
la source
8

Il existe un autre moyen qui évite les données temp. Le modèle que j'aime consiste à créer une action pour le rendu d'origine et le rendu du formulaire invalide. Ca fait plutot comme ca:

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 modèle. Un petit pseudo-jouet. Avec cela, vous pouvez créer 1 vue pour gérer le rendu du formulaire, réafficher les valeurs (puisque le formulaire sera rempli avec les valeurs précédentes) et afficher les messages d'erreur.

Lors de la publication de cette action, si elle est valide, elle transfère le contrôle à une autre action.

J'essaie de rendre ce modèle facile dans le cadre de validation .net lorsque nous développons la prise en charge de MVC.

Dane O'Connor
la source
J'utilise également TempData, le problème tel que je le comprends, avec votre solution Deeno est que si l'utilisateur devait actualiser la page après avoir publié des données invalides, il recevrait 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.
user10479
Cool. Il semble que quelqu'un ait également remarqué cette idée de base avec l'aperçu 5.
Matt Mitchell
2

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

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

TempData est la solution qui garde les données d'action en action.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Aswal
la source