Piszę usługę sieciową (używając ASP.NET MVC) i dla celów wsparcia chcielibyśmy móc rejestrować żądania i odpowiedzi w jak najbardziej zbliżonym do surowego formacie on-the-wire (tj. W tym HTTP metoda, ścieżka, wszystkie nagłówki i treść) do bazy danych.
Nie jestem pewien, jak zdobyć te dane w najmniej „zniekształcony” sposób. Mogę ponownie określić, jak moim zdaniem wygląda żądanie, sprawdzając wszystkie właściwości HttpRequest
obiektu i budując z nich ciąg (i podobnie w przypadku odpowiedzi), ale naprawdę chciałbym uzyskać rzeczywiste dane żądania / odpowiedzi, które wysłane za pośrednictwem drutu.
Z przyjemnością używam dowolnego mechanizmu przechwytywania, takiego jak filtry, moduły itp., A rozwiązanie może być specyficzne dla IIS7. Jednak wolałbym zachować go tylko w kodzie zarządzanym.
Jakieś zalecenia?
Edycja: Zauważyłem, że HttpRequest
ma SaveAs
metodę, która może zapisać żądanie na dysku, ale to rekonstruuje żądanie ze stanu wewnętrznego przy użyciu obciążenia wewnętrznych metod pomocniczych, do których nie można uzyskać dostępu publicznie (dlaczego nie pozwala to na zapisanie do podanego przez użytkownika strumień nie wiem). Zaczyna więc wyglądać, że będę musiał zrobić co w mojej mocy, aby zrekonstruować tekst żądania / odpowiedzi z obiektów ... jęk.
Edycja 2: Proszę zauważyć, że powiedziałem, że całe żądanie, w tym metoda, ścieżka, nagłówki itp. Bieżące odpowiedzi dotyczą tylko strumieni treści, które nie zawierają tych informacji.
Edycja 3: Czy nikt tutaj nie czyta pytań? Jak dotąd pięć odpowiedzi, a jednak żadna z nich nie wskazuje nawet sposobu na uzyskanie całego surowego żądania w sieci. Tak, wiem, że mogę przechwytywać strumienie wyjściowe, nagłówki, adres URL i wszystko inne z obiektu żądania. Powiedziałem już, że w pytaniu zobacz:
Mogę odtworzyć to, jak moim zdaniem wygląda żądanie, sprawdzając wszystkie właściwości obiektu HttpRequest i budując z nich ciąg (i podobnie w przypadku odpowiedzi), ale naprawdę chciałbym uzyskać rzeczywiste dane żądania / odpowiedzi to jest wysłane przez kabel.
Jeśli znasz kompletne nieprzetworzone dane (w tym nagłówki, adres URL, metodę http itp.), Po prostu nie możesz ich pobrać, wtedy warto to wiedzieć. Podobnie, jeśli wiesz, jak uzyskać to wszystko w formacie surowym (tak, nadal mam na myśli włączenie nagłówków, adresu URL, metody http itp.) Bez konieczności rekonstrukcji, o co prosiłem, wtedy byłoby to bardzo przydatne. Ale mówienie mi, że mogę to zrekonstruować z HttpRequest
/ HttpResponse
obiektów, nie jest przydatne. Wiem to. Już to powiedziałem.
Uwaga: zanim ktokolwiek zacznie mówić, że to zły pomysł lub ograniczy skalowalność itp., Zaimplementujemy również mechanizmy ograniczania przepustowości, dostarczania sekwencyjnego i zapobiegania powtórzeniom w środowisku rozproszonym, więc i tak rejestrowanie bazy danych jest wymagane. Nie szukam dyskusji, czy to dobry pomysł, szukam, jak można to zrobić.
źródło
Odpowiedzi:
Zdecydowanie użyj
IHttpModule
i zaimplementuj zdarzeniaBeginRequest
iEndRequest
.Wszystkie „surowe” dane są obecne między
HttpRequest
aHttpResponse
, po prostu nie są w jednym nieprzetworzonym formacie. Oto części potrzebne do zbudowania zrzutów w stylu Fiddlera (prawie tak blisko surowego HTTP, jak to tylko możliwe):Aby uzyskać odpowiedź:
Pamiętaj, że nie możesz odczytać strumienia odpowiedzi, więc musisz dodać filtr do strumienia wyjściowego i przechwycić kopię.
W swoim
BeginRequest
będziesz musiał dodać filtr odpowiedzi:Przechowaj,
filter
gdzie możesz się do niego dostać w programieEndRequest
obsługi. Proponuję wHttpContext.Items
. Tam można uzyskać pełne dane odpowiedzi w formaciefilter.ReadStream()
.Następnie zaimplementuj
OutputFilterStream
za pomocą wzorca dekoratora jako opaski wokół strumienia:źródło
Poniższa metoda rozszerzenia w HttpRequest utworzy ciąg, który można wkleić do programu Fiddler i odtworzyć.
źródło
HttpRequestBaseExtensions
iHttpRequest
naHttpRequestBase
w każdym miejscu.Możesz użyć zmiennej serwera ALL_RAW, aby pobrać oryginalne nagłówki HTTP wysłane z żądaniem, a następnie możesz normalnie pobrać InputStream:
sprawdź: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx
źródło
HttpContext.Current.Request
aby pobrać bieżący kontekst poza kontrolerami MVC, stronami ASPX itp ... tylko upewnij się, że nie jest on null pierwszy;)Cóż, pracuję nad projektem i zrobiłem, może niezbyt głęboki, dziennik używając parametrów żądania:
Spójrz:
Możesz udekorować swoją klasę kontrolerów, aby całkowicie ją rejestrować:
lub zarejestruj tylko niektóre indywidualne metody akcji
źródło
Czy jest jakiś powód, dla którego musisz zachować go w kodzie zarządzanym?
Warto wspomnieć, że możesz włączyć rejestrowanie nieudanego śledzenia w IIS7, jeśli nie lubisz ponownie wymyślać koła. To rejestruje nagłówki, treść żądania i odpowiedzi, a także wiele innych rzeczy.
źródło
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
na końcuRegister(..)
inWebApiConfig.cs
, ale może się to różnić w zależności od wersji.Poszedłem z podejściem McKAMEYA. Oto moduł, który napisałem, który pomoże Ci zacząć i miejmy nadzieję, pozwoli Ci zaoszczędzić trochę czasu. Będziesz oczywiście musiał podłączyć Logger do czegoś, co działa dla Ciebie:
źródło
Encoding.UTF8
, a możeEncoding.Default
podczas czytania strumienia żądań? Lub po prostu użyjStreamReader
( z usuwaniem zastrzeżeń )OK, więc wygląda na to, że odpowiedź brzmi "nie, nie możesz pobrać surowych danych, musisz zrekonstruować żądanie / odpowiedź z właściwości przeanalizowanych obiektów". No cóż, zrobiłem rekonstrukcję.
źródło
użyj IHttpModule :
źródło
jeśli do okazjonalnego użytku, aby ominąć ciasny róg, co powiesz na coś prymitywnego jak poniżej?
źródło
Możesz to zrobić
DelegatingHandler
bez korzystania zOutputFilter
wymienionych w innych odpowiedziach w .NET 4.5 za pomocąStream.CopyToAsync()
funkcji.Nie jestem pewien szczegółów, ale nie powoduje to wszystkich złych rzeczy, które mają miejsce, gdy próbujesz bezpośrednio odczytać strumień odpowiedzi.
Przykład:
źródło
Wiem, że to nie jest kod zarządzany, ale mam zamiar zasugerować filtr ISAPI. Minęło kilka lat, odkąd miałem „przyjemność” utrzymywać własny ISAPI, ale z tego, co pamiętam, możesz uzyskać dostęp do wszystkich tych rzeczy, zarówno przed, jak i po tym, jak ASP.Net już to zrobił.
http://msdn.microsoft.com/en-us/library/ms524610.aspx
Jeśli moduł HTTPModule nie jest wystarczająco dobry dla tego, czego potrzebujesz, po prostu nie sądzę, aby można było to zrobić w wymaganej ilości szczegółów. Jednak będzie to trudne.
źródło
Zgadzam się z innymi, użyj IHttpModule. Spójrz na odpowiedź na to pytanie, która robi prawie to samo, o co pytasz. Rejestruje żądanie i odpowiedź, ale bez nagłówków.
Jak śledzić żądania ScriptService WebService?
źródło
Najlepiej zrobić to poza aplikacją. Możesz skonfigurować odwrotne proxy, aby robić takie rzeczy (i wiele więcej). Odwrotny serwer proxy to w zasadzie serwer WWW, który znajduje się w twojej serwerowni i znajduje się między twoim serwerem (serwerami) WWW a klientem. Zobacz http://en.wikipedia.org/wiki/Reverse_proxy
źródło
Zgadzam się z FigmentEngine,
IHttpModule
wydaje się być drogą do zrobienia.Spójrz w
httpworkerrequest
,readentitybody
iGetPreloadedEntityBody
.Aby uzyskać
httpworkerrequest
, musisz to zrobić:gdzie
inApp
jest obiekt httpapplication.źródło
HttpRequest
aHttpResponse
wcześniej MVC miałGetInputStream()
iGetOutputStream()
może być użyty do tego celu. Nie zaglądałem do tych części w MVC, więc nie jestem pewien, czy są dostępne, ale może to być pomysł :)źródło