O que devo fazer se a sessão atual do ASP.NET for nula?

125

No meu aplicativo da web, faço algo assim para ler as variáveis ​​da sessão:

if (HttpContext.Current.Session != null &&  HttpContext.Current.Session["MyVariable"] != null)
{
    string myVariable= (string)HttpContext.Current.Session["MyVariable"];
}

Entendo por que é importante verificar por que o HttpContext.Current.Session ["MyVariable"] é nulo (a variável pode ainda não ter sido armazenada na sessão ou a sessão foi redefinida por vários motivos), mas por que preciso verificar se HttpContext.Current.Sessioné nulo?

Meu entendimento é que a sessão é criada automaticamente pelo ASP.NET, portanto, HttpContext.Current.Session nunca deve ser nulo. Essa suposição está correta? Se puder ser nulo, significa que eu também devo verificá-lo antes de armazenar algo nele:

if (HttpContext.Current.Session != null)
{
    HttpContext.Current.Session["MyVariable"]="Test";
}
else
{
    // What should be done in this case (if session is null)?
    // Is it possible to force the session to be created if it doesn't exist?
}
Anthony
fonte
ASP.NET WebAPI terá comportamento diferente, você pode verificá-lo na sessão Acessando Usando ASP.NET Web API
Tiago Gouvêa

Respostas:

158

Sim, o objeto Session pode ser nulo, mas apenas em determinadas circunstâncias, nas quais você raramente encontrará:

Se você tiver apenas código nas páginas, não encontrará isso. A maior parte do meu código ASP .NET usa Session sem verificar nulo repetidamente. É, no entanto, algo para se pensar se você estiver desenvolvendo um IHttpModule ou se houver outros detalhes nos detalhes do ASP .NET.

Editar

Em resposta ao comentário: A disponibilidade ou não do estado da sessão depende se o evento AcquireRequestState foi executado para a solicitação. É aqui que o módulo de estado da sessão funciona, lendo o cookie da sessão e localizando o conjunto apropriado de variáveis ​​de sessão para você.

AcquireRequestState é executado antes do controle ser entregue à sua página. Portanto, se você estiver chamando outra funcionalidade, incluindo classes estáticas, da sua página, você deve ficar bem.

Se você tiver algumas classes executando a lógica de inicialização durante a inicialização, por exemplo, no evento Application_Start ou usando um construtor estático, o estado da Sessão poderá não estar disponível. Tudo se resume a se há uma solicitação atual e se o AcquireRequestState foi executado.

Além disso, se o cliente tiver desativado os cookies, o objeto Session ainda estará disponível - mas, na próxima solicitação, o usuário retornará com uma nova Sessão vazia. Isso ocorre porque o cliente recebe uma bolsa de estado da Sessão se ainda não a possui. Se o cliente não transportar o cookie da sessão, não temos como identificá-lo como o mesmo, portanto, ele receberá uma nova sessão repetidamente.

driis
fonte
6
Apenas uma atualização rápida que encontrei hoje. A sessão não está disponível no construtor de páginas! Somente no evento Init ou depois disso.
Nuno Agapito
Acabei de encontrar um HttpContext.Current.Session == null é um código chamado por um evento Page_Load de uma página mestre. Aparentemente, isso pode ocorrer no contexto de uma página. Se eu inspecionar o objeto HttpContext.Current, a maioria dos membros será inicializada, mas CurrentNotification e IsPostNotification geram um erro: {System.PlatformNotSupportedException}. Qualquer que seja a causa, esse problema não ocorreu na produção, onde é executada há anos. A plataforma é o Windows Server 2003 R2 SP2, o aplicativo possui a estrutura de destino .Net 3.5 e é executado no IIS com o estado da sessão ativado.
R. Schreurs
Também descobri que, quando o IIS está atendendo a uma solicitação direta de um arquivo de recurso existente no disco, como uma folha de estilos, HttpContext.Current.Sessionpode ser nulo no código em `Application_AcquireRequestState '. A solicitação para a própria página, no entanto, disponibiliza o objeto de sessão para codificar nela. Isso está no MVC.NET 4, pelo menos.
ingredient_15939
Eu acho que também poderia ser nulo se você estiver dentro de uma ação MVC em cache de saída.
user2173353
40

A declaração a seguir não é totalmente precisa:

"Portanto, se você estiver chamando outra funcionalidade, incluindo classes estáticas, da sua página, você deve ficar bem"

Estou chamando um método estático que referencia a sessão através de HttpContext.Current.Session e é nulo. No entanto, estou chamando o método por meio de um método de serviço da web por meio do ajax usando jQuery.

Como descobri aqui, você pode corrigir o problema com um atributo simples no método ou usar o objeto de sessão de serviço da web:

Há um truque, porém, para acessar o estado da sessão em um método da web, você deve ativar o gerenciamento do estado da sessão da seguinte maneira:

[WebMethod (EnableSession = true)]

Ao especificar o valor EnableSession, agora você terá uma sessão gerenciada para brincar. Se você não especificar esse valor, receberá um objeto Session nulo e, mais do que provavelmente, executará exceções de referência nula ao tentar acessar o objeto da sessão.

Obrigado a Matthew Cozier pela solução.

Só pensei em adicionar meus dois centavos.

Ed

Ed Bishop
fonte
1
obrigado Ed, Session estava aparecendo como nulo no método da web - adicionando isso corrigi-lo. 1)
fusi
1
Bem, quando você está ligando para um serviço da Web, usa outra solicitação que não a da página, para que a declaração ainda esteja correta, IMO.
Driis 9/10/12
Documentos do MSDN aqui - the default value is false. Funciona como um encanto.
Benjineer 6/01/15
22

Se sua instância de Sessão for nula e a sua em um arquivo 'ashx', apenas implemente a interface 'IRequiresSessionState'.

Essa interface não possui nenhum membro, portanto, você só precisa adicionar o nome da interface após a declaração da classe (C #):

public class MyAshxClass : IHttpHandler, IRequiresSessionState
mathijsuitmegen
fonte
Muito obrigado, a sessão foi nula na minha classe de login. Quando adicionei este código ao meu manipulador de ashx, ele também transformou a sessão na minha classe
#
Eu acho que isso responde muito bem à pergunta. Muito obrigado.
Sachin Joseph
2

Artigos técnicos do ASP.NET

Recolher tudo Sumário: No ASP.NET, todas as páginas da Web derivam da classe System.Web.UI.Page. A classe Page agrega uma instância do objeto HttpSession para dados da sessão. A classe Page expõe diferentes eventos e métodos para personalização. Em particular, o método OnInit é usado para definir o estado de inicialização do objeto Page. Se a solicitação não possuir o cookie Session, um novo cookie Session será emitido para o solicitante.

EDITAR:

Sessão: Um Conceito para Iniciantes

RESUMO: A sessão é criada quando o usuário envia uma primeira solicitação ao servidor para qualquer página no aplicativo Web, o aplicativo cria a Sessão e envia o ID da Sessão de volta ao usuário com a resposta e é armazenado na máquina do cliente como um pequeno cookie . Idealmente, a "máquina que desativou os cookies, as informações da sessão não serão armazenadas".

adatapost
fonte
2

No meu caso ASP.NET State Servicefoi parado. Alterar o Startup typepara Automatice iniciar o serviço manualmente pela primeira vez resolveu o problema.

Eric
fonte