Ich schreibe einen Webdienst (mit ASP.NET MVC) und zu Supportzwecken möchten wir die Anforderungen und Antworten so nah wie möglich am unformatierten On-the-Wire-Format (dh einschließlich HTTP) protokollieren können Methode, Pfad, alle Header und der Body) in eine Datenbank.
Ich bin mir nicht sicher, wie ich diese Daten auf die am wenigsten "verstümmelte" Weise erreichen kann. Ich kann wieder herstellen, wie die Anfrage meiner Meinung nach aussieht, indem ich alle Eigenschaften des HttpRequest
Objekts überprüfe und daraus eine Zeichenfolge erstelle (und ähnlich für die Antwort), aber ich möchte wirklich die tatsächlichen Anforderungs- / Antwortdaten erhalten, die es sind auf den Draht geschickt.
Ich verwende gerne Abfangmechanismen wie Filter, Module usw., und die Lösung kann spezifisch für IIS7 sein. Ich würde es jedoch vorziehen, es nur in verwaltetem Code zu belassen.
Irgendwelche Empfehlungen?
Bearbeiten: Ich stelle fest, dass HttpRequest
es eine SaveAs
Methode gibt, mit der die Anforderung auf der Festplatte gespeichert werden kann, die jedoch die Anforderung aus dem internen Status mithilfe einer Reihe interner Hilfsmethoden rekonstruiert, auf die nicht öffentlich zugegriffen werden kann (weshalb dies das Speichern auf einem vom Benutzer bereitgestellten Gerät nicht zulässt Stream weiß ich nicht). Es sieht also so aus, als müsste ich mein Bestes geben, um den Anforderungs- / Antworttext aus den Objekten zu rekonstruieren ... Stöhnen.
Bearbeiten 2: Bitte beachten Sie, dass ich die gesamte Anfrage einschließlich Methode, Pfad, Header usw. gesagt habe . Die aktuellen Antworten beziehen sich nur auf die Body-Streams, die diese Informationen nicht enthalten.
Edit 3: Liest hier niemand Fragen? Bisher fünf Antworten, von denen noch keine einen Hinweis darauf gibt, wie die gesamte rohe On-the-Wire-Anfrage beantwortet werden kann. Ja, ich weiß, dass ich die Ausgabestreams und die Header sowie die URL und all das Zeug vom Anforderungsobjekt erfassen kann. Ich habe das bereits in der Frage gesagt, siehe:
Ich kann wieder herstellen, wie die Anfrage meiner Meinung nach aussieht, indem ich alle Eigenschaften des HttpRequest-Objekts überprüfe und daraus eine Zeichenfolge (und ähnlich für die Antwort) erstelle, aber ich möchte wirklich die tatsächlichen Anforderungs- / Antwortdaten abrufen das ist auf dem Draht gesendet.
Wenn Sie wissen, dass die vollständigen Rohdaten (einschließlich Header, URL, http-Methode usw.) einfach nicht abgerufen werden können, ist dies hilfreich. Wenn Sie wissen, wie Sie alles im Rohformat erhalten (ja, ich meine immer noch Header, URL, http-Methode usw.), ohne es rekonstruieren zu müssen, was ich gefragt habe, dann wäre das sehr nützlich. Es ist jedoch nicht sinnvoll , mir zu sagen, dass ich es aus den HttpRequest
/ HttpResponse
-Objekten rekonstruieren kann. Ich weiß das. Ich habe es schon gesagt.
Bitte beachten Sie: Bevor jemand anfängt zu sagen, dass dies eine schlechte Idee ist oder die Skalierbarkeit usw. einschränkt, werden wir auch Drosselungs-, sequentielle Übermittlungs- und Anti-Replay-Mechanismen in einer verteilten Umgebung implementieren, sodass ohnehin eine Datenbankprotokollierung erforderlich ist. Ich suche keine Diskussion darüber, ob dies eine gute Idee ist, ich suche nach Möglichkeiten, wie dies getan werden kann.
quelle
Antworten:
Verwenden Sie auf jeden Fall ein
IHttpModule
und implementieren Sie dieBeginRequest
undEndRequest
-Ereignisse.Alle "Rohdaten" sind zwischen
HttpRequest
undHttpResponse
nur in einem einzigen Rohformat vorhanden. Hier sind die Teile, die zum Erstellen von Dumps im Fiddler-Stil benötigt werden (ungefähr so nah wie möglich an rohem HTTP):Für die Antwort:
Beachten Sie, dass Sie den Antwortstrom nicht lesen können, sodass Sie dem Ausgabestream einen Filter hinzufügen und eine Kopie erfassen müssen.
In Ihrem
BeginRequest
müssen Sie einen Antwortfilter hinzufügen:Speichern
filter
Sie imEndRequest
Handler, wo Sie darauf zugreifen können. Ich schlage vorHttpContext.Items
. Dort können dann die vollständigen Antwortdaten abgerufen werdenfilter.ReadStream()
.Implementieren Sie dann
OutputFilterStream
das Decorator-Muster als Wrapper um einen Stream:quelle
Die folgende Erweiterungsmethode für HttpRequest erstellt eine Zeichenfolge, die in Fiddler eingefügt und wiedergegeben werden kann.
quelle
HttpRequestBaseExtensions
und zu ändern ,HttpRequest
umHttpRequestBase
an jedem Ort.Sie können die Servervariable ALL_RAW verwenden, um die ursprünglichen HTTP-Header abzurufen, die mit der Anforderung gesendet wurden. Anschließend können Sie den InputStream wie gewohnt abrufen:
Überprüfen Sie: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx
quelle
HttpContext.Current.Request
, um den aktuellen Kontext außerhalb von MVC-Controllern, ASPX-Seiten usw.Nun, ich arbeite an einem Projekt und habe, vielleicht nicht zu tief, ein Protokoll mit den Anforderungsparametern erstellt:
Schau mal:
Sie können Ihre Controller-Klasse dekorieren, um sie vollständig zu protokollieren:
oder protokollieren Sie nur einige einzelne Aktionsmethoden
quelle
Gibt es einen Grund, warum Sie es im verwalteten Code behalten müssen?
Es ist erwähnenswert , dass Sie aktivieren können Trace - Protokollierung können nicht in IIS7 , wenn Sie nicht wie neu zu erfinden das Rad. Dies protokolliert Header, den Anforderungs- und Antworttext sowie viele andere Dinge.
quelle
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
am Ende vonRegister(..)
in hinzugefügt werden.WebApiConfig.cs
Dies kann jedoch zwischen den Versionen variieren.Ich habe mich für McKAMEY entschieden. Hier ist ein Modul, das ich geschrieben habe, um Ihnen den Einstieg zu erleichtern und Ihnen hoffentlich etwas Zeit zu sparen. Sie müssen den Logger offensichtlich mit etwas verbinden, das für Sie funktioniert:
quelle
Encoding.UTF8
oder vielleichtEncoding.Default
beim Lesen des Anforderungsstroms? Oder verwenden Sie einfach eineStreamReader
( mit Vorbehalt )OK, es sieht also so aus, als ob die Antwort "Nein, Sie können die Rohdaten nicht erhalten, Sie müssen die Anforderung / Antwort aus den Eigenschaften der analysierten Objekte rekonstruieren" lautet. Na ja, ich habe den Wiederaufbau gemacht.
quelle
Verwenden Sie ein IHttpModule :
quelle
Wenn Sie es gelegentlich benutzen, um um eine enge Ecke zu kommen, wie wäre es dann mit etwas Grobem wie unten?
quelle
Sie können dies in a erreichen,
DelegatingHandler
ohne dieOutputFilter
in anderen Antworten in .NET 4.5 genannten zu verwendenStream.CopyToAsync()
Funktionen zu verwenden.Ich bin mir bei den Details nicht sicher, aber es löst nicht alle schlechten Dinge aus, die passieren, wenn Sie versuchen, den Antwortstrom direkt zu lesen.
Beispiel:
quelle
Ich weiß, dass es sich nicht um verwalteten Code handelt, aber ich werde einen ISAPI-Filter vorschlagen. Es ist ein paar Jahre her, seit ich das "Vergnügen" hatte, mein eigenes ISAPI zu pflegen, aber soweit ich mich erinnere, können Sie auf all diese Dinge zugreifen, sowohl vor als auch nachdem ASP.Net es getan hat.
http://msdn.microsoft.com/en-us/library/ms524610.aspx
Wenn ein HTTPModul nicht gut genug für das ist, was Sie brauchen, dann glaube ich einfach nicht, dass es eine verwaltete Möglichkeit gibt, dies in der erforderlichen Menge an Details zu tun. Es wird allerdings ein Schmerz sein.
quelle
Ich stimme den anderen zu, benutze ein IHttpModule. Schauen Sie sich die Antwort auf diese Frage an, die fast das Gleiche tut, was Sie stellen. Es protokolliert die Anforderung und Antwort, jedoch ohne Header.
Wie verfolge ich ScriptService WebService-Anforderungen?
quelle
Es ist möglicherweise am besten, dies außerhalb Ihrer Anwendung zu tun. Sie können einen Reverse-Proxy einrichten, um solche Dinge (und vieles mehr) zu tun. Ein Reverse-Proxy ist im Grunde ein Webserver, der sich in Ihrem Serverraum befindet und zwischen Ihren Webservern und dem Client steht. Siehe http://en.wikipedia.org/wiki/Reverse_proxy
quelle
Stimmen Sie mit FigmentEngine überein,
IHttpModule
scheint der Weg zu sein.Schauen Sie in
httpworkerrequest
,readentitybody
undGetPreloadedEntityBody
.Um das zu bekommen
httpworkerrequest
, müssen Sie dies tun:Wo
inApp
ist das httpapplication-Objekt?quelle
HttpRequest
undHttpResponse
vor MVC hatte früher einGetInputStream()
undGetOutputStream()
das könnte für diesen Zweck verwendet werden. Ich habe mir diesen Teil in MVC nicht angesehen, daher bin ich mir nicht sicher, ob er verfügbar ist, könnte aber eine Idee sein :)quelle