デバッグコードをいくつかテストして、デバッグコードが期待どおりに動作していませんでした。以下の例は、私の質問を説明するための単純化されたコードです。
これは.NET 4にあり、WebApiを使用して、デバッグコードでhttpリクエストの本文を出力しようとしています。これを行うには、入力ストリームをシークしてストリームを読み取ります。最初は問題なく動作しますが、もう一度読み込もうとすると、空の文字列が表示されます。
InputStreamを再度シークして読み取ることができないのはなぜですか?以下の例では、body2は常に空です。 2番目のセットでは、CanSeekはまだtrueであり、ReadToEnd()への2番目の呼び出しは、デフォルトを上書きする空の文字列を返します。
using System.IO;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
public class TestController : ApiController
{
public class TestOutuput
{
public string firstRead;
public string secondRead;
}
public HttpResponseMessage Post()
{
string body1 = "default for one";
string body2 = "default for two";
if (HttpContext.Current.Request.InputStream.CanSeek)
{
HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
using (var reader = new StreamReader(HttpContext.Current.Request.InputStream))
{
body1 = reader.ReadToEnd();
}
if (HttpContext.Current.Request.InputStream.CanSeek)
{
HttpContext.Current.Request.InputStream.Seek(0, System.IO.SeekOrigin.Begin);
}
using (var reader2 = new StreamReader(HttpContext.Current.Request.InputStream))
{
// this is always empty, even after seek back to Origin
body2 = reader2.ReadToEnd();
}
TestOutuput testOutput = new TestOutuput() { firstRead = body1, secondRead = body2 };
HttpResponseMessage response = new HttpResponseMessage();
return Request.CreateResponse<TestOutuput>(HttpStatusCode.OK, testOutput);
}
}
StreamReader
は、破棄されるときに、指定されたストリームでDispose
を呼び出します。ストリームを開いたままにするには、StreamReader
に 適切なコンストラクタ を使用します。あるいは、バッファにコピーするだけです。 MSDNから:
ストリームから読み取る場合は、ストリームの内部バッファーと同じサイズのバッファーを使用する方が効率的です。
たとえば この質問 を参照してください。
HttpContext.Current.Request.InputStream.Position=0;
位置を読み取ると、最後の値に移動し、そこから2回目の読み取りを試みます。読む前に、位置をゼロに設定してください。
それが役に立てば幸い。