Exemplarische Vorgehensweise: Erstellen eines Request-Level HTTP-Moduls mithilfe von nativem Code

In dieser exemplarischen Vorgehensweise wird veranschaulicht, wie Sie mit C++ ein HTTP-Modul auf Anforderungsebene erstellen, das die neue Anforderungsverarbeitungsarchitektur in IIS 7 implementiert. Diese neue Architektur erweitert die Funktionen der nativen Codeprogrammierung, wenn Sie IIS-Anwendungen über frühere Versionen von ASP.NET HTTP-Modulen und ISAPI-Filtern oder -Erweiterungen schreiben. Weitere Informationen zum Entwerfen von HTTP-Modulen mithilfe der neuen Anforderungsverarbeitungsarchitektur finden Sie unter Entwerfen Native-Code HTTP-Module.

In dieser exemplarischen Vorgehensweise erstellen Sie ein C++-Projekt für Ihr HTTP-Modul, fügen den erforderlichen Code für ein "Hallo Welt"-Projekt hinzu und kompilieren und testen dann das Modul.

Voraussetzungen

Die folgende Software ist erforderlich, um die Schritte im Beispiel auszuführen:

  • IIS 7.

  • Visual Studio 2005.

  • Windows Software Development Kit (SDK).

    Hinweis Sie können Visual Studio .NET 2003 oder früher verwenden, obwohl die exemplarischen Schritte möglicherweise nicht identisch sind.

Erstellen des Moduls

In diesem Teil der exemplarischen Vorgehensweise erstellen Sie ein leeres C++-DLL-Projekt für Ihr HTTP-Modul.

So erstellen Sie ein neues C++-DLL-Projekt

  1. Öffnen Sie Visual Studio 2005.

  2. Vergewissern Sie sich, dass die globalen Optionen alle richtigen Pfade zum SDK enthalten:

    1. Klicken Sie im Menü Extras auf Optionen.

    2. Erweitern Sie den Knoten Projekte und Projektmappen in der Strukturansicht, und klicken Sie dann auf VC++-Verzeichnisse.

    3. Wählen Sie im Dropdownfeld Verzeichnisse für anzeigen die Option Dateien einschließen aus.

    4. Vergewissern Sie sich, dass der Pfad aufgeführt ist, in dem Sie das Windows SDK include files installiert haben. Wenn der Pfad nicht aufgeführt ist, klicken Sie auf das Symbol Neue Zeile , und fügen Sie dann den Pfad hinzu, in dem Sie die SDK-Includedateien installiert haben. Das Standardinstallationsverzeichnis ist $(VCInstallDir)PlatformSDK\bin.

    5. Klicken Sie auf OK.

  3. Erstellen Sie ein neues C++-Projekt:

    1. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

      Das Dialogfeld Neues Projekt wird angezeigt.

    2. Erweitern Sie im Bereich Projekttypen den Knoten Visual C++ , und klicken Sie dann auf Win32.

    3. Wählen Sie im Bereich Vorlagendie Option Win32-Projekt aus.

    4. Geben Sie im Feld Nameden Namen HelloWorld ein.

    5. Geben Sie im Feld Speicherort den Pfad für das Beispiel ein.

    6. Klicken Sie auf OK.

      Der Win32-Anwendungs-Assistent wird geöffnet.

    7. Klicken Sie auf Anwendungseinstellungen.

    8. Klicken Sie unter Anwendungstyp auf DLL.

    9. Klicken Sie unter Zusätzliche Optionen auf Leeres Projekt.

    10. Klicken Sie auf Fertig stellen.

Hinzufügen des Codes und der Quelldateien

Der nächste Schritt besteht darin, dem Projekt die erforderlichen C++- und Moduldefinitionsdateien hinzuzufügen.

So fügen Sie dem Projekt die Quelldateien hinzu

  1. Erstellen Sie die Moduldefinitionsdatei, um die Funktion RegisterModule zu exportieren:

    1. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf Quelldateien, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Neues Element.

      Das Dialogfeld Neues Element hinzufügen wird angezeigt.

    2. Erweitern Sie den Knoten Visual C++ im Bereich Kategorien , und klicken Sie dann auf Code.

    3. Wählen Sie im Bereich Vorlagen die Vorlage Moduldefinitionsdatei aus.

    4. Geben Sie im Feld Nameden Namen HelloWorld ein, und behalten Sie den Standardpfad für die Datei im Feld Speicherort bei.

    5. Klicken Sie auf Hinzufügen.

    6. Fügen Sie eine Zeile mit EXPORTS und RegisterModulehinzu. Ihre Datei sollte wie der folgende Code aussehen:

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Hinweis

      Anstatt eine Moduldefinitionsdatei zu erstellen, können Sie die RegisterModule-Funktion mithilfe des Schalters /EXPORT:RegisterModule exportieren.

  2. Erstellen Sie die C++-Datei:

    1. Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf Quelldateien, zeigen Sie auf Hinzufügen, und klicken Sie dann auf Neues Element.

      Das Dialogfeld Neues Element hinzufügen wird angezeigt.

    2. Erweitern Sie den Knoten Visual C++ im Bereich Kategorien , und klicken Sie dann auf Code.

    3. Wählen Sie im Bereich Vorlagen die Vorlage C++-Datei aus.

    4. Geben Sie im Feld Nameden Namen HelloWorld ein, und behalten Sie den Standardpfad für die Datei im Feld Speicherort bei.

    5. Klicken Sie auf Hinzufügen.

    6. Fügen Sie den folgenden Code hinzu:

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

Kompilieren und Testen des Moduls

So kompilieren und testen Sie das Projekt

  1. Kompilieren Sie das HTTP-Modul:

    1. Klicken Sie im Menü Erstellen auf Projektmappe erstellen.

    2. Stellen Sie sicher, dass Visual Studio keine Fehler oder Warnungen zurückgegeben hat.

    3. Fügen Sie das modul HelloWorld.dll (mit dem vollständigen Pfad) zum globalModules Abschnitt der Datei %windir%\system32\inetsrv\config\applicationHost.config hinzu.

  2. Verwenden Sie internet Explorer, um zu Ihrer Website zu navigieren. Sie sollten "Beispiel für die Startanforderung" mit angezeigter Anforderungsanzahl sehen.

Hinweis

Sie müssen IIS beenden, bevor Sie Ihr Projekt mit nachfolgenden Builds verknüpfen.

Problembehandlung für Ihre Einstellungen

Wenn Ihr Modul nicht kompiliert wird oder nicht wie erwartet funktioniert, können Sie die folgenden Bereiche überprüfen:

  • Stellen Sie sicher, dass Sie für Ihre exportierten Funktionen angegeben __stdcall oder die Kompilierung mithilfe der __stdcall (/Gz) Aufrufkonvention konfiguriert haben.

  • Stellen Sie sicher, dass IIS HelloWorld.dll geladen hat:

    1. Klicken Sie im IIS-Manager im Bereich Verbindungen auf Standardwebsite.

    2. Wählen Sie im Arbeitsbereich (dem mittleren Bereich) die Option Featureansicht aus.

    3. Wählen Sie im Feld Gruppierung nach die Option Kategorie aus.

    4. Doppelklicken Sie in der Kategorie Serverkomponenten auf Module.

    5. Vergewissern Sie sich, dass das HelloWorld-Modul aufgeführt ist.

  • Stellen Sie sicher, dass Sie der Definitionsdatei den richtigen RegisterModule Export hinzugefügt haben.

  • Stellen Sie sicher, dass Sie die Definitionsdatei zu den Projekteinstellungen hinzugefügt haben. Führen Sie die folgenden Schritte aus, um die Datei zu den Projekteinstellungen hinzuzufügen:

    1. Klicken Sie im Menü Projekt auf Eigenschaften.

    2. Erweitern Sie den Knoten Konfigurationseigenschaften in der Strukturansicht, erweitern Sie den Knoten Linker , und klicken Sie dann auf Eingabe.

    3. Stellen Sie für die Moduldefinitionsdateieinstellungen sicher, dass Ihre Definitionsdatei aufgeführt ist.

Weitere Informationen

Erstellen von Native-Code HTTP-Modulen
Entwerfen Native-Code HTTP-Module