WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

HttpRequest.Body から読み取る方法 (CORE)

by WebSurfer 15. April 2021 16:44

ASP.NET Core MVC / Razor Page には HttpRequest.Body プロパティというものがあって、要求のボディ部分を Stream として取得できます。しかしながら、それから StreamReader を使って内容を読みだすと空文字しか返ってきません。

Body の内容が空

それは何故なのかと、どのようにすれば読み出せるのかを書きます。それが何か役に立つのかと聞かれると自分は答えに窮しますが、とりあえず備忘録として。

読み出せないのは、上の画像の赤枠部分が示すように、Body プロパティから Stream を取得した時点で CanSeek が false になっており、Length プロパティも Position プロパティもサポートされていないからです。stackoverflow の記事 How to read ASP.NET Core Response.Body? によると "the Request.Body is a forward only stream that doesn't support seeking or reading the stream a second time" ということだそうです。

何故そういうことになっているかというと "to make the default configuration of request handling as lightweight and performant as possible" だからだそうです。それならそうと公式ドキュメントに書いておいてほしいと思うのですが・・・

どのようにすれば読み出せるかですが、HttpRequestRewindExtensions.EnableBuffering メソッドを設定することにより可能になります。

具体的には、startup.cs の Configure メソッドにミドルウェアとして以下のように登録します(Controller では効果は無いようです)。EnableBuffering メソッドにはオーバーロードが複数ありますので適当なものを選んでください。

app.Use(async (context, next) => {
    context.Request.EnableBuffering();
    await next();
});

上記の設定により、以下の画像の通り Body プロパティから取得した Stream の CanSeek が true になり、Position プロパティも有効になって巻き戻して(Position プロパティに 0 を設定して)複数回読むことが可能になります。

Body の内容取得

ただ、そのような設定をして複数回読めるようにすると、性能上の劣化が生じる可能性はあるかもしれません。

あと、stackoverflow の記事に書いてあるように、StreamReader を初期化する際は using は使わない、読み終わったら Position プロパティを 0 に設定しておくという点も注意した方が良さそうです。

Tags: , , ,

CORE

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  June 2021  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar