Skip to main content
ATL Server Library Reference 
Session-State Tasks 

To add session-state support to an existing ATL Server ISAPI extension DLL

  1. Add an instance of the CSessionStateService class to the CIsapiExtension-derived class. The following example code declares a data member called m_SessionStateSvc:

    protected:
    typedef CSessionStateService<CWorkerThread<>, CMemSessionServiceImpl> sessionSvcType;
    CComObjectGlobal<sessionSvcType> m_SessionStateSvc;

    The CMemSessionServiceImpl template argument indicates that the memory-backed session-state implementation will be used. Alternately, the CDBSessionServiceImplT class can be used for database-backed support.

  2. Modify the existing GetExtensionVersion method, or, if one does not exist, override the base class version. The GetExtensionVersion method should initialize the CSessionStateService object by calling its Initialize method, like this:

    BOOL GetExtensionVersion(HSE_VERSION_INFO* pVer)
    {
       if (!baseISAPI::GetExtensionVersion(pVer))
       {
          return FALSE;
       }
       if (S_OK != m_SessionStateSvc.Initialize(&m_WorkerThread,
                                     static_cast<IServiceProvider*>(this)))
       {
          TerminateExtension(0);
          return FALSE;
       }
       return TRUE;
    }
  3. Ensure that the TerminateExtension method is overridden, and modify it so that it terminates the session service object using the CSessionStateService::Shutdown method:

    BOOL TerminateExtension(DWORD dwFlags)
    {
       BOOL bRet = baseISAPI::TerminateExtension(dwFlags);
       m_SessionStateSvc.Shutdown();
       return bRet;
    }
  4. Override the QueryService method to support the retrieval of the ISessionStateService interface:

    HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, 
             REFIID riid, void** ppvObject)
    {
       if (InlineIsEqualGUID(guidService, __uuidof(ISessionStateService)))
             return m_SessionStateSvc.QueryInterface(riid, ppvObject);
       return baseISAPI::QueryService(guidService, riid, ppvObject);
    }

To use session-state in an ATL Server request handler

  1. Include the AtlSession.h header file in your project:

    #include <atlsession.h>
  2. Add two data members to the request handler class for use in manipulating the ISessionStateService and ISession interfaces:

    CComPtr<ISessionStateService> m_spSessionService;
    CComPtr<ISession> m_spSession;
  3. Within the request handler's ValidateAndExchange method, request the ISessionStateService interface from the ISAPI extension DLL using the IServiceProviderImpl::QueryService method (this call will fail if the ISAPI extension DLL does not include session-state support):

    HRESULT hr = m_spServiceProvider->QueryService(__uuidof(ISessionStateService), &m_spSessionService);

    (Use steps 4 and 5 if an existing session is to be retrieved.)

  4. Retrieve the session cookie from the client request object. In this example, the ATL Server SESSION_COOKIE_NAME macro is used for the session cookie name:

    m_HttpRequest.Cookies(SESSION_COOKIE_NAME).GetValue(sessionID)
  5. If a session cookie is found, use it to attempt the retrieval of an existing session using the ISessionStateService::GetSession method. If the session cookie length is zero, no session cookie is present in the client request, so no session can be retrieved:

    if (sessionID.GetLength())
       hr = m_spSessionService->GetSession(sessionID, &m_spSession);

    (Use steps 6 and 7 if a new session is to be created)

  6. Use the ISessionStateService::CreateNewSession method to create a new session along with a corresponding session ID:

    const size_t nCharacters = 64;
    CHAR szID[nCharacters + 1];
    szID[0] = 0;
    DWORD dwCharacters = nCharacters;
    hr = m_spSessionService->CreateNewSession(szID, &dwCharacters, &m_spSession);

    This code demonstrates how to create a session ID that is less than or equal to 64 characters in length.

  7. If the call to CreateNewSession succeeds, attach the new session ID to the server response using the CHttpResponse::AppendCookie method:

    if (SUCCEEDED(hr))
    {
       CSessionCookie theSessionCookie( szID );
       m_HttpResponse.AppendCookie( &theSessionCookie );
    }
  8. Either by creating a new session, or retrieving an existing one, the m_spSession pointer is now initialized and ready for use in storing or retrieving session data. Use the ISession::SetVariable method to add or modify session data and the ISession::GetVariable method to retrieve data. See the SessionSettings Sample for an example of using session data storage.

To convert from memory to database-backed session-state support

  1. Modify the CSessionStateService declaration within your ISAPI extension DLL project to use the desired session-state implementation. Use CMemSessionServiceImpl for memory support and CDBSessionServiceImplT for database support.

  2. Change the arguments passed to the CSessionStateService::Initialize method by the GetExtensionVersion method to reflect the underlying scheme.

    For memory-backed support, the Initialize arguments should look like this:

    m_SessionStateService.Initialize(&m_WorkerThread,NULL);

    For database backed session-state support, the data source must be specified:

    const char pszConnection[] = 
             "Provider=SQLOLEDB.1;"
             "Initial Catalog=ATLServer;"
             "Data Source=YourServer"
             ;
    m_SessionStateService.Initialize(
          &m_WorkerThread,
          (IServiceProvider*)this,
          ATL_SESSION_TIMEOUT,
          const_cast<void*>(static_cast<const void*>(pszConnection)),
          lstrlen(pszConnection) + 1); 

See Also