Próbuję rozwiązać problem z klientem usługi sieciowej w moim bieżącym projekcie. Nie jestem pewien platformy serwera usług (najprawdopodobniej LAMP). Uważam, że po ich stronie ogrodzenia jest błąd, ponieważ wyeliminowałem potencjalne problemy z moim klientem. Klient jest standardowym proxy odwołań do sieci WWW typu ASMX generowanym automatycznie z usługi WSDL.
To, do czego potrzebuję, to wiadomości RAW SOAP (żądanie i odpowiedzi)
Jaki jest najlepszy sposób, aby to zrobić?
Można zaimplementować SoapExtension, który rejestruje pełne żądanie i odpowiedź w pliku dziennika. Następnie możesz włączyć rozszerzenie SoapExtension w pliku web.config, co ułatwia włączanie / wyłączanie do celów debugowania. Oto przykład, który znalazłem i zmodyfikowałem na własny użytek, w moim przypadku logowanie zostało wykonane przez log4net, ale możesz zastąpić metody dziennika własnymi.
Następnie dodaj następującą sekcję do pliku web.config, gdzie YourNamespace i YourAssembly wskazują klasę i zestaw Twojego SoapExtension:
źródło
Nie wiem, po co tyle zamieszania z web.config lub klasą serializatora. Poniższy kod zadziałał dla mnie:
źródło
myEnvelope
bierze?Wypróbuj Fiddler2 , który pozwoli ci sprawdzić żądania i odpowiedzi. Warto zauważyć, że Fiddler działa zarówno z ruchem http, jak i https.
źródło
Wygląda na to, że rozwiązanie Tima Cartera nie działa, jeśli wywołanie odwołania internetowego zgłasza wyjątek. Próbowałem uzyskać odpowiedź nieprzetworzoną, aby móc ją zbadać (w kodzie) w programie obsługi błędów po wyrzuceniu wyjątku. Jednak stwierdzam, że dziennik odpowiedzi napisany przez metodę Tima jest pusty, gdy wywołanie zgłasza wyjątek. Nie rozumiem do końca kodu, ale wydaje się, że metoda Tima przerywa proces po punkcie, w którym .Net już unieważnił i odrzucił odpowiedź sieciową.
Pracuję z klientem, który ręcznie opracowuje usługę internetową z kodowaniem niskiego poziomu. W tym momencie dodają swoje własne wewnętrzne komunikaty o błędach procesu jako komunikaty w formacie HTML do odpowiedzi PRZED odpowiedzią w formacie SOAP. Oczywiście, pojawia się tutaj odniesienie do automagic .Net. Gdybym mógł uzyskać nieprzetworzoną odpowiedź HTTP po wyrzuceniu wyjątku, mógłbym poszukać i przeanalizować każdą odpowiedź SOAP w mieszanej zwrotnej odpowiedzi HTTP i wiedzieć, że otrzymali moje dane w porządku, czy nie.
Później ...
Oto rozwiązanie, które działa, nawet po wykonaniu (zwróć uwagę, że jestem dopiero po odpowiedzi - również mogę uzyskać żądanie):
Oto jak możesz to skonfigurować w pliku konfiguracyjnym:
„TestCallWebService” należy zastąpić nazwą biblioteki (była to nazwa aplikacji konsoli testowej, w której pracowałem).
Naprawdę nie powinieneś iść do ChainStream; powinieneś być w stanie zrobić to prościej z ProcessMessage, ponieważ:
Jeśli spojrzysz na SoapMessage.Stream, powinien to być strumień tylko do odczytu, którego możesz użyć do sprawdzenia danych w tym momencie. Jest to błąd, ponieważ jeśli odczytujesz strumień, kolejne przetwarzanie bomb bez błędów znalezionych danych (strumień był na końcu) i nie możesz zresetować pozycji do początku.
Co ciekawe, jeśli wykonasz obie metody, ChainStream i ProcessMessage, metoda ProcessMessage będzie działać, ponieważ zmieniono typ strumienia z ConnectStream na MemoryStream w ChainStream, a MemoryStream zezwala na operacje wyszukiwania. (Próbowałem rzucić ConnectStream na MemoryStream - nie było dozwolone.)
Więc ..... Microsoft powinien albo zezwolić na operacje wyszukiwania na typie ChainStream, albo uczynić SoapMessage.Stream prawdziwie kopią tylko do odczytu, tak jak powinna. (Napisz kongresmana itp.)
Jeszcze jeden punkt. Po utworzeniu sposobu na odzyskanie nieprzetworzonej odpowiedzi HTTP po wyjątku nadal nie otrzymałem pełnej odpowiedzi (określonej przez sniffer HTTP). Dzieje się tak, ponieważ gdy programistyczna usługa sieciowa dodawała komunikaty o błędach HTML na początku odpowiedzi, nie dostosowywała nagłówka Content-Length, więc wartość Content-Length była mniejsza niż rozmiar rzeczywistej treści odpowiedzi. Wszystko, co otrzymałem, to liczba znaków wartości Content-Length - reszty brakowało. Oczywiście, kiedy .Net czyta strumień odpowiedzi, po prostu czyta liczbę znaków Content-Length i nie pozwala na to, aby wartość Content-Length była błędna. Tak powinno być; ale jeśli wartość nagłówka Content-Length jest nieprawidłowa, jedynym sposobem, w jaki kiedykolwiek otrzymasz całą treść odpowiedzi, jest sniffer HTTP (używam analizatora HTTP zhttp://www.ieinspector.com ).
źródło
Wolałbym, aby platforma wykonywała rejestrowanie za Ciebie, przechodząc do strumienia rejestrowania, który rejestruje, gdy struktura przetwarza ten strumień. Poniższe nie są tak przejrzyste, jak bym chciał, ponieważ nie możesz zdecydować między żądaniem a odpowiedzią w metodzie ChainStream. Oto jak sobie z tym radzę. Z podziękowaniami dla Jona Hanny za nadrzędny pomysł na transmisję
źródło
Oto uproszczona wersja najlepszej odpowiedzi. Dodaj to do
<configuration>
elementu swojegoweb.config
lubApp.config
pliku. Utworzytrace.log
plik wbin/Debug
folderze twojego projektu . Lub możesz określić bezwzględną ścieżkę do pliku dziennika przy użyciuinitializeData
atrybutu.Ostrzega, że atrybuty
maxdatasize
itracemode
nie są dozwolone, ale zwiększają ilość danych, które mogą być rejestrowane, i unikają rejestrowania wszystkiego w postaci szesnastkowej.źródło
Nie określiłeś języka, którego używasz, ale zakładając C # / .NET, możesz użyć rozszerzeń SOAP .
W przeciwnym razie użyj sniffera, takiego jak Wireshark
źródło
Zdaję sobie sprawę, że jestem dość spóźniony na imprezę, a ponieważ język nie został określony, oto rozwiązanie VB.NET oparte na odpowiedzi Bimmerbound, na wypadek gdyby ktoś się na to natknął i potrzebował rozwiązania. Uwaga: musisz mieć odniesienie do klasy stringbuilder w swoim projekcie, jeśli jeszcze tego nie zrobiłeś.
Po prostu wywołaj funkcję, a zwróci ona ciąg znaków z zserializowanym kodem XML obiektu, który próbujesz przekazać do usługi sieciowej (realistycznie powinno to działać również dla każdego obiektu, który chcesz do niego rzucić).
Na marginesie, wywołanie replace w funkcji przed zwróceniem xml ma na celu usunięcie znaków vbCrLf z wyniku. Mój miał ich kilka w wygenerowanym pliku XML, ale oczywiście będzie się to różnić w zależności od tego, co próbujesz serializować i myślę, że mogą zostać usunięte podczas wysyłania obiektu do usługi internetowej.
źródło