Passo a passo: criando um módulo HTTP Request-Level usando código nativo

Este passo a passo demonstra como usar o C++ para criar um módulo HTTP de nível de solicitação de exemplo que implementa a nova arquitetura de processamento de solicitação no IIS 7. Essa nova arquitetura estende os recursos de programação de código nativo quando você está escrevendo aplicativos IIS em versões anteriores de módulos HTTP ASP.NET e filtros OU extensões ISAPI. Para obter mais informações sobre como criar módulos HTTP usando a nova arquitetura de processamento de solicitações, consulte Criando módulos HTTP Native-Code.

Neste passo a passo, você criará um projeto C++ para seu módulo HTTP, adicionará o código necessário para um projeto "Olá, Mundo" e, em seguida, compilará e testará o módulo.

Pré-requisitos

O seguinte software é necessário para concluir as etapas no exemplo:

  • IIS 7.

  • Visual Studio 2005.

  • SDK (Software Development Kit) do Windows.

    Nota Você pode usar o Visual Studio .NET 2003 ou anterior, embora as etapas passo a passo possam não ser idênticas.

Criando o módulo

Nesta parte do passo a passo, você criará um projeto de DLL C++ vazio para seu módulo HTTP.

Para criar um novo projeto de DLL do C++

  1. Abra o Visual Studio 2005.

  2. Verifique se as opções globais têm todos os caminhos certos para o SDK incluem arquivos:

    1. No menu Ferramentas , clique em Opções.

    2. Expanda o nó Projetos e Soluções no modo de exibição de árvore e clique em Diretórios VC++.

    3. Na caixa suspensa Mostrar diretórios para , selecione Incluir arquivos.

    4. Verifique se o caminho em que você instalou o SDK do Windows inclui arquivos está listado. Se o caminho não estiver listado, clique no ícone Nova Linha e adicione o caminho em que você instalou os arquivos de inclusão do SDK. O diretório de instalação padrão é $(VCInstallDir)PlatformSDK\bin.

    5. Clique em OK.

  3. Crie um novo projeto C++:

    1. No menu Arquivo , aponte para Novoe clique em Projeto.

      A caixa de diálogo Novo Projeto será aberta.

    2. No painel Tipos de Projeto , expanda o nó Visual C++ e clique em Win32.

    3. No painel Modelos , selecione Projeto Win32.

    4. Na caixa Nome , digite HelloWorld.

    5. Na caixa Localização, digite o caminho para o exemplo.

    6. Clique em OK.

      O Assistente de Aplicativo Win32 é aberto.

    7. Clique em Configurações do Aplicativo.

    8. Em Tipo de aplicativo, clique em DLL.

    9. Em Opções adicionais, clique em Projeto vazio.

    10. Clique em Concluir.

Adicionando o código e os arquivos de origem

A próxima etapa é adicionar os arquivos C++ e definição de módulo necessários ao projeto.

Para adicionar os arquivos de origem ao projeto

  1. Crie o arquivo de definição de módulo para exportar a função RegisterModule :

    1. Em Gerenciador de Soluções, clique com o botão direito do mouse em Arquivos de Origem, aponte para Adicionar e clique em Novo Item.

      A caixa de diálogo Adicionar Novo Item é aberta.

    2. Expanda o nó do Visual C++ no painel Categorias e clique em Código.

    3. No painel Modelos , selecione o modelo Arquivo de Definição de Módulo .

    4. Na caixa Nome , digite HelloWorld e deixe o caminho padrão para o arquivo na caixa Localização .

    5. Clique em Adicionar.

    6. Adicione uma linha com EXPORTS e RegisterModule. Seu arquivo deve ter a aparência do código abaixo:

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Observação

      Em vez de criar um arquivo de definição de módulo, você pode exportar a função RegisterModule usando a opção /EXPORT:RegisterModule .

  2. Crie o arquivo C++:

    1. Em Gerenciador de Soluções, clique com o botão direito do mouse em Arquivos de Origem, aponte para Adicionar e clique em Novo Item.

      A caixa de diálogo Adicionar Novo Item é aberta.

    2. Expanda o nó do Visual C++ no painel Categorias e clique em Código.

    3. No painel Modelos , selecione o modelo arquivo C++ .

    4. Na caixa Nome , digite HelloWorld e deixe o caminho padrão para o arquivo na caixa Localização .

    5. Clique em Adicionar.

    6. Adicione os códigos a seguir:

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

Compilando e testando o módulo

Para compilar e testar o projeto

  1. Compile o módulo HTTP:

    1. No menu Compilar, clique em Compilar Solução.

    2. Verifique se o Visual Studio não retornou erros ou avisos.

    3. Adicione o módulo HelloWorld.dll (com o caminho completo) à globalModules seção do arquivo %windir%\system32\inetsrv\config\applicationHost.config.

  2. Use o Explorer da Internet para navegar até seu site; você deverá ver "Exemplo de solicitação de início" com a contagem de solicitações exibida.

Observação

Você precisará interromper o IIS antes de vincular seu projeto em builds subsequentes.

Solução de problemas de suas configurações

Se o módulo não compilar ou não funcionar conforme o esperado, aqui estão várias áreas que você pode marcar:

  • Verifique se você especificou __stdcall para suas funções exportadas ou se configurou a compilação usando a __stdcall (/Gz) convenção de chamada.

  • Verifique se o IIS carregou HelloWorld.dll:

    1. No Gerenciador do IIS, clique em Site Padrão no painel Conexões .

    2. No workspace (o painel central), selecione Exibição de Recursos.

    3. Na caixa Agrupar por , selecione Categoria.

    4. Na categoria Componentes do Servidor , clique duas vezes em Módulos.

    5. Verifique se o módulo HelloWorld está listado.

  • Verifique se você adicionou a exportação correta RegisterModule ao arquivo de definição.

  • Verifique se você adicionou o arquivo de definição às configurações do projeto. Para adicionar o arquivo às configurações do projeto, conclua as seguintes etapas:

    1. No menu Projeto , clique em Propriedades.

    2. Expanda o nó Propriedades de Configuração no modo de exibição de árvore, expanda o nó Vinculador e clique em Entrada.

    3. Para as configurações do Arquivo de Definição de Módulo , verifique se o arquivo de definição está listado.

Consulte Também

Criando módulos HTTP Native-Code
Criando módulos HTTP Native-Code