HttpContext.Current.Session равен нулю

#c# #asp.net

#c# #asp.net

Вопрос:

У меня есть веб-сайт с пользовательским объектом кэша внутри библиотеки классов. Все проекты работают под управлением .NET 3.5. Я хотел бы преобразовать этот класс для использования состояния сеанса вместо кэша, чтобы сохранить состояние на сервере состояний при повторной загрузке моего приложения. Однако этот код выдает исключение с «HttpContext.Current.Сеанс равен нулю «, когда я посещаю методы из моего глобального файла.asax. Я вызываю класс следующим образом:

 Customer customer = CustomerCache.Instance.GetCustomer(authTicket.UserData);
  

Почему объект всегда равен нулю?

 public class CustomerCache: System.Web.SessionState.IRequiresSessionState
{
    private static CustomerCache m_instance;

    private static Cache m_cache = HttpContext.Current.Cache;

    private CustomerCache()
    {
    }

    public static CustomerCache Instance
    {
        get
        {
            if ( m_instance == null )
                m_instance = new CustomerCache();

            return m_instance;
        }
    }

    public void AddCustomer( string key, Customer customer )
    {
        HttpContext.Current.Session[key] = customer;

        m_cache.Insert( key, customer, null, Cache.NoAbsoluteExpiration, new TimeSpan( 0, 20, 0 ), CacheItemPriority.NotRemovable, null );
    }

    public Customer GetCustomer( string key )
    {
        object test = HttpContext.Current.Session[ key ];

        return m_cache[ key ] as Customer;
    }
}
  

Как вы можете видеть, я пытался добавить IRequiresSessionState в класс, но это не имеет значения.

Приветствую, Йенс

Комментарии:

1. Если вы попытаетесь получить доступ к сеансу из Application_Start, текущего сеанса еще нет.

Ответ №1:

На самом деле речь идет не о включении состояния внутри вашего класса, а скорее о том, где вы вызываете его в своем Global.asax. Сеанс доступен не во всех методах.

Рабочим примером может быть:

 using System.Web.SessionState;

// ...

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState)
        {
            HttpContext context = HttpContext.Current;
            // Your Methods
        }
    }
  

Это не будет работать, например, в Application_Start

Комментарии:

1. Я вызываю это в void Application_AuthenticateRequest (отправитель объекта, EventArgs e), так что это не выход?

2. Да, это бесполезно, при вызове этого метода сеанс всегда равен нулю, вы можете протестировать это, просто отладив и проверив, Context.Handler является ли это либо IRequiresSessionState , либо IReadOnlySessionState , чего никогда не бывает. Однако, основываясь на том, что я сделал, Application_PreRequestHandlerExecute работает для этого, хотя я не уверен в ваших целях.

Ответ №2:

В зависимости от того, что вы пытаетесь сделать, вы также можете извлечь выгоду из использования Session_Start и Session_End в Global.asax:

http://msdn.microsoft.com/en-us/library/ms178473 (v = против100).aspx

http://msdn.microsoft.com/en-us/library/ms178581 (v = против100).aspx

 void Session_Start(object sender, EventArgs e)
{
    // Code that runs when a new session is started

}

void Session_End(object sender, EventArgs e)
{
    // Code that runs when a session ends. 
    // Note: The Session_End event is raised only when the sessionstate mode
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised.

}
  

Обратите внимание на ограничения в режиме SessionState, прежде чем полагаться на Session_End.