Cómo registrar inputstream de solicitud con HttpModule, luego restablecer la posición de InputStream


Estoy tratando de registrar el contenido de una solicitud http, usando un módulo IHTTP de la siguiente manera:

public class LoggingModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += ContextBeginRequest;
    }

    private void ContextBeginRequest(object sender, EventArgs e)
    {
        var request = ((HttpApplication)sender).Request;
        string content;

        using (var reader = new StreamReader(request.InputStream))
        {
            content = reader.ReadToEnd();
        }

        LogRequest(content)
    }
}

El problema es que después de leer el flujo de entrada hasta el final, el flujo de entrada parece haber desaparecido o es más probable que el cursor esté al final del flujo.

He intentado request.InputStream.Position = 0; y request.InputStream.Seek(0, SeekOrigin.Begin); pero ninguna obra.

Author: kiamlaluno, 2009-11-05

6 answers

He resuelto el problema: creo que llamar a dispose en el StreamReader también debe estar matando el InputStream.

En lugar de usar el StreamReader hice lo siguiente:

        var bytes = new byte[request.InputStream.Length];
        request.InputStream.Read(bytes, 0, bytes.Length);
        request.InputStream.Position = 0;
        string content = Encoding.ASCII.GetString(bytes);

Así que el código completo:

public class LoggingModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.BeginRequest += ContextBeginRequest;
    }

    private void ContextBeginRequest(object sender, EventArgs e)
    {
        var request = ((HttpApplication)sender).Request;

        var bytes = new byte[request.InputStream.Length];
        request.InputStream.Read(bytes, 0, bytes.Length);
        request.InputStream.Position = 0;
        string content = Encoding.ASCII.GetString(bytes);

        LogRequest(content)
    }
}
 34
Author: cbp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-18 06:01:41

Sí el StreamReader cerrará la secuencia suministrada.

Si estás en >v4.5, usa un constructor StreamReader que deje la secuencia abierta.

using (var reader = new StreamReader(request.InputStream, Encoding.UTF8, true, 1024, true))
{
    content = reader.ReadToEnd();
}
 14
Author: Ivan Hamilton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-29 01:50:46

Necesita usar un filtro de solicitud . Escribe una clase derivada de Stream y regístrala como filtro.

 1
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-05 07:20:33

Esta respuesta no funcionó. devuelve un array que contiene valores nulos.

        var bytes = new byte[request.InputStream.Length];
        request.InputStream.Read(bytes, 0, bytes.Length);
        request.InputStream.Position = 0;
        string content = Encoding.ASCII.GetString(bytes);

porque el flujo de entrada consumido.
 1
Author: amir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-26 15:28:27

Tuve que hacer un pequeño ajuste a la respuesta proporcionada por "cbp". Al usar su código, sólo tengo ceros. Moví el ajuste de la posición a 0 por encima de la lectura y ahora funciona.

 var bytes = new byte[Request.InputStream.Length];
 Request.InputStream.Position = 0;
 Request.InputStream.Read(bytes, 0, bytes.Length);
 string content = Encoding.ASCII.GetString(bytes);
 1
Author: David Colvin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-10 17:39:08

En algún momento, RequestFilter no ejecute el método de lectura. Parece ser que W3WP no lee el contenido de httprequest de manera normal.

Si despliega WEbservice en el servidor. A continuación, utilice IHttpModule para atraparlo. Añadir RequestFilter.

Pero el método Read() del filtro de solicitud no se ejecuta: P

 -1
Author: Nguyễn Văn Quang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-20 04:35:55