ViewBag, ViewData et TempData

209

Tout organisme pourrait-il expliquer quand utiliser

  1. TempData
  2. ViewBag
  3. ViewData

J'ai une exigence, où je dois définir une valeur dans un contrôleur, que le contrôleur redirige vers le contrôleur deux et le contrôleur deux rendra la vue.

J'ai essayé d'utiliser ViewBag, la valeur est perdue au moment où j'atteins le contrôleur deux.

Puis-je savoir quand l'utiliser et quels sont ses avantages ou ses inconvénients?

Merci

Hari Gillala
la source
5
C'est un excellent article qui explique les différences.
Beku
1
stackoverflow.com/a/17199709/2015869
Imad Alazani
2
Vérifiez ce ViewData Vs ViewBag Vs TempData
user2794034

Réponses:

293

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"]

ViewBagest juste un wrapper dynamique ViewDataet 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.

Darin Dimitrov
la source
57
Excellente réponse, mais je ne suis pas d'accord avec l'énoncé dogmatique "aucune de ces deux constructions ne devrait jamais être utilisée". J'ai trouvé quelques utilisations légitimes du ViewBag. Par exemple, j'ai défini une ViewBag.Titlepropriété sur toutes mes vues qui est utilisée dans mon _Layout.cshtmlfichier de vue de base. Un autre cas où je l'utilise est de donner des messages d'information (par exemple "Produit enregistré avec succès!") Aux utilisateurs. J'ai placé un balisage générique Layout.cshtmlpour rendre un message s'il est fourni et cela me permet de définir ViewBag.Messageune action. L'utilisation d'une propriété ViewModel pour l'un ou l'autre cas présente trop d'inconvénients.
Jesse Webb
22
Je dois être d'accord avec Jesse, bien que ce soit une excellente description, affirmant ouvertement qu'il n'y a aucune bonne raison d'utiliser ViewBag est une question d'opinion, pas une question de fait. C'est certainement une mauvaise pratique de sur-utiliser le ViewBag, et certains développeurs tombent dans ce piège, mais utilisé avec goût, c'est une ressource puissante.
Ron DeFreitas
1
@ ron.defreitas, d'accord, dites-moi alors une bonne raison pour laquelle vous utiliseriez ViewBag. Veuillez décrire un scénario spécifique du monde réel, lorsque ViewBag a une certaine utilité. Puisque vous dites que c'est le cas, je cite une ressource puissante , je suppose que vous avez des cas spécifiques où cette ressource puissante est puissante . Comme je ne l'ai jamais utilisé dans ma carrière, je serais très heureux d'apprendre comment les gens utilisent cette arme puissante .
Darin Dimitrov
27
Nous avons un élitiste ici. Darin, Jesse a spécifiquement mentionné un tel exemple. Le simple fait qu'il existe toujours d'autres façons de faire ne nie pas automatiquement leur utilité.
Djentleman
2
@DarinDimitrov: J'ai un scénario en ce moment où je dois transmettre des informations à la vue depuis une méthode d'attribut. L'utilisation de filterContext.Controller.ViewData est beaucoup plus facile que d'essayer de le passer à une vue fortement typée. Cela dit, merci pour votre explication, cela a été très utile.
Andy
15

ASP.NET MVC nous offre trois options ViewData, ViewBag et TempData pour transmettre les données du contrôleur à la vue et à la prochaine demande. ViewData et ViewBag sont presque similaires et TempData exerce une responsabilité supplémentaire. Permet de discuter ou d'obtenir des points clés sur ces trois objets:

Similitudes entre ViewBag et ViewData:

  • Aide à conserver les données lorsque vous passez du contrôleur à la vue.
  • Utilisé pour transmettre les données du contrôleur à la vue correspondante.
  • Une durée de vie courte signifie que la valeur devient nulle lorsque la redirection se produit. En effet, leur objectif est de fournir un moyen de communiquer entre les contrôleurs et les vues. C'est un mécanisme de communication au sein de l'appel serveur.

Différence entre ViewBag et ViewData:

  • ViewData est un dictionnaire d'objets dérivé de la classe ViewDataDictionary et accessible à l'aide de chaînes comme clés.
  • ViewBag est une propriété dynamique qui tire parti des nouvelles fonctionnalités dynamiques de C # 4.0.
  • ViewData nécessite une conversion de type pour les types de données complexes et vérifiez les valeurs nulles pour éviter les erreurs.
  • ViewBag ne nécessite pas de transtypage pour les types de données complexes.

Exemple ViewBag & ViewData:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

En vue:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData est également un dictionnaire dérivé de la classe TempDataDictionary et stocké dans une session de courte durée et c'est une clé chaîne et une valeur d'objet. La différence est que le cycle de vie de l'objet. TempData conserve les informations pendant la durée d'une requête HTTP. Cela ne signifie que d'une page à l'autre. Cela fonctionne également avec une redirection 302/303 car elle se trouve dans la même requête HTTP. Aide à conserver les données lorsque vous passez d'un contrôleur à un autre contrôleur ou d'une action à une autre. En d'autres termes, lorsque vous redirigez, «TempData» permet de conserver les données entre ces redirections. Il utilise en interne des variables de session. L'utilisation des données temporaires pendant la demande actuelle et suivante signifie uniquement qu'elles sont utilisées lorsque vous êtes sûr que la prochaine demande sera redirigée vers la vue suivante. Il nécessite une conversion de type pour les types de données complexes et vérifiez les valeurs nulles pour éviter les erreurs.

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

Le dernier mécanisme est la session qui fonctionne comme le ViewData, comme un dictionnaire qui prend une chaîne pour clé et un objet pour valeur. Celui-ci est stocké dans le cookie client et peut être utilisé beaucoup plus longtemps. Il faut également plus de vérification pour ne jamais avoir d'informations confidentielles. Concernant ViewData ou ViewBag, vous devez l'utiliser intelligemment pour les performances de l'application. Parce que chaque action passe par tout le cycle de vie d'une demande mvc asp.net régulière. Vous pouvez utiliser ViewData / ViewBag dans votre action enfant, mais veillez à ne pas l'utiliser pour remplir les données non liées qui peuvent polluer votre contrôleur.

Abdur Rahman
la source
11

TempData

Fondamentalement, c'est comme un DataReader, une fois lu, les données seront perdues.

Regardez cette vidéo

Exemple

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

Si vous faites attention au code ci-dessus, RedirectToAction n'a aucun impact sur TempData jusqu'à ce que TempData soit lu. Ainsi, une fois TempData lu, les valeurs seront perdues.

Comment puis-je conserver le TempData après la lecture?

Vérifiez la sortie dans Action Method Test 1 et Test 2

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

Si vous faites attention au code ci-dessus, les données ne sont pas perdues après RedirectToAction ainsi qu'après la lecture des données et la raison en est que nous utilisons TempData.Keep(). est-ce

De cette façon, vous pouvez également le faire persister aussi longtemps que vous le souhaitez dans d'autres contrôleurs.

ViewBag / ViewData

Les données resteront dans la vue correspondante


la source
4

TempData dans Asp.Net MVC est l'une des fonctionnalités très utiles. Il est utilisé pour transmettre des données de la demande actuelle à la demande suivante. En d'autres termes, si nous voulons envoyer des données d'une page à une autre pendant que la redirection se produit, nous pouvons utiliser TempData, mais nous devons faire un peu de réflexion dans le code pour obtenir cette fonctionnalité dans MVC. Parce que la durée de vie de TempData est très courte et ne réside que jusqu'à ce que la vue cible soit entièrement chargée. Mais, nous pouvons utiliser la méthode Keep () pour conserver les données dans TempData.

Lire la suite

Anil Sharma
la source
3

ViewBag, ViewData, TempData et View State dans MVC

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ASP.NET MVC nous offre trois options ViewData, VieBag et TempData pour transmettre les données du contrôleur à la vue et à la prochaine demande. ViewData et ViewBag sont presque similaires et TempData exerce une responsabilité supplémentaire.

Similitudes entre ViewBag et ViewData:

Aide à conserver les données lorsque vous passez du contrôleur à la vue. Utilisé pour transmettre les données du contrôleur à la vue correspondante. Une durée de vie courte signifie que la valeur devient nulle lorsque la redirection se produit. En effet, leur objectif est de fournir un moyen de communiquer entre les contrôleurs et les vues. C'est un mécanisme de communication au sein de l'appel serveur.

Différence entre ViewBag et ViewData:

ViewData est un dictionnaire d'objets dérivé de la classe ViewDataDictionary et accessible à l'aide de chaînes comme clés. ViewBag est une propriété dynamique qui tire parti des nouvelles fonctionnalités dynamiques de C # 4.0. ViewData nécessite une conversion de type pour les types de données complexes et vérifiez les valeurs nulles pour éviter les erreurs. ViewBag ne nécessite pas de transtypage pour les types de données complexes.

Exemple ViewBag & ViewData:

public ActionResult Index()

{  
    ViewBag.Name = "Arun Prakash";
    return View();    
}

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return View(); 
}

Dans View, nous appelons comme ci-dessous:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Aide à conserver les données lorsque vous passez d'un contrôleur à un autre contrôleur ou d'une action à une autre. En d'autres termes, lorsque vous redirigez, «Tempdata» permet de conserver les données entre ces redirections. Il utilise en interne des variables de session. TempData est censé être une instance de très courte durée, et vous ne devez l'utiliser que pendant les requêtes en cours et suivantes uniquement

Le seul scénario où l'utilisation de TempData fonctionnera de manière fiable est lorsque vous redirigez. En effet, une redirection tue la demande actuelle (et envoie le code d'état HTTP 302 Objet déplacé au client), puis crée une nouvelle demande sur le serveur pour servir la vue redirigée.

Il nécessite une conversion de type pour les types de données complexes et vérifiez les valeurs nulles pour éviter les erreurs.

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  
Arun Prakash
la source
1
void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 
Saineshwar
la source
1

TempData sera toujours disponible jusqu'à la première lecture, une fois que vous l'avez lu, il n'est plus disponible. ViewBag Il est plus utile lorsque vous passez rapidement des données à la vue, normalement vous devez passer toutes les données à la vue via le modèle, mais il y a des cas où vous modélisez directement à partir d'une classe qui est mappée dans la base de données comme le cadre d'entité dans ce cas, vous ne pas quoi changer votre modèle pour passer un nouveau morceau de données, vous pouvez le coller dans le viewbag ViewData est juste une version indexée de ViewBag et a été utilisé avant MVC3

David Fawzy
la source
0

La portée est également différente entre viewbag et temptdata. viewbag est basé sur la première vue (non partagé entre les méthodes d'action) mais les temptdata peuvent être partagées entre une méthode d'action et juste entre elles.

Elnaz
la source