Ich versuche, einen Webdienst-Client in meinem aktuellen Projekt zu reparieren. Ich bin mir nicht sicher über die Plattform des Service Servers (höchstwahrscheinlich LAMP). Ich glaube, es gibt einen Fehler auf ihrer Seite des Zauns, da ich die potenziellen Probleme mit meinem Kunden beseitigt habe. Der Client ist ein Standard-Webreferenz-Proxy vom Typ ASMX, der automatisch aus der Service-WSDL generiert wird.
Was ich erreichen muss, sind die RAW-SOAP-Nachrichten (Anfrage und Antworten)
Was ist der beste Weg, um dies zu erreichen?
Sie können eine SoapExtension implementieren, die die vollständige Anforderung und Antwort auf eine Protokolldatei protokolliert. Anschließend können Sie die SoapExtension in der Datei web.config aktivieren, wodurch das Ein- und Ausschalten für Debugging-Zwecke vereinfacht wird. Hier ist ein Beispiel, das ich für meinen eigenen Gebrauch gefunden und geändert habe. In meinem Fall wurde die Protokollierung von log4net durchgeführt, aber Sie können die Protokollierungsmethoden durch Ihre eigenen ersetzen.
Anschließend fügen Sie Ihrer web.config den folgenden Abschnitt hinzu, in dem YourNamespace und YourAssembly auf die Klasse und Assembly Ihrer SoapExtension verweisen:
quelle
Ich bin mir nicht sicher, warum ich so viel Aufhebens um web.config oder eine Serializer-Klasse mache. Der folgende Code hat bei mir funktioniert:
quelle
myEnvelope
das?Probieren Sie Fiddler2 aus, damit Sie die Anforderungen und Antworten überprüfen können. Es könnte erwähnenswert sein, dass Fiddler sowohl mit http- als auch mit https-Verkehr arbeitet.
quelle
Es sieht so aus, als ob die Lösung von Tim Carter nicht funktioniert, wenn der Aufruf der Webreferenz eine Ausnahme auslöst. Ich habe versucht, auf die unformatierte Webantwort zuzugreifen, damit ich sie (im Code) im Fehlerhandler untersuchen kann, sobald die Ausnahme ausgelöst wird. Ich stelle jedoch fest, dass das von Tims Methode geschriebene Antwortprotokoll leer ist, wenn der Aufruf eine Ausnahme auslöst. Ich verstehe den Code nicht vollständig, aber es scheint, dass Tims Methode in den Prozess einschneidet, nachdem .Net die Webantwort bereits ungültig gemacht und verworfen hat.
Ich arbeite mit einem Client zusammen, der einen Webdienst manuell mit niedriger Codierung entwickelt. Zu diesem Zeitpunkt fügen sie der Antwort VOR der SOAP-formatierten Antwort ihre eigenen internen Prozessfehlermeldungen als HTML-formatierte Nachrichten hinzu. Natürlich sprengt die automagische .Net-Webreferenz dies. Wenn ich nach dem Auslösen einer Ausnahme auf die unformatierte HTTP-Antwort zugreifen könnte, könnte ich jede SOAP-Antwort in der gemischten HTTP-Antwort suchen und analysieren und wissen, ob meine Daten in Ordnung sind oder nicht.
Später ...
Hier ist eine Lösung, die auch nach einer Ausführung funktioniert (beachten Sie, dass ich erst nach der Antwort bin - könnte auch die Anfrage erhalten):
So konfigurieren Sie es in der Konfigurationsdatei:
"TestCallWebService" sollte durch den Namen der Bibliothek ersetzt werden (dies war zufällig der Name der Testkonsolen-App, in der ich gearbeitet habe).
Sie sollten wirklich nicht zu ChainStream gehen müssen; Sie sollten dies in ProcessMessage einfacher tun können als:
Wenn Sie nach SoapMessage.Stream suchen, sollte es sich um einen schreibgeschützten Stream handeln, mit dem Sie die Daten an dieser Stelle überprüfen können. Dies ist ein Fehler, denn wenn Sie den Stream lesen, nachfolgende Verarbeitungsbomben ohne Datenfehler gefunden haben (Stream war am Ende) und Sie die Position nicht auf den Anfang zurücksetzen können.
Interessanterweise funktioniert die ProcessMessage-Methode, wenn Sie beide Methoden ausführen, ChainStream und ProcessMessage, da Sie den Stream-Typ in ChainStream von ConnectStream in MemoryStream geändert haben und MemoryStream Suchvorgänge zulässt. (Ich habe versucht, den ConnectStream in MemoryStream zu übertragen - war nicht zulässig.)
Also ..... Microsoft sollte entweder Suchvorgänge für den ChainStream-Typ zulassen oder SoapMessage.Stream wirklich zu einer schreibgeschützten Kopie machen, wie sie sein soll. (Schreiben Sie Ihren Kongressabgeordneten usw.)
Ein weiterer Punkt. Nachdem ich eine Möglichkeit erstellt hatte, die unformatierte HTTP-Antwort nach einer Ausnahme abzurufen, erhielt ich immer noch nicht die vollständige Antwort (wie von einem HTTP-Sniffer ermittelt). Dies lag daran, dass der Entwicklungswebdienst beim Hinzufügen der HTML-Fehlermeldungen am Anfang der Antwort den Content-Length-Header nicht anpasste, sodass der Content-Length-Wert kleiner als die Größe des tatsächlichen Antwortkörpers war. Alles, was ich bekam, war die Anzahl der Zeichen für den Wert der Inhaltslänge - der Rest fehlte. Wenn .Net den Antwortstrom liest, liest es natürlich nur die Anzahl der Zeichen für die Inhaltslänge und lässt nicht zu, dass der Wert für die Inhaltslänge möglicherweise falsch ist. Das ist so wie es sein sollte; Wenn der Content-Length-Header-Wert jedoch falsch ist, erhalten Sie den gesamten Antworttext nur mit einem HTTP-Sniffer (ich benutze HTTP Analyzer vonhttp://www.ieinspector.com ).
quelle
Ich würde es vorziehen, wenn das Framework die Protokollierung für Sie durchführt, indem es einen Protokollierungsdatenstrom einbindet, der protokolliert, während das Framework den zugrunde liegenden Datenstrom verarbeitet. Das Folgende ist nicht so sauber, wie ich es gerne hätte, da Sie sich in der ChainStream-Methode nicht zwischen Anfrage und Antwort entscheiden können. Das Folgende ist, wie ich damit umgehe. Vielen Dank an Jon Hanna für das Überschreiben einer Stream-Idee
quelle
Hier ist eine vereinfachte Version der Top-Antwort. Fügen Sie dies dem
<configuration>
Element Ihrerweb.config
oderApp.config
Datei hinzu. Es wird einetrace.log
Datei imbin/Debug
Ordner Ihres Projekts erstellt . Oder Sie können mithilfe desinitializeData
Attributs einen absoluten Pfad für die Protokolldatei angeben .Es warnt davor, dass die Attribute
maxdatasize
undtracemode
nicht zulässig sind, erhöht jedoch die Datenmenge, die protokolliert werden kann, und vermeidet, alles in hexadezimaler Form zu protokollieren.quelle
Sie haben nicht angegeben, welche Sprache Sie verwenden, aber unter der Annahme von C # / .NET können Sie SOAP-Erweiterungen verwenden .
Verwenden Sie andernfalls einen Schnüffler wie Wireshark
quelle
Mir ist klar, dass ich ziemlich spät zur Party komme, und da die Sprache nicht wirklich angegeben wurde, ist hier eine VB.NET-Lösung, die auf der Antwort von Bimmerbound basiert, falls jemand darüber stolpert und eine Lösung benötigt. Hinweis: Wenn Sie dies noch nicht getan haben, benötigen Sie einen Verweis auf die Stringbuilder-Klasse in Ihrem Projekt.
Rufen Sie einfach die Funktion auf und es wird eine Zeichenfolge mit der serialisierten XML des Objekts zurückgegeben, das Sie an den Webdienst übergeben möchten (realistisch gesehen sollte dies für jedes Objekt funktionieren, das Sie auch darauf werfen möchten).
Als Randnotiz besteht der Ersetzungsaufruf in der Funktion vor der Rückgabe der XML darin, vbCrLf-Zeichen aus der Ausgabe zu entfernen. Meins hatte eine Menge davon in der generierten XML-Datei, dies hängt jedoch offensichtlich davon ab, was Sie serialisieren möchten, und ich denke, dass sie möglicherweise entfernt werden, während das Objekt an den Webdienst gesendet wird.
quelle