Compartir a través de


IHttpContext::ExecuteRequest (Método)

Ejecuta una solicitud secundaria.

Sintaxis

virtual HRESULT ExecuteRequest(  
   IN BOOL fAsync,  
   IN IHttpContext* pHttpContext,  
   IN DWORD dwExecuteFlags,  
   IN IHttpUser* pHttpUser,  
   OUT BOOL* pfCompletionExpected = NULL  
) = 0;  

Parámetros

fAsync
[IN] Siempre true (especifica la ejecución asincrónica).

pHttpContext
[IN] Puntero al IHttpContext secundario que se va a ejecutar.

dwExecuteFlags
[IN] que DWORD contiene las marcas de ejecución de la solicitud.

pHttpUser
[IN] Puntero a un IHttpUser para la solicitud. (Opcional)

pfCompletionExpected
[OUT] true si la finalización asincrónica sigue pendiente; de lo contrario, false. (Opcional)

Valor devuelto

Una clase HRESULT. Entre los valores posibles se incluyen los que se indican en la tabla siguiente, entre otros.

Valor Descripción
S_OK Indica que la operación se realizó correctamente.
ERROR_NOT_SUPPORTED Indica que no se admite la solicitud (por ejemplo, fAsync se establece false en o la solicitud secundaria no se clonó de la solicitud primaria).
ERROR_STACK_OVERFLOW Indica que la solicitud supera el límite de solicitudes secundarias recursivas.

Comentarios

El ExecuteRequest método ejecuta la solicitud secundaria especificada por la interfaz IHttpContext en el pHttpContext parámetro . Debe crear este contexto de solicitud mediante el método IHttpContext::CloneContext .

Importante

Si se intenta ejecutar una solicitud secundaria que la solicitud primaria no clonó, devolverá ERROR_NOT_SUPPORTED.

Cada contexto secundario solo se puede ejecutar una vez, aunque las solicitudes secundarias se pueden anidar de forma recursiva.

Nota

El límite de solicitudes secundarias recursivas es 10.

El ExecuteRequest método solo admite la operación asincrónica, lo que impide agotar el grupo de subprocesos.

Importante

Si intenta ejecutar una solicitud secundaria sincrónica, se devolverán ERROR_NOT_SUPPORTED.

Puede controlar el comportamiento de ejecución de la solicitud secundaria especificando marcas de ejecución en dwExecuteFlags. En la tabla siguiente se enumeran los valores posibles para estas marcas.

Valor Descripción
EXECUTE_FLAG_NO_HEADERS Suprima los encabezados HTTP de la solicitud secundaria.
EXECUTE_FLAG_IGNORE_CURRENT_INTERCEPTOR Omita el controlador de mapa de scripts actual para esta cadena de solicitudes.
EXECUTE_FLAG_IGNORE_APPPOOL Ejecute la solicitud incluso si la solicitud secundaria no está en el mismo grupo de aplicaciones.
EXECUTE_FLAG_DISABLE_CUSTOM_ERROR Deshabilite los errores personalizados para la solicitud secundaria.
EXECUTE_FLAG_SAME_URL La dirección URL de la solicitud secundaria es la misma que la solicitud primaria. Nota: Los controladores de mapa de scripts usan esta marca para reenviar la ejecución.
EXECUTE_FLAG_BUFFER_RESPONSE No vacíe la respuesta secundaria; devuelve la respuesta a la solicitud primaria.
EXECUTE_FLAG_HTTP_CACHE_ELIGIBLE La respuesta secundaria sigue siendo apta para el almacenamiento en caché Http.sys. Nota: El almacenamiento en caché está deshabilitado de forma predeterminada cuando se ejecuta una solicitud secundaria.

Si especifica una IHttpUser interfaz para pHttpUser, se omitirá la autenticación para la solicitud secundaria.

Ejemplo

En el ejemplo de código siguiente se muestra cómo crear un módulo HTTP que realice las tareas siguientes:

  1. El módulo se registra para la notificación de RQ_MAP_PATH .

  2. El módulo crea una clase CHttpModule que contiene métodos OnMapPath y OnAsyncCompletion .

  3. Cuando un cliente web solicita una dirección URL, IIS llama al método del OnMapPath módulo. Este método realiza las tareas siguientes:

    1. Comprueba si la dirección URL de la solicitud actual coincide con dos direcciones URL específicas en la raíz del sitio web. Si la dirección URL coincide con cualquiera de las direcciones URL especificadas, el módulo usa el IHttpContext::CloneContext método para crear un clon de la solicitud actual.

    2. Llama al método del IHttpRequest::SetUrl clon para establecer la dirección URL del clon en /example/default.aspx.

    3. Llama al ExecuteRequest método para ejecutar la solicitud secundaria.

    4. Comprueba la finalización asincrónica. Si la finalización asincrónica está pendiente, el módulo devuelve el procesamiento a la canalización integrada de procesamiento de solicitudes. Si no es así, el módulo libera el contexto clonado.

  4. Si se requiere finalización asincrónica, IIS llama al método del OnAsyncCompletion módulo. Este método libera el contexto clonado.

  5. El módulo quita la CHttpModule clase de la memoria y, a continuación, se cierra.

#define _WINSOCKAPI_
#include <windows.h>
#include <sal.h>
#include <httpserv.h>

// Create the module class.
class MyHttpModule : public CHttpModule
{

private:

    // Create a pointer for a child request.
    IHttpContext * m_pChildRequestContext;

public:

    MyHttpModule(void)
    {
        m_pChildRequestContext = NULL;
    }

    REQUEST_NOTIFICATION_STATUS
    OnMapPath(
        IN IHttpContext * pHttpContext,
        IN IMapPathProvider * pProvider
    )
    {
        UNREFERENCED_PARAMETER( pProvider );

        HRESULT hr;
        BOOL fCompletionExpected;

        // Retrieve a pointer to the URL.
        PCWSTR pwszUrl = pProvider->GetUrl();

        // Only process requests for the root.
        if (0 == wcscmp(pwszUrl,L"/") || 0 == wcscmp(pwszUrl,L"/default.aspx"))
        {            
            // Clone the current context.
            hr = pHttpContext->CloneContext(
                CLONE_FLAG_BASICS, &m_pChildRequestContext );
            
            // Test for a failure.
            if (FAILED(hr))
            {
                goto Failure;
            }
            
            // Test for an error.
            if ( NULL != m_pChildRequestContext )
            {
                // Set the URL for the child request.
                hr = m_pChildRequestContext->GetRequest()->SetUrl(
                    "/example/default.aspx",
                    (DWORD)strlen("/example/default.aspx"),false);
            
                // Test for a failure.
                if (FAILED(hr))
                {
                    goto Failure;
                }
                
                // Execute the child request.
                hr = pHttpContext->ExecuteRequest(
                    TRUE, m_pChildRequestContext,
                    0, NULL, &fCompletionExpected );
                
                // Test for a failure.
                if (FAILED(hr))
                {
                    goto Failure;
                }
                
                // Test for pending asynchronous operations.
                if (fCompletionExpected)
                {
                    return RQ_NOTIFICATION_PENDING;
                }

            }

 Failure:
            // Test for a child request.
            if (NULL != m_pChildRequestContext)
            {
                // Release the child request.
                m_pChildRequestContext->ReleaseClonedContext();
                m_pChildRequestContext = NULL;
            }
        }
        
        // Return processing to the pipeline.
        return RQ_NOTIFICATION_CONTINUE;
    }
    
    REQUEST_NOTIFICATION_STATUS
        OnAsyncCompletion(
        IN IHttpContext * pHttpContext,
        IN DWORD dwNotification,
        IN BOOL fPostNotification,
        IN IHttpEventProvider * pProvider,
        IN IHttpCompletionInfo * pCompletionInfo
        )
    {
        // Test for a child request.
        if (NULL != m_pChildRequestContext)
        {
            // Release the child request.
            m_pChildRequestContext->ReleaseClonedContext();
            m_pChildRequestContext = NULL;
        }
        // Return processing to the pipeline.
        return RQ_NOTIFICATION_CONTINUE;
    }

};

// Create the module's class factory.
class MyHttpModuleFactory : public IHttpModuleFactory
{
public:
    HRESULT
    GetHttpModule(
        OUT CHttpModule ** ppModule, 
        IN IModuleAllocator * pAllocator
    )
    {
        UNREFERENCED_PARAMETER( pAllocator );

        // Create a new instance.
        MyHttpModule * pModule = new MyHttpModule;

        // Test for an error.
        if (!pModule)
        {
            // Return an error if we 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 );

    return pModuleInfo->SetRequestNotifications(
        new MyHttpModuleFactory,
        RQ_MAP_PATH,
        0
    );
}

El módulo debe exportar la función RegisterModule . Puede exportar esta función mediante la creación de un archivo de definición de módulo (.def) para el proyecto, o bien puede compilar el módulo mediante el /EXPORT:RegisterModule modificador . Para obtener más información, vea Tutorial: Creación de un módulo HTTP de Request-Level mediante código nativo.

Opcionalmente, puede compilar el código mediante la __stdcall (/Gz) convención de llamada en lugar de declarar explícitamente la convención de llamada para cada función.

Requisitos

Tipo Descripción
Remoto - IIS 7.0 en Windows Vista
- IIS 7.5 en Windows 7
- IIS 8.0 en Windows 8
- IIS 10.0 en Windows 10
Servidor - IIS 7.0 en Windows Server 2008
- IIS 7.5 en Windows Server 2008 R2
- IIS 8.0 en Windows Server 2012
- IIS 8.5 en Windows Server 2012 R2
- IIS 10.0 en Windows Server 2016
Producto - IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0
- IIS Express 7.5, IIS Express 8.0, IIS Express 10.0
Encabezado Httpserv.h

Consulte también

IHttpContext (interfaz)
IHttpContext::CloneContext (Método)
IHttpContext::GetParentContext (Método)
IHttpContext::ReleaseClonedContext (Método)