質問: await reader.ReadToEndAsync().ConfigureAwait(false); } return Ok(bodyStr); } } ``` 以下、リクエストはPowerShellから投げております。 ``` #読み取れるリクエスト Invoke-WebRequest 'http://localhost:8080/Test' ` -mehtod post ` -Headers @{"Content-type"="text/plain"} ` -body 'hoge' #以下問題のリクエスト Invoke-WebRequest 'http://localhost:8080/Test' ` -mehtod post ` -Headers @{"Content-type"="application/x-www-form-urlencoded"} ` -body 'hoge' # 本来は"aaa=aaa&bbb=bbb"のような値を送りたい。 ``` ### 試したこと Postメソッドの引数に'[FromForm]'を指定すれば解決するのですが、Bodyの型を指定したくなく、すべてのリクエストに対応したいためあえてStreamを読み込んでおります。 前提に書きました通り、他のContent-Type(text/plain, text/xml, application/json等)で試行しております。その際は文字列は返却できておりました。 またStreamを読み込んだ時点で値が空となりますので、リクエスト返却時ではなくリクエスト受付時の問題と認識しております。 stackoverflowにてForwardを実装している記事を見たのですが、mvcではなくWebHttpRequestを利用したものとなっており、本問題には使えないかなと思い手詰まりとなってしまいました。 該当URL:stackoverflowのリンク 明確な質問とならず申し訳ございません。 ご助力いただけますと幸いです。 ### 補足情報(FW/ツールのバージョンなど) 言語:C# フレームワーク:.NetCore3.1 実行環境:VisualStudioProfessional2019 Version 16.8.5内のIISExpress
回答: 「Bodyから値を取得」とのことですが、MVC で受け取ってそれをそのまま「どこか他のAPIやWEBアプリ」に投げるということですか? それは全く普通ではない、少なくとも私の理解のはるか斜め上のことを考えておられるような気がします。時間制限するのが目的とのことですが、それだけならプロキシサーバーでも間に入れるとか、別の手段を考えた方が良いのでは? **【追記】** 下の 2021/04/13 10:47 の私のコメントで「後で回答欄に書いておきます」と書いた件です。 コメント欄で紹介した stackoverflow の記事 (URL 下記) の回答を検証してみました。それに書いてあるようにして Body から文字列を取得できます。 How to read ASP.NET Core Response.Body? startup.cs の Configure メソッドに**ミドルウェアとして**以下を登録。Controller では効果は無いようです。 ``` app.Use(async (context, next) => { context.Request.EnableBuffering(); await next(); }); ``` application/x-www-form-urlencoded 形式でデータを POST。下の画像は Fiddler で見た要求ヘッダとボディ。 !イメージ説明 アクションメソッドで HttpRequest.Body を取得。Position が末尾になっているので巻き戻してから(Position を 0 に設定してから)StreamReader で読むと Body の文字列を取得できます。。 !イメージ説明 デフォルトでは 1 回しか Body から読めないが、アクションメソッドで Body を取得する時点ではすでに読んでしまっているので Body から読めないということのようです。 上のようにすればアクションメソッドで巻き戻してもう一回読むことは可能です。ただし、わざわざそうしているのは "to make the default configuration of request handling as lightweight and performant as possible" ということだそうで、性能上の劣化が生じる可能性はあるかも。 あと、問題とは直接関係ない話ですが、stackoverflow の記事に書いてあるように、using は使わない、取得し終わったら Stream を巻き戻すようにするのがよいかもしれません。