Saya sedang menulis layanan web (menggunakan ASP.NET MVC) dan untuk tujuan dukungan kami ingin dapat mencatat permintaan dan tanggapan sedekat mungkin dengan format mentah, on-the-wire (yaitu termasuk HTTP metode, path, semua header, dan tubuh) ke dalam database.
Apa yang saya tidak yakin adalah bagaimana mendapatkan data ini dengan cara yang paling 'rusak'. Saya dapat membentuk kembali seperti apa yang saya yakini seperti permintaan dengan memeriksa semua properti dariHttpRequest
objek dan membangun string dari mereka (dan juga untuk respon) tetapi saya benar-benar ingin mendapatkan data permintaan / respons aktual yang dikirim melalui kawat.
Saya senang menggunakan mekanisme intersepsi seperti filter, modul, dll. Dan solusinya dapat spesifik untuk IIS7. Namun, saya lebih suka menyimpannya dalam kode terkelola saja.
Ada rekomendasi?
Sunting: Saya perhatikan bahwa HttpRequest
memiliki SaveAs
metode yang dapat menyimpan permintaan ke disk tetapi ini merekonstruksi permintaan dari kondisi internal menggunakan beban metode pembantu internal yang tidak dapat diakses secara publik (cukup mengapa ini tidak memungkinkan menyimpan ke yang disediakan pengguna) aliran saya tidak tahu). Jadi itu mulai terlihat seperti saya harus melakukan yang terbaik untuk merekonstruksi teks permintaan / respons dari objek ... erangan.
Sunting 2: Harap perhatikan bahwa saya mengatakan seluruh permintaan termasuk metode, jalur, tajuk dll. Respons saat ini hanya melihat aliran tubuh yang tidak termasuk informasi ini.
Sunting 3: Apakah tidak ada yang membaca pertanyaan di sekitar sini? Sejauh ini lima jawaban namun tidak ada satu pun petunjuk tentang cara untuk mendapatkan seluruh permintaan mentah on-the-wire. Ya, saya tahu saya bisa menangkap aliran keluaran dan tajuk serta URL dan semua itu dari objek permintaan. Saya sudah mengatakan itu dalam pertanyaan, lihat:
Saya dapat membentuk kembali apa yang saya yakini seperti permintaan dengan memeriksa semua properti dari objek HttpRequest dan membuat string dari mereka (dan juga untuk respon) tetapi saya benar-benar ingin mendapatkan data request / response yang sebenarnya yang dikirim pada kabel.
Jika Anda mengetahui data mentah lengkap (termasuk tajuk, url, metode http, dll.) Tidak dapat diambil maka itu akan berguna untuk diketahui. Demikian pula jika Anda tahu cara mendapatkan semuanya dalam format mentah (ya, maksud saya masih termasuk header, url, metode http, dll.) Tanpa harus merekonstruksi itu, yang saya tanyakan, maka itu akan sangat berguna. Tetapi mengatakan kepada saya bahwa saya dapat merekonstruksinya dari HttpRequest
/ HttpResponse
objek tidak berguna. Saya tahu itu. Saya sudah mengatakannya.
Harap dicatat: Sebelum ada yang mulai mengatakan ini adalah ide yang buruk, atau akan membatasi skalabilitas, dll., Kami juga akan menerapkan mekanisme pelambatan, pengiriman berurutan, dan anti-ulangan di lingkungan terdistribusi, sehingga pembuatan basis data tetap diperlukan. Saya tidak mencari diskusi apakah ini ide yang baik, saya sedang mencari cara untuk melakukannya.
sumber
Jawaban:
Pasti menggunakan
IHttpModule
dan menerapkanBeginRequest
danEndRequest
acara.Semua data "mentah" ada di antaranya
HttpRequest
danHttpResponse
, itu tidak dalam format mentah tunggal. Berikut adalah bagian-bagian yang diperlukan untuk membangun dump gaya-Fiddler (sedekat mungkin dengan HTTP mentah):Untuk tanggapan:
Perhatikan bahwa Anda tidak dapat membaca aliran respons sehingga Anda harus menambahkan filter ke aliran Output dan mengambil salinan.
Di Anda
BeginRequest
, Anda perlu menambahkan filter tanggapan:Simpan di
filter
mana Anda bisa mendapatkannya diEndRequest
handler. Saya sarankan diHttpContext.Items
. Di sana kemudian bisa mendapatkan data respons penuhfilter.ReadStream()
.Kemudian implementasikan
OutputFilterStream
menggunakan pola Dekorator sebagai pembungkus di sekitar aliran:sumber
Metode ekstensi berikut pada HttpRequest akan membuat string yang dapat disisipkan ke fiddler dan diputar ulang.
sumber
HttpRequestBaseExtensions
dan untuk mengubahHttpRequest
keHttpRequestBase
di setiap tempat.Anda dapat menggunakan variabel server ALL_RAW untuk mendapatkan tajuk HTTP asli yang dikirim bersama permintaan, maka Anda bisa mendapatkan InputStream seperti biasa:
periksa: http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx
sumber
HttpContext.Current.Request
untuk mengambil konteks saat ini di luar pengontrol MVC, halaman ASPX, dll ... pastikan saja itu bukan null pertama;)Yah, saya sedang mengerjakan sebuah proyek dan melakukan, mungkin tidak terlalu dalam, sebuah log menggunakan params permintaan:
Lihatlah:
Anda dapat mendekorasi kelas pengontrol Anda untuk mencatatnya sepenuhnya:
atau catat hanya beberapa metode tindakan individu
sumber
Adakah alasan Anda harus menyimpannya dalam kode terkelola?
Perlu disebutkan bahwa Anda dapat mengaktifkan Failed Trace logging di IIS7 jika Anda tidak suka menciptakan kembali roda. Ini mencatat tajuk, badan permintaan dan tanggapan, serta banyak hal lainnya.
sumber
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
di akhirRegister(..)
inWebApiConfig.cs
, tetapi ini dapat bervariasi antar versi.Saya pergi dengan pendekatan McKAMEY. Berikut adalah modul yang saya tulis yang akan membantu Anda memulai dan semoga menghemat waktu. Anda harus mencolokkan Logger dengan sesuatu yang cocok untuk Anda:
sumber
Encoding.UTF8
, atau mungkinEncoding.Default
saat membaca aliran permintaan? Atau hanya menggunakanStreamReader
( dengan membuang peringatan )OK, jadi sepertinya jawabannya adalah "tidak, Anda tidak bisa mendapatkan data mentah, Anda harus merekonstruksi permintaan / respons dari properti objek yang diuraikan". Oh well, saya sudah melakukan rekonstruksi.
sumber
gunakan IHttpModule :
sumber
jika untuk penggunaan sesekali, untuk menyiasati, bagaimana dengan sesuatu yang kasar seperti di bawah ini?
sumber
Anda dapat melakukan ini dalam
DelegatingHandler
tanpa menggunakan yangOutputFilter
disebutkan dalam jawaban lain di .NET 4.5 menggunakanStream.CopyToAsync()
fungsi.Saya tidak yakin tentang detailnya, tetapi itu tidak memicu semua hal buruk yang terjadi ketika Anda mencoba untuk langsung membaca aliran respons.
Contoh:
sumber
Saya tahu ini bukan kode yang dikelola, tapi saya akan menyarankan filter ISAPI. Sudah beberapa tahun sejak saya memiliki "kesenangan" mempertahankan ISAPI saya sendiri tetapi dari apa yang saya ingat Anda bisa mendapatkan akses ke semua hal ini, baik sebelum dan sesudah ASP.Net telah melakukan hal itu.
http://msdn.microsoft.com/en-us/library/ms524610.aspx
Jika HTTPModule tidak cukup baik untuk apa yang Anda butuhkan, maka saya rasa tidak ada cara yang dikelola untuk melakukan ini dalam jumlah detail yang diperlukan. Ini akan menjadi sakit untuk dilakukan.
sumber
Saya setuju dengan yang lain, gunakan IHttpModule. Lihatlah jawaban untuk pertanyaan ini, yang melakukan hal yang hampir sama dengan yang Anda tanyakan. Ini mencatat permintaan dan respons, tetapi tanpa header.
Bagaimana cara melacak permintaan ScriptService WebService?
sumber
Mungkin yang terbaik untuk melakukan ini di luar aplikasi Anda. Anda dapat mengatur proxy terbalik untuk melakukan hal-hal seperti ini (dan banyak lagi). Proxy terbalik pada dasarnya adalah server web yang berada di ruang server Anda, dan berdiri di antara server web Anda dan klien. Lihat http://en.wikipedia.org/wiki/Reverse_proxy
sumber
Setuju dengan FigmentEngine,
IHttpModule
tampaknya menjadi cara untuk pergi.Lihatlah ke dalam
httpworkerrequest
,readentitybody
danGetPreloadedEntityBody
.Untuk mendapatkan
httpworkerrequest
Anda perlu melakukan ini:di mana objek
inApp
aplikasi http.sumber
HttpRequest
danHttpResponse
pra MVC dulu memilikiGetInputStream()
danGetOutputStream()
yang dapat digunakan untuk tujuan itu. Belum melihat bagian-bagian dalam MVC jadi saya tidak yakin mereka tersedia tetapi mungkin ide :)sumber