Condividi tramite


Procedura dettagliata: Creazione di un modulo HTTP Request-Level tramite codice nativo

Questa procedura dettagliata illustra come usare C++ per creare un modulo HTTP a livello di richiesta di esempio che implementa la nuova architettura di elaborazione delle richieste in IIS 7. Questa nuova architettura estende le funzionalità di programmazione del codice nativo quando si scrivono applicazioni IIS su versioni precedenti di moduli HTTP ASP.NET e filtri o estensioni ISAPI. Per altre informazioni sulla progettazione di moduli HTTP tramite la nuova architettura di elaborazione delle richieste, vedere Progettazione di moduli HTTP Native-Code.

In questa procedura dettagliata si creerà un progetto C++ per il modulo HTTP, si aggiungerà il codice necessario per un progetto "Hello World" e quindi si compilerà e testerà il modulo.

Prerequisiti

Il software seguente è necessario per completare i passaggi nell'esempio:

  • IIS 7.

  • Visual Studio 2005.

  • Windows Software Development Kit (SDK).

    Nota È possibile usare Visual Studio .NET 2003 o versioni precedenti, anche se i passaggi della procedura dettagliata potrebbero non essere identici.

Creazione del modulo

In questa parte della procedura dettagliata si creerà un progetto DLL C++ vuoto per il modulo HTTP.

Per creare un nuovo progetto DLL C++

  1. Aprire Visual Studio 2005.

  2. Verificare che le opzioni globali abbiano tutti i percorsi corretti per i file di inclusione dell'SDK.

    1. Sul menu Strumenti, fare clic su Opzioni.

    2. Espandere il nodo Progetti e soluzioni nella visualizzazione albero e quindi fare clic su Directory VC++.

    3. Nella casella a discesa Mostra directory per selezionare Includi file.

    4. Verificare che sia elencato il percorso in cui è stato installato i file di inclusione di Windows SDK. Se il percorso non è elencato, fare clic sull'icona Nuova riga e quindi aggiungere il percorso in cui è stato installato l'SDK include file. La directory di installazione predefinita è $(VCInstallDir)PlatformSDK\bin.

    5. Fare clic su OK.

  3. Creare un nuovo progetto C++:

    1. Scegliere Nuovo dal menu Filee quindi fare clic su Progetto.

      Verrà visualizzata la finestra di dialogo Nuovo progetto .

    2. Nel riquadro Tipi di progetto espandere il nodo Visual C++ e quindi fare clic su Win32.

    3. Nel riquadro Modelli selezionare Progetto Win32.

    4. Nella casella Nome digitare HelloWorld.

    5. Nella casella Posizione digitare il percorso per l'esempio.

    6. Fare clic su OK.

      La Creazione guidata per applicazione Win32 si apre.

    7. Fare clic su Impostazioni applicazione.

    8. In Tipo di applicazione fare clic su DLL.

    9. In Opzioni aggiuntive fare clic su Progetto vuoto.

    10. Fare clic su Fine.

Aggiunta del codice e dei file sorgenti

Il passaggio successivo consiste nell'aggiungere i file di definizione del modulo e C++ necessari al progetto.

Per aggiungere i file di origine al progetto

  1. Creare il file di definizione del modulo per esportare la funzione RegisterModule :

    1. In Esplora soluzioni fare clic con il pulsante destro del mouse su File di origine, scegliere Aggiungi e quindi fare clic su Nuovo elemento.

      La finestra di dialogo Aggiungi nuovo elemento si apre.

    2. Espandere il nodo Visual C++ nel riquadro Categorie e quindi fare clic su Codice.

    3. Nel riquadro Modelli selezionare il modello File di Definizione Modulo.

    4. Nella casella Nome digitare HelloWorld e lasciare il percorso predefinito per il file nella casella Percorso .

    5. Fare clic su Aggiungi.

    6. Aggiungere una riga con EXPORTS e RegisterModule. Il file dovrebbe essere simile al codice seguente:

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Annotazioni

      Anziché creare un file di definizione del modulo, è possibile esportare la funzione RegisterModule usando l'opzione /EXPORT:RegisterModule .

  2. Creare il file C++:

    1. In Esplora soluzioni fare clic con il pulsante destro del mouse su File di origine, scegliere Aggiungi e quindi fare clic su Nuovo elemento.

      La finestra di dialogo Aggiungi nuovo elemento si apre.

    2. Espandere il nodo Visual C++ nel riquadro Categorie e quindi fare clic su Codice.

    3. Nel riquadro Modelli selezionare il modello file C++ .

    4. Nella casella Nome digitare HelloWorld e lasciare il percorso predefinito per il file nella casella Percorso .

    5. Fare clic su Aggiungi.

    6. Aggiungere il codice seguente:

      #define _WINSOCKAPI_
      #include <windows.h>
      #include <sal.h>
      #include <httpserv.h>
      
      // Create the module class.
      class CHelloWorld : public CHttpModule
      {
      public:
          REQUEST_NOTIFICATION_STATUS
          OnBeginRequest(
              IN IHttpContext * pHttpContext,
              IN IHttpEventProvider * pProvider
          )
          {
              UNREFERENCED_PARAMETER( pProvider );
      
              // Create an HRESULT to receive return values from methods.
              HRESULT hr;
              
              // Retrieve a pointer to the response.
              IHttpResponse * pHttpResponse = pHttpContext->GetResponse();
      
              // Test for an error.
              if (pHttpResponse != NULL)
              {
                  // Clear the existing response.
                  pHttpResponse->Clear();
                  // Set the MIME type to plain text.
                  pHttpResponse->SetHeader(
                      HttpHeaderContentType,"text/plain",
                      (USHORT)strlen("text/plain"),TRUE);
      
                  // Create a string with the response.
                  PCSTR pszBuffer = "Hello World!";
                  // Create a data chunk.
                  HTTP_DATA_CHUNK dataChunk;
                  // Set the chunk to a chunk in memory.
                  dataChunk.DataChunkType = HttpDataChunkFromMemory;
                  // Buffer for bytes written of data chunk.
                  DWORD cbSent;
                  
                  // Set the chunk to the buffer.
                  dataChunk.FromMemory.pBuffer =
                      (PVOID) pszBuffer;
                  // Set the chunk size to the buffer size.
                  dataChunk.FromMemory.BufferLength =
                      (USHORT) strlen(pszBuffer);
                  // Insert the data chunk into the response.
                  hr = pHttpResponse->WriteEntityChunks(
                      &dataChunk,1,FALSE,TRUE,&cbSent);
      
                  // Test for an error.
                  if (FAILED(hr))
                  {
                      // Set the HTTP status.
                      pHttpResponse->SetStatus(500,"Server Error",0,hr);
                  }
      
                  // End additional processing.
                  return RQ_NOTIFICATION_FINISH_REQUEST;
              }
      
              // Return processing to the pipeline.
              return RQ_NOTIFICATION_CONTINUE;
          }
      };
      
      // Create the module's class factory.
      class CHelloWorldFactory : public IHttpModuleFactory
      {
      public:
          HRESULT
          GetHttpModule(
              OUT CHttpModule ** ppModule, 
              IN IModuleAllocator * pAllocator
          )
          {
              UNREFERENCED_PARAMETER( pAllocator );
      
              // Create a new instance.
              CHelloWorld * pModule = new CHelloWorld;
      
              // Test for an error.
              if (!pModule)
              {
                  // Return an error if the factory cannot create the instance.
                  return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
              }
              else
              {
                  // Return a pointer to the module.
                  *ppModule = pModule;
                  pModule = NULL;
                  // Return a success status.
                  return S_OK;
              }            
          }
      
          void
          Terminate()
          {
              // Remove the class from memory.
              delete this;
          }
      };
      
      // Create the module's exported registration function.
      HRESULT
      __stdcall
      RegisterModule(
          DWORD dwServerVersion,
          IHttpModuleRegistrationInfo * pModuleInfo,
          IHttpServer * pGlobalInfo
      )
      {
          UNREFERENCED_PARAMETER( dwServerVersion );
          UNREFERENCED_PARAMETER( pGlobalInfo );
      
          // Set the request notifications and exit.
          return pModuleInfo->SetRequestNotifications(
              new CHelloWorldFactory,
              RQ_BEGIN_REQUEST,
              0
          );
      }
      

Compilazione e test del modulo

Per compilare e testare il progetto

  1. Compilare il modulo HTTP:

    1. Nel menu Compila scegliere Compila soluzione.

    2. Verificare che Visual Studio non restituisca errori o avvisi.

    3. Aggiungere il modulo HelloWorld.dll (con il percorso completo) alla globalModules sezione del file di %windir%\system32\inetsrv\config\applicationHost.config.

  2. Utilizzare Internet Explorer per visitare il sito Web; dovresti vedere "Begin Request sample" con il conteggio delle richieste visualizzato.

Annotazioni

È necessario arrestare IIS prima di collegare il progetto alle compilazioni successive.

Risoluzione dei problemi relativi alle impostazioni

Se il modulo non viene compilato o non funziona come previsto, ecco alcune aree che è possibile controllare:

  • Assicurarsi di aver specificato __stdcall per le funzioni esportate o di aver configurato la compilazione usando la convenzione di chiamata __stdcall (/Gz).

  • Assicurarsi che IIS abbia caricato HelloWorld.dll:

    1. In Gestione IIS fare clic su Sito Web predefinito nel riquadro Connessioni .

    2. Nell'area di lavoro (riquadro centrale) selezionare Visualizzazione funzionalità.

    3. Nella casella Raggruppa per selezionare Categoria.

    4. Nella categoria Componenti server fare doppio clic su Moduli.

    5. Verificare che il modulo HelloWorld sia elencato.

  • Assicurarsi di aver aggiunto l'esportazione corretta RegisterModule al file di definizione.

  • Assicurarsi di aver aggiunto il file di definizione alle impostazioni del progetto. Per aggiungere il file alle impostazioni del progetto, seguire questa procedura:

    1. Scegliere Proprietàdal menu Project .

    2. Espandere il nodo Proprietà di configurazione nella visualizzazione albero, espandere il nodo Linker e quindi fare clic su Input.

    3. Per le impostazioni del file di definizione del modulo , assicurarsi che il file di definizione sia elencato.

Vedere anche

Creazione di moduli HTTP Native-Code
Progettazione di moduli HTTP Native-Code