web-dev-qa-db-ja.com

ASP.NETで生のリクエスト本文を取得する方法は?

の中に HttpApplication.BeginRequestイベント、生のリクエスト本文全体を読み取るにはどうすればよいですか?読み込もうとすると、InputStreamの長さが0であるため、ASP.NETによってすでに読み取られていると思われます。

私はこのようにInputStreamを読み込もうとしました:

using (StreamReader reader = new StreamReader(context.Request.InputStream))
{
    string text = reader.ReadToEnd();
}

しかし、私が得るのは空の文字列だけです。位置を0にリセットしましたが、もちろんストリームが読み取られると永久に消えてしまうため、うまくいきませんでした。最後に、ストリームの長さをチェックすると0が返されます。

編集:これはPOSTリクエスト用です。

31
Josh M.

要求オブジェクトは、BeginRequestイベントに取り込まれません。イベントのライフサイクルの後半で、このオブジェクトにアクセスする必要があります(Init、Load、PreRenderなど)。また、入力ストリームをメモリストリームにコピーして、seekを使用することもできます。

protected void Page_Load(object sender, EventArgs e)
{
    MemoryStream memstream = new MemoryStream();
    Request.InputStream.CopyTo(memstream);
    memstream.Position = 0;
    using (StreamReader reader = new StreamReader(memstream))
    {
        string text = reader.ReadToEnd();
    }
}
17
Pål Thingbø

Pålの答え は正しいですが、もっと短くすることもできます:

string req_txt;
using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
{
    req_txt = reader.ReadToEnd();
}

これは.NET 4.6にあります。

9
Ian

未処理のコンテンツを取得するための同様の要件があり、同じ問題にぶつかりました。 Seek(0, SeekOrigin.Begin)を呼び出すと問題が解決することがわかりました。

これは、基礎となるインフラストラクチャがどのように動作するかを想定しているため、特に良いアプローチではありませんが、機能しているようです。

4
Dale Anderson

ASP.NET Core 2の場合:

using (var reader = new StreamReader(HttpContext.Request.Body)) {
    var body = reader.ReadToEnd();
}
3

InputStreamの位置をリセットすることが重要です。

var memstream = new MemoryStream();
Request.InputStream.CopyTo(memstream);
Request.InputStream.Position = 0;
using (StreamReader reader = new StreamReader(memstream)) {
    var text = reader.ReadToEnd();
    Debug.WriteLine(text);
}
2
doker