J'essaye de dépanner un client de service Web dans mon projet actuel. Je ne suis pas sûr de la plate-forme du serveur de service (très probablement LAMP). Je pense qu'il y a un défaut de leur côté de la clôture car j'ai éliminé les problèmes potentiels avec mon client. Le client est un proxy de référence Web de type ASMX standard généré automatiquement à partir du service WSDL.
Ce dont je dois accéder, ce sont les messages SOAP RAW (demande et réponses)
Quelle est la meilleure manière de s'occuper de ça?
Vous pouvez implémenter une SoapExtension qui enregistre la requête et la réponse complètes dans un fichier journal. Vous pouvez ensuite activer SoapExtension dans le web.config, ce qui facilite l'activation / la désactivation à des fins de débogage. Voici un exemple que j'ai trouvé et modifié pour mon propre usage, dans mon cas, la journalisation a été effectuée par log4net mais vous pouvez remplacer les méthodes de journalisation par les vôtres.
Vous ajoutez ensuite la section suivante à votre web.config où YourNamespace et YourAssembly pointent vers la classe et l'assembly de votre SoapExtension:
la source
Je ne sais pas pourquoi tout le problème avec web.config ou une classe de sérialisation. Le code ci-dessous a fonctionné pour moi:
la source
myEnvelope
vient-il?Essayez Fiddler2, il vous permettra d'inspecter les demandes et la réponse. Il peut être intéressant de noter que Fiddler fonctionne à la fois avec le trafic http et https.
la source
Il semble que la solution de Tim Carter ne fonctionne pas si l'appel à la référence Web lève une exception. J'ai essayé d'obtenir la réponse Web brute afin de pouvoir l'examiner (dans le code) dans le gestionnaire d'erreurs une fois l'exception levée. Cependant, je trouve que le journal des réponses écrit par la méthode de Tim est vide lorsque l'appel lève une exception. Je ne comprends pas complètement le code, mais il semble que la méthode de Tim entre dans le processus après le point où .Net a déjà invalidé et ignoré la réponse Web.
Je travaille avec un client qui développe manuellement un service Web avec un codage de bas niveau. À ce stade, ils ajoutent leurs propres messages d'erreur de processus internes sous forme de messages au format HTML dans la réponse AVANT la réponse au format SOAP. Bien sûr, la référence Web automagic .Net explose à ce sujet. Si je pouvais obtenir la réponse HTTP brute après qu'une exception a été lancée, je pourrais rechercher et analyser toute réponse SOAP dans la réponse HTTP de retour mixte et savoir qu'ils ont reçu mes données OK ou non.
Plus tard ...
Voici une solution qui fonctionne, même après une exécution (notez que je ne suis qu'après la réponse - je pourrais aussi obtenir la demande):
Voici comment vous le configurez dans le fichier de configuration:
"TestCallWebService" doit être remplacé par le nom de la bibliothèque (qui s'est avéré être le nom de l'application de la console de test dans laquelle je travaillais).
Vous ne devriez vraiment pas avoir à accéder à ChainStream; vous devriez pouvoir le faire plus simplement à partir de ProcessMessage comme:
Si vous recherchez SoapMessage.Stream, il est censé être un flux en lecture seule que vous pouvez utiliser pour inspecter les données à ce stade. C'est une mauvaise cause si vous lisez le flux, les bombes de traitement ultérieures sans données ont trouvé des erreurs (le flux était à la fin) et vous ne pouvez pas réinitialiser la position au début.
Fait intéressant, si vous utilisez les deux méthodes, ChainStream et ProcessMessage, la méthode ProcessMessage fonctionnera car vous avez changé le type de flux de ConnectStream en MemoryStream dans ChainStream, et MemoryStream autorise les opérations de recherche. (J'ai essayé de lancer ConnectStream sur MemoryStream - ce n'était pas autorisé.)
Donc ..... Microsoft devrait soit autoriser les opérations de recherche sur le type ChainStream, soit faire de SoapMessage.Stream une véritable copie en lecture seule comme il est censé l'être. (Écrivez à votre membre du Congrès, etc ...)
Un autre point. Après avoir créé un moyen de récupérer la réponse HTTP brute après une exception, je n'ai toujours pas obtenu la réponse complète (comme déterminé par un sniffer HTTP). En effet, lorsque le service Web de développement a ajouté les messages d'erreur HTML au début de la réponse, il n'a pas ajusté l'en-tête Content-Length, de sorte que la valeur Content-Length était inférieure à la taille du corps de la réponse réelle. Tout ce que j'ai obtenu était le nombre de caractères de la valeur Content-Length - le reste manquait. De toute évidence, lorsque .Net lit le flux de réponse, il lit simplement le nombre de caractères Content-Length et ne permet pas que la valeur Content-Length soit éventuellement fausse. C'est comme ça qu'il devrait être; mais si la valeur de l'en-tête Content-Length est fausse, la seule façon d'obtenir le corps de la réponse dans son intégralité est d'utiliser un sniffer HTTPhttp://www.ieinspector.com ).
la source
Je préférerais que le cadre fasse la journalisation pour vous en accrochant un flux de journalisation qui se connecte comme le cadre traite ce flux sous-jacent. Ce qui suit n'est pas aussi propre que je le voudrais, car vous ne pouvez pas choisir entre la demande et la réponse dans la méthode ChainStream. Voici comment je le gère. Remerciements à Jon Hanna pour l'idée dominante d'un stream
la source
Voici une version simplifiée de la réponse principale. Ajoutez ceci à l'
<configuration>
élément de votre fichierweb.config
ouApp.config
. Il créera untrace.log
fichier dans le dossier de votre projetbin/Debug
. Ou, vous pouvez spécifier un chemin absolu pour le fichier journal à l'aide de l'initializeData
attribut.Il avertit que les attributs
maxdatasize
ettracemode
ne sont pas autorisés, mais ils augmentent la quantité de données qui peuvent être enregistrées et évitent de tout enregistrer en hexadécimal.la source
Vous n'avez pas spécifié la langue que vous utilisez, mais en supposant C # / .NET, vous pouvez utiliser des extensions SOAP .
Sinon, utilisez un renifleur tel que Wireshark
la source
Je me rends compte que je suis assez en retard à la fête, et comme la langue n'a pas été spécifiée, voici une solution VB.NET basée sur la réponse de Bimmerbound, au cas où quelqu'un trébucherait sur cela et aurait besoin d'une solution. Remarque: vous devez avoir une référence à la classe stringbuilder dans votre projet, si vous ne l'avez pas déjà.
Appelez simplement la fonction et elle renverra une chaîne avec le xml sérialisé de l'objet que vous essayez de transmettre au service Web (en réalité, cela devrait fonctionner pour tout objet que vous souhaitez lui lancer).
En remarque, l'appel de remplacement dans la fonction avant de renvoyer le xml consiste à supprimer les caractères vbCrLf de la sortie. Le mien en avait un certain nombre dans le xml généré, mais cela variera évidemment en fonction de ce que vous essayez de sérialiser, et je pense qu'ils pourraient être supprimés lors de l'envoi de l'objet au service Web.
la source