Estoy escribiendo un servicio web (usando ASP.NET MVC) y para fines de soporte, nos gustaría poder registrar las solicitudes y la respuesta lo más cerca posible del formato sin formato en el cable (es decir, incluido HTTP método, ruta, todos los encabezados y el cuerpo) en una base de datos.
De lo que no estoy seguro es de cómo obtener estos datos de la manera menos 'destrozada'. Puedo reconstituir el aspecto que creo que tiene la solicitud al inspeccionar todas las propiedades del HttpRequest
objeto y construir una cadena a partir de ellos (y de manera similar para la respuesta), pero realmente me gustaría obtener los datos reales de solicitud / respuesta que están enviado por cable.
Me complace utilizar cualquier mecanismo de intercepción, como filtros, módulos, etc., y la solución puede ser específica para IIS7. Sin embargo, preferiría mantenerlo solo en código administrado.
¿Alguna recomendación?
Editar: Observo que HttpRequest
tiene un SaveAs
método que puede guardar la solicitud en el disco, pero esto reconstruye la solicitud desde el estado interno utilizando una carga de métodos auxiliares internos a los que no se puede acceder públicamente (bastante por qué esto no permite guardar en un archivo proporcionado por el usuario corriente no lo sé). Así que parece que tendré que hacer todo lo posible para reconstruir el texto de solicitud / respuesta de los objetos ... gemido.
Edición 2: Tenga en cuenta que dije toda la solicitud, incluido el método, la ruta, los encabezados, etc. Las respuestas actuales solo miran las secuencias del cuerpo que no incluyen esta información.
Edición 3: ¿Nadie lee las preguntas por aquí? Cinco respuestas hasta el momento y, sin embargo, ninguna sugiere siquiera una forma de obtener toda la solicitud cruda en el cable. Sí, sé que puedo capturar las secuencias de salida y los encabezados y la URL y todas esas cosas del objeto de solicitud. Ya dije eso en la pregunta, ver:
Puedo reconstituir lo que creo que se ve la solicitud al inspeccionar todas las propiedades del objeto HttpRequest y construir una cadena a partir de ellas (y de manera similar para la respuesta), pero realmente me gustaría obtener los datos reales de solicitud / respuesta eso se envía por cable.
Si sabe que los datos sin procesar completos (incluidos los encabezados, la URL, el método http, etc.) simplemente no se pueden recuperar, sería útil saberlo. Del mismo modo, si sabe cómo obtenerlo todo en formato sin formato (sí, todavía me refiero a incluir encabezados, url, método http, etc.) sin tener que reconstruirlo, que es lo que pedí, entonces sería muy útil. Pero decirme que puedo reconstruirlo desde los objetos HttpRequest
/ HttpResponse
no es útil. Yo sé eso. Ya lo dije
Tenga en cuenta: antes de que alguien comience a decir que es una mala idea, o limitará la escalabilidad, etc., también implementaremos mecanismos de aceleración, entrega secuencial y antirrepetición en un entorno distribuido, por lo que se requiere el registro de la base de datos de todos modos. No estoy buscando una discusión sobre si esta es una buena idea, estoy buscando cómo se puede hacer.
fuente
Respuestas:
Definitivamente use un
IHttpModule
e implemente elBeginRequest
yEndRequest
eventos .Todos los datos "sin procesar" están presentes entre
HttpRequest
yHttpResponse
, simplemente, no están en un solo formato sin procesar. Estas son las partes necesarias para crear volcados de estilo Fiddler (lo más cerca posible de HTTP sin procesar):Para la respuesta:
Tenga en cuenta que no puede leer la secuencia de respuesta, por lo que debe agregar un filtro a la secuencia de salida y capturar una copia.
En su
BeginRequest
, deberá agregar un filtro de respuesta:Almacene
filter
donde pueda acceder en elEndRequest
controlador. Sugiero enHttpContext.Items
. Luego puede obtener los datos de respuesta completafilter.ReadStream()
.Luego implemente
OutputFilterStream
usando el patrón Decorator como envoltorio alrededor de una secuencia:fuente
El siguiente método de extensión en HttpRequest creará una cadena que puede pegarse en el violinista y reproducirse.
fuente
HttpRequestBaseExtensions
y cambiarHttpRequest
aHttpRequestBase
en cada lugar.Puede usar la variable de servidor ALL_RAW para obtener los encabezados HTTP originales enviados con la solicitud, luego puede obtener InputStream como de costumbre:
echa un vistazo: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx
fuente
HttpContext.Current.Request
para tomar el contexto actual fuera de los controladores MVC, páginas ASPX, etc., solo asegúrese de que no sea nulo primero;)Bueno, estoy trabajando en un proyecto e hice, tal vez no demasiado profundo, un registro usando los parámetros de solicitud:
Echar un vistazo:
Puede decorar su clase de controladores para registrarla por completo:
o registrar solo algunos métodos de acción individuales
fuente
¿Alguna razón para mantenerlo en código administrado?
Vale la pena mencionar que puede habilitar el registro de Failed Trace en IIS7 si no le gusta reinventar la rueda. Esto registra los encabezados, el cuerpo de solicitud y respuesta, así como muchas otras cosas.
fuente
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
al final deRegister(..)
inWebApiConfig.cs
, pero esto puede variar entre versiones.Seguí el enfoque de McKAMEY. Aquí hay un módulo que escribí que lo ayudará a comenzar y, con suerte, le ahorrará algo de tiempo. Obviamente, deberá conectar el Logger con algo que funcione para usted:
fuente
Encoding.UTF8
, o tal vezEncoding.Default
al leer la secuencia de solicitud? O simplemente use unStreamReader
( con advertencias de eliminación )De acuerdo, parece que la respuesta es "no, no puede obtener los datos sin procesar, debe reconstruir la solicitud / respuesta a partir de las propiedades de los objetos analizados". Oh bueno, he hecho lo de la reconstrucción.
fuente
use un IHttpModule :
fuente
si para uso ocasional, para moverse en una esquina cerrada, ¿qué tal algo crudo como el de abajo?
fuente
Puede lograr esto
DelegatingHandler
sin usar loOutputFilter
mencionado en otras respuestas en .NET 4.5 usando laStream.CopyToAsync()
función.No estoy seguro de los detalles, pero no activa todas las cosas malas que suceden cuando intenta leer directamente el flujo de respuesta.
Ejemplo:
fuente
Sé que no es código administrado, pero voy a sugerir un filtro ISAPI. Han pasado un par de años desde que tuve el "placer" de mantener mi propio ISAPI, pero por lo que recuerdo, puede tener acceso a todo esto, tanto antes como después de que ASP.Net haya hecho todo.
http://msdn.microsoft.com/en-us/library/ms524610.aspx
Si un HTTPModule no es lo suficientemente bueno para lo que necesita, entonces no creo que haya una forma administrada de hacerlo con la cantidad de detalles requerida. Sin embargo, será un dolor.
fuente
Estoy de acuerdo con los demás, use un IHttpModule. Eche un vistazo a la respuesta a esta pregunta, que hace casi lo mismo que está preguntando. Registra la solicitud y la respuesta, pero sin encabezados.
¿Cómo rastrear las solicitudes de ScriptService WebService?
fuente
Puede ser mejor hacer esto fuera de su aplicación. Puede configurar un proxy inverso para hacer cosas como esta (y mucho más). Un proxy inverso es básicamente un servidor web que se encuentra en su sala de servidores y se interpone entre su (s) servidor (es) web y el cliente. Ver http://en.wikipedia.org/wiki/Reverse_proxy
fuente
De acuerdo con FigmentEngine,
IHttpModule
parece ser el camino a seguir.Mira en
httpworkerrequest
,readentitybody
yGetPreloadedEntityBody
.Para obtener lo
httpworkerrequest
que necesita hacer esto:donde
inApp
está el objeto httpapplication.fuente
HttpRequest
yHttpResponse
pre MVC solía tener unGetInputStream()
yGetOutputStream()
que podría usarse para ese propósito. No he examinado esas partes en MVC, así que no estoy seguro de que estén disponibles, pero podría ser una idea :)fuente