1) TempData
Vous permet de stocker des données qui survivront pour une redirection. En interne, il utilise la session comme magasin de sauvegarde, une fois la redirection effectuée, les données sont automatiquement supprimées. Le schéma est le suivant:
public ActionResult Foo()
{
// store something into the tempdata that will be available during a single redirect
TempData["foo"] = "bar";
// you should always redirect if you store something into TempData to
// a controller action that will consume this data
return RedirectToAction("bar");
}
public ActionResult Bar()
{
var foo = TempData["foo"];
...
}
2) ViewBag, ViewData
Vous permet de stocker des données dans une action de contrôleur qui sera utilisée dans la vue correspondante. Cela suppose que l'action renvoie une vue et ne redirige pas. Vit uniquement pendant la demande en cours.
Le schéma est le suivant:
public ActionResult Foo()
{
ViewBag.Foo = "bar";
return View();
}
et dans la vue:
@ViewBag.Foo
ou avec ViewData:
public ActionResult Foo()
{
ViewData["Foo"] = "bar";
return View();
}
et dans la vue:
@ViewData["Foo"]
ViewBag
est juste un wrapper dynamique ViewData
et n'existe que dans ASP.NET MVC 3.
Cela étant dit, aucune de ces deux constructions ne doit jamais être utilisée. Vous devez utiliser des modèles de vue et des vues fortement typées. Le modèle correct est donc le suivant:
Voir le modèle:
public class MyViewModel
{
public string Foo { get; set; }
}
Action:
public Action Foo()
{
var model = new MyViewModel { Foo = "bar" };
return View(model);
}
Vue fortement typée:
@model MyViewModel
@Model.Foo
Après cette brève introduction, répondons à votre question:
Mon exigence est que je veux définir une valeur dans un contrôleur, ce contrôleur redirigera vers ControllerTwo et Controller2 rendra la vue.
public class OneController: Controller
{
public ActionResult Index()
{
TempData["foo"] = "bar";
return RedirectToAction("index", "two");
}
}
public class TwoController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Foo = TempData["foo"] as string
};
return View(model);
}
}
et la vue correspondante ( ~/Views/Two/Index.cshtml
):
@model MyViewModel
@Html.DisplayFor(x => x.Foo)
Il y a aussi des inconvénients à utiliser TempData: si l'utilisateur frappe F5 sur la page cible, les données seront perdues.
Personnellement, je n'utilise pas non plus TempData. C'est parce qu'en interne, il utilise Session et que je désactive la session dans mes applications. Je préfère un moyen plus reposant d'y parvenir. Ce qui est: dans la première action du contrôleur qui effectue le stockage de redirection, l'objet dans votre magasin de données et l'utilisateur l'ID unique généré lors de la redirection. Ensuite, sur l'action cible, utilisez cet identifiant pour récupérer l'objet initialement stocké:
public class OneController: Controller
{
public ActionResult Index()
{
var id = Repository.SaveData("foo");
return RedirectToAction("index", "two", new { id = id });
}
}
public class TwoController: Controller
{
public ActionResult Index(string id)
{
var model = new MyViewModel
{
Foo = Repository.GetData(id)
};
return View(model);
}
}
La vue reste la même.