Quando usar TempData vs Session no asp.net MVC

Eu estou tentando pegar o jeito do framework MVC tão urso comigo.

No momento, a única coisa em que estou usando o armazenamento de session é armazenar o usuário atualmente conectado. Meu site é simples. Para este exemplo, considere três objects de domínio, Pessoa, Reunião e Arquivo. Os usuários podem fazer login e visualizar um perfil “somente para membros” de uma reunião e adicionar arquivos a ela ou visualizar o “perfil” público de uma reunião, caso não estejam conectados.

Portanto, no perfil particular da reunião, com um usuário conectado, eu tenho um link “adicionar arquivos”. Este link direciona para FileContoller.Add (int meetingId). A partir dessa ação, recebo a reunião à qual o usuário deseja adicionar arquivos usando o ID da reunião, mas depois que o formulário é postado, ainda preciso saber em qual reunião o usuário está adicionando arquivos. É aí que está minha pergunta: devo passar a reunião “atualmente interagindo com” por meio de TempData ou adicioná-la ao armazenamento de session?

É assim que tenho atualmente a configuração Adicionar ação, mas não está funcionando:

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}); } 

Editar:

Com base na maioria das respostas, qualquer um pode fornecer exemplos sobre que tipo de dados (além de mensagens) devem ser armazenados em TempData vs Session?

   

    TempData é a session, então eles não são totalmente diferentes. No entanto, a distinção é fácil de entender, porque TempData é para redirecionamentos e redireciona apenas . Então, quando você define uma mensagem em TempData e, em seguida, redireciona, você está usando TempData corretamente.

    No entanto, usar Session para qualquer tipo de segurança é extremamente perigoso. Sessão e associação são totalmente separadas no ASP.NET. Você pode “roubar” sessões de outros usuários e, sim, pessoas atacam sites da Web dessa maneira. Portanto, se desejar interromper seletivamente uma informação de postagem com base no fato de um usuário estar conectado, verificar IsAuthenticated e desejar exibir seletivamente informações com base no tipo de usuário que efetuou login, use um provedor de Função . Como os GETs podem ser armazenados em cache, a única maneira de permitir seletivamente o access a uma ação em um GET é com o AuthorizeAttribute.

    Atualização Em resposta à sua pergunta editada: Você já tem um bom exemplo de uso do TempData em sua pergunta, ou seja, retornando uma mensagem de erro simples após um POST com falha. Em termos do que deve ser armazenado em Session (além de “não muito”), penso apenas em Session como um cache específico do usuário. Como o Cache não específico do usuário, você não deve colocar informações confidenciais de segurança nele. Mas é um bom lugar para colocar coisas que são relativamente caras para procurar. Por exemplo, nosso Site.Master tem o nome completo do usuário exibido nele. Isso é armazenado em um database e não queremos fazer uma consulta ao database para cada página que servimos. (Uma instalação de nosso aplicativo é usada em uma única empresa, portanto, o nome completo de um usuário não é considerado “sensível à segurança”.) Portanto, se você pensar em Session como um cache que varia de acordo com um cookie, você ganhou t estar muito errado.

    O provedor TempData padrão usa a session para que realmente não haja muita distinção, exceto que seu TempData é apagado no final da próxima solicitação. Você deve usar TempData quando os dados precisarem persistir apenas entre duas solicitações, preferencialmente a segunda sendo um redirecionamento para evitar problemas com outras solicitações do usuário – de AJAX, por exemplo – excluindo os dados acidentalmente. Se os dados precisarem persistir por mais tempo do que isso, você deve preencher novamente o TempData ou usar a Session diretamente.

    “Não funciona” não é muito descritivo, mas deixe-me oferecer algumas sugestões.

    Sob o capô, TempData usa a session para armazenar valores. Portanto, não há muita diferença em termos de mecanismos de armazenamento ou algo parecido. No entanto, TempData dura apenas até a próxima solicitação ser recebida.

    Se o usuário fizer uma solicitação de ajax entre as postagens de formulário, o TempData será removido. Qualquer pedido, qualquer que seja, apagará o TempData. Então, é realmente apenas confiável quando você está fazendo um redirecionamento manual.

    Por que você não pode simplesmente renderizar o ID da reunião em um campo oculto no formulário de visualização? Você já está adicionando ao modelo. Como alternativa, adicione-o à sua rota como um parâmetro.

    Você pode usá-lo como por sua exigência. Um esclarecimento pode ser,

    TempData Vs Session

    TempData

    1. TempData nos permite persistir dados para a duração do pedido subsequente único.
    2. O ASP.net MVC expira automaticamente o valor de tempdata uma vez que uma solicitação consecutiva retornou o resultado (significa que está ativo somente até que a exibição de destino esteja totalmente carregada).
    3. É válido apenas para solicitações atuais e subsequentes
    4. TempData tem método Keep para manter o valor de TempData.

      Exemplo:

      TempData.Keep (), TempData.Keep (“EmpName”)

    5. TempData armazenou internamente o valor na variável Session.

    6. Ele é usado para armazenar apenas mensagens únicas, como mensagens de validação, mensagens de erro, etc.

    Sessão:

    1. A session é capaz de armazenar dados muito mais tempo, até que a session do usuário não expire.
    2. A session expirará após o tempo limite da session.
    3. É válido para todos os pedidos.
    4. N / D
    5. As variables ​​da session são armazenadas no object SessionStateItemCollection (que é exposto através da propriedade HttpContext.Session da página).
    6. Ele é usado para armazenar dados de longa duração, como id de usuário, id de function, etc., que são necessários durante toda a session do usuário.

    TempData e session, ambos exigiram typecasting para obter dados e verificar valores nulos para evitar exceção de tempo de execução.

    Eu prefiro manter esse tipo de dados na própria página. Renderize o ID da reunião como uma input oculta, para que ele seja enviado de volta ao controlador. O controlador que manipula a postagem pode, então, alimentar essa ID de reunião de volta para qualquer exibição que será renderizada, de forma que o ID da reunião seja transmitido basicamente pelo tempo que você precisar.

    É como a diferença entre armazenar um valor em uma variável global antes de chamar um método que funcionará nele, em vez de passar o valor diretamente para o método.

    Eu sugeriria a solução da MvcContrib: http://jonkruger.com/blog/2009/04/06/aspnet-mvc-pass-parameters-when-redirecting-from-one-action-to-another/

    Se você não quiser MvcContrib completo, a solução é apenas 1 método + 1 class que você pode facilmente obter de fonts MvcContrib.

    O valor da propriedade TempData é armazenado no estado da session. O valor de TempData persiste até ser lido ou até a session expirar. Se você quiser passar uma vista de controlador de dados para outra vista de controlador, deverá usar TempData.

    Use a session quando os dados precisarem de todo o aplicativo