Estoy tratando de solucionar problemas con un cliente de servicio web en mi proyecto actual. No estoy seguro de la plataforma del servidor de servicios (probablemente LAMP). Creo que hay una falla en su lado de la cerca, ya que eliminé los problemas potenciales con mi cliente. El cliente es un proxy de referencia web de tipo ASMX estándar generado automáticamente a partir del servicio WSDL.
Lo que necesito para llegar son los mensajes RAW SOAP (solicitud y respuestas)
¿Cuál es la mejor forma de hacerlo?
Puede implementar una SoapExtension que registre la solicitud y la respuesta completas en un archivo de registro. A continuación, puede habilitar SoapExtension en web.config, lo que facilita su activación / desactivación para fines de depuración. Aquí hay un ejemplo que encontré y modifiqué para mi propio uso, en mi caso, el registro fue realizado por log4net, pero puede reemplazar los métodos de registro con los suyos.
Luego agrega la siguiente sección a su web.config donde YourNamespace y YourAssembly apuntan a la clase y ensamblaje de su SoapExtension:
fuente
No estoy seguro de por qué tanto alboroto con web.config o una clase de serializador. El siguiente código funcionó para mí:
fuente
myEnvelope
vienePruebe Fiddler2 , le permitirá inspeccionar las solicitudes y la respuesta. Vale la pena señalar que Fiddler funciona con tráfico http y https.
fuente
Parece que la solución de Tim Carter no funciona si la llamada a la referencia web arroja una excepción. He estado tratando de acceder a la resonancia web sin procesar para poder examinarla (en código) en el controlador de errores una vez que se lanza la excepción. Sin embargo, encuentro que el registro de respuesta escrito por el método de Tim está en blanco cuando la llamada arroja una excepción. No entiendo completamente el código, pero parece que el método de Tim interviene en el proceso después del punto en el que .Net ya ha invalidado y descartado la respuesta web.
Estoy trabajando con un cliente que está desarrollando un servicio web manualmente con codificación de bajo nivel. En este punto, están agregando sus propios mensajes de error de proceso interno como mensajes con formato HTML en la respuesta ANTES de la respuesta con formato SOAP. Por supuesto, la referencia web de Automagic .Net explota sobre esto. Si pudiera obtener la respuesta HTTP sin procesar después de que se lanza una excepción, podría buscar y analizar cualquier respuesta SOAP dentro de la respuesta HTTP de retorno mixta y saber que recibieron mis datos bien o no.
Luego ...
Aquí hay una solución que funciona, incluso después de una ejecución (tenga en cuenta que solo estoy después de la respuesta, también podría obtener la solicitud):
Así es como se configura en el archivo de configuración:
"TestCallWebService" debe reemplazarse con el nombre de la biblioteca (que resultó ser el nombre de la aplicación de la consola de prueba en la que estaba trabajando).
Realmente no debería tener que ir a ChainStream; debería poder hacerlo de manera más simple desde ProcessMessage como:
Si busca SoapMessage.Stream, se supone que es un flujo de solo lectura que puede usar para inspeccionar los datos en este punto. Esto es un error porque si lee la transmisión, el procesamiento posterior de bombas sin errores de datos encontrados (la transmisión estaba al final) y no puede restablecer la posición al principio.
Curiosamente, si usa ambos métodos, ChainStream y ProcessMessage, el método ProcessMessage funcionará porque cambió el tipo de flujo de ConnectStream a MemoryStream en ChainStream, y MemoryStream sí permite operaciones de búsqueda. (Intenté transmitir ConnectStream a MemoryStream, no estaba permitido).
Entonces ... Microsoft debería permitir las operaciones de búsqueda en el tipo ChainStream o hacer que SoapMessage.Stream sea realmente una copia de solo lectura como se supone que es. (Escriba a su congresista, etc ...)
Un punto más. Después de crear una forma de recuperar la respuesta HTTP sin procesar después de una excepción, todavía no obtuve la respuesta completa (según lo determinado por un rastreador de HTTP). Esto se debió a que cuando el servicio web de desarrollo agregó los mensajes de error HTML al comienzo de la respuesta, no ajustó el encabezado Content-Length, por lo que el valor Content-Length era menor que el tamaño del cuerpo de la respuesta real. Todo lo que obtuve fue el número de caracteres del valor Content-Length; el resto faltaba. Obviamente, cuando .Net lee el flujo de respuesta, solo lee el número de caracteres Content-Length y no permite que el valor Content-Length posiblemente sea incorrecto. Esto es como debería ser; pero si el valor del encabezado Content-Length es incorrecto, la única forma de obtener el cuerpo de respuesta completo es con un rastreador HTTP (yo utilizo HTTP Analyzer dehttp://www.ieinspector.com ).
fuente
Preferiría que el marco haga el registro por usted conectando un flujo de registro que se registre a medida que el marco procesa ese flujo subyacente. Lo siguiente no es tan limpio como me gustaría, ya que no puede decidir entre solicitud y respuesta en el método ChainStream. Lo siguiente es cómo lo manejo. Agradecimiento a Jon Hanna por la idea primordial de una transmisión.
fuente
Aquí hay una versión simplificada de la respuesta principal. Agregue esto al
<configuration>
elemento de su archivoweb.config
oApp.config
. Creará untrace.log
archivo en labin/Debug
carpeta de su proyecto . O puede especificar una ruta absoluta para el archivo de registro utilizando elinitializeData
atributo.Advierte que los atributos
maxdatasize
ytracemode
no están permitidos, pero aumentan la cantidad de datos que se pueden registrar y evitan registrar todo en hexadecimal.fuente
No ha especificado qué lenguaje está usando, pero asumiendo que C # / .NET podría usar extensiones SOAP .
De lo contrario, use un rastreador como Wireshark
fuente
Me doy cuenta de que llego bastante tarde a la fiesta y, dado que el idioma no se especificó en realidad, aquí hay una solución VB.NET basada en la respuesta de Bimmerbound, en caso de que alguien se encuentre con esto y necesite una solución. Nota: debe tener una referencia a la clase stringbuilder en su proyecto, si aún no la tiene.
Simplemente llame a la función y devolverá una cadena con el xml serializado del objeto que está intentando pasar al servicio web (de manera realista, esto debería funcionar para cualquier objeto que quiera lanzarle también).
Como nota al margen, la llamada de reemplazo en la función antes de devolver el xml es eliminar los caracteres vbCrLf de la salida. El mío tenía un montón de ellos dentro del xml generado, sin embargo, esto obviamente variará dependiendo de lo que esté tratando de serializar, y creo que podrían eliminarse durante el envío del objeto al servicio web.
fuente