web-dev-qa-db-fra.com

Quand utiliser TempData vs Session dans ASP.Net MVC

J'essaie de comprendre le cadre MVC, alors restez avec moi.

À l'heure actuelle, la seule chose pour laquelle j'utilise le magasin de sessions est de stocker l'utilisateur actuellement connecté. Mon site Web est simple. Pour cet exemple, considérez trois objets de domaine, Personne, Réunion et Fichier. Les utilisateurs peuvent se connecter et afficher le profil "réservé aux membres" d'une réunion et peuvent y ajouter des fichiers ou afficher le "profil" public d'une réunion s'ils ne sont pas connectés.

Ainsi, à partir du profil privé de la réunion, avec un utilisateur connecté, j'ai un lien "ajouter des fichiers". Ce lien route vers FileContoller.Add (int meetingId). À partir de cette action, j'obtiens la réunion à laquelle l'utilisateur souhaite ajouter des fichiers à l'aide de l'ID de réunion, mais après la publication du formulaire, j'ai toujours besoin de savoir à quelle réunion l'utilisateur ajoute des fichiers. C'est là que réside ma question, dois-je passer la réunion "actuellement en interaction avec" via TempData, ou l'ajouter au magasin de sessions?

Voici comment j'ai actuellement la configuration de l'action Ajouter, mais cela ne fonctionne pas:

    public ActionResult Add(int meetingId)
    {
        try
        {
            var meeting = _meetingsRepository.GetById(meetingId);
            ViewData.Model = meeting;
            TempData[TempDataKeys.CurrentMeeting] = meeting; /* add to tempdata here */
        }
        catch (Exception)
        {
            TempData[TempDataKeys.ErrorMessage] = "Unable to add files to this meeting.";
            return RedirectToRoute("MeetingsIndex");
        }

        return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Add(FormCollection form)
    {
        var member = Session[SessionStateKeys.Member] as Member;
        var meeting = TempData[TempDataKeys.CurrentMeeting] as Meeting; /* meeting ends up null here */

        if (member == null)
        {
            TempData[TempDataKeys.ErrorMessage] = "You must be logged in to add files to an meeting.";
            return RedirectToRoute("LoginPage");
        }

        if (meeting == null) 
        {
            TempData[TempDataKeys.ErrorMessage] = "An error occurred. No meeting selected.";
            return RedirectToRoute("MeetingsIndex");
        }

            // add files to meeting

        TempData[TempDataKeys.Notification] = "Successfully added.";
        return RedirectToRoute("AddFiles", new {meetingId = meeting.MeetingId});
}

Modifier:

Sur la base de la plupart des réponses, quelqu'un peut-il fournir des exemples sur le type de données (autres que les messages) à stocker dans TempData vs Session?

60
scottm

TempData est une session, ils ne sont donc pas entièrement différents. Cependant, la distinction est facile à comprendre, car TempData est destiné aux redirections et aux redirections uniquement . Ainsi, lorsque vous définissez un message dans TempData puis redirigez, vous utilisez correctement TempData.

Cependant, l'utilisation de Session pour tout type de sécurité est extrêmement dangereuse. La session et l'appartenance sont entièrement distinctes dans ASP.NET. Vous pouvez "voler" des sessions à d'autres utilisateurs , et oui, les gens attaquent les sites Web de cette façon. Donc, si vous souhaitez arrêter de manière sélective une information de publication en fonction de la connexion d'un utilisateur, consultez IsAuthenticated , et si vous souhaitez afficher de manière sélective des informations en fonction du type d'utilisateur connecté, vous utilisez a Fournisseur de rôles . Étant donné que les GET peuvent être mis en cache, la manière uniquement d'autoriser sélectivement l'accès à une action dans une GET est avec AuthorizeAttribute.

Mise à jour En réponse à votre question modifiée: Vous avez déjà un bon exemple d'utilisation de TempData dans votre question, à savoir, renvoyer un message d'erreur simple après un POST échoué . En termes de ce qui devrait être stocké dans Session (au-delà de "pas beaucoup"), je pense simplement à Session comme un cache spécifique à l'utilisateur. Comme le cache non spécifique à l'utilisateur, vous ne devez pas y mettre d'informations sensibles à la sécurité. Mais c'est un bon endroit pour coller des choses qui sont relativement chères à rechercher. Par exemple, notre Site.Master contient le nom complet de l'utilisateur. Cela est stocké dans une base de données, et nous ne voulons pas faire une requête de base de données pour chaque page que nous servons. (Une installation de notre application est utilisée dans une seule entreprise, donc le nom complet d'un utilisateur n'est pas considéré comme "sensible à la sécurité".) Donc, si vous considérez Session comme un cache qui varie en fonction d'un cookie que l'utilisateur a, vous gagnerez " Je me trompe de loin.

89
Craig Stuntz

Le fournisseur TempData par défaut utilise la session, il n'y a donc pas vraiment de distinction, sauf que votre TempData est effacé à la fin de la prochaine demande. Vous devez utiliser TempData lorsque les données doivent seulement persister entre deux demandes, de préférence la deuxième étant une redirection pour éviter les problèmes avec d'autres demandes de l'utilisateur - d'AJAX, par exemple - supprimant les données accidentellement. Si les données doivent persister plus longtemps que cela, vous devez soit repeupler le TempData ou utiliser la session directement.

17
tvanfosson

"Cela ne fonctionne pas" n'est pas très descriptif, mais permettez-moi de faire quelques suggestions.

Sous le capot, TempData utilise Session pour stocker des valeurs. Il n'y a donc pas beaucoup de différence en termes de mécanismes de stockage ou quelque chose comme ça. Cependant, TempData ne dure que jusqu'à la réception de la prochaine demande.

Si l'utilisateur fait une demande ajax entre les messages du formulaire, TempData est parti. Toute demande quelle qu'elle soit effacera TempData. Il n'est donc vraiment fiable que lorsque vous effectuez une redirection manuelle.

Pourquoi ne pouvez-vous pas simplement afficher simplement l'ID de réunion dans un champ masqué de votre formulaire Afficher? Vous l'ajoutez déjà au modèle. Vous pouvez également l'ajouter à votre itinéraire en tant que paramètre.

4
womp

Vous pouvez l'utiliser selon vos besoins. Une clarification peut être,

TempData Vs Session

TempData

  1. TempData nous permet de conserver des données pendant la durée d'une seule demande ultérieure.
  2. ASP.net MVC expirera automatiquement la valeur de tempdata une fois que la requête consécutive aura renvoyé le résultat (cela signifie qu'il ne vivra que jusqu'à ce que la vue cible soit complètement chargée).
  3. Il n'est valable que pour la demande actuelle et ultérieure uniquement
  4. TempData a la méthode Keep pour conserver la valeur de TempData.

    Exemple:

    TempData.Keep (), TempData.Keep ("EmpName")

  5. TempData a stocké en interne la valeur dans la variable Session.

  6. Il est utilisé pour stocker uniquement des messages uniques comme des messages de validation, des messages d'erreur, etc.

Session:

  1. La session est capable de stocker des données beaucoup plus longtemps, jusqu'à ce que la session utilisateur n'expire pas.
  2. La session expirera après l'expiration de la session.
  3. Il est valable pour toutes les demandes.
  4. N/A
  5. Les variables de session sont stockées dans l'objet SessionStateItemCollection (qui est exposé via la propriété HttpContext.Session de la page).
  6. Il est utilisé pour stocker des données à longue durée de vie comme l'ID utilisateur, l'ID de rôle, etc., qui ont été nécessaires tout au long de la session utilisateur.

TempData et session, tous deux nécessitant une conversion de type pour obtenir des données et vérifier les valeurs nulles pour éviter les exceptions d'exécution.

4
iamCR

Je préfère conserver ce type de données dans la page elle-même. Rendez meetingID en tant qu'entrée masquée, afin qu'il soit renvoyé au contrôleur. Le contrôleur qui gère la publication peut ensuite renvoyer cet ID de réunion à la vue qui sera rendue, de sorte que l'ID de réunion soit essentiellement transmis aussi longtemps que vous en avez besoin.

C'est un peu comme la différence entre le stockage d'une valeur dans une variable globale avant d'appeler une méthode qui fonctionnera dessus, par rapport à la transmission directe de la valeur à la méthode.

0
RedFilter

La valeur de la propriété TempData est stockée dans l'état de session. La valeur de TempData persiste jusqu'à sa lecture ou jusqu'à l'expiration de la session. Si vous souhaitez transmettre des données d'une vue de contrôleur à une autre vue de contrôleur, vous devez utiliser TempData.

Utiliser la session lorsque les données ont besoin pour l'ensemble de l'application

0
Mervin

Je suggère la solution de MvcContrib: http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/ =

Si vous ne voulez pas de MvcContrib complet, la solution est seulement 1 méthode + 1 classe que vous pouvez facilement extraire des sources MvcContrib.

0
queen3