WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

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

by WebSurfer 2021年4月15日 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月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar