2012-02-06 7 views
0

私はXML-RPC.NET(http://www.xml-rpc.net/)と、特定のネットワークポートでXML-RPC通信をリッスンしてそれに応答するHttpListenerメソッドを使用しています。Streamオブジェクトを消費せずに読む

で来るリクエストのボディがHttpListenerContextInstance.Request.InputStream Streamオブジェクトを介してアクセスできます:

HttpListener hlListener = new HttpListener(); 
HttpListenerContext hlcContext = hlListener.GetContext(); 
// hlcContext.Request.InputStream contains what I want 

ストリームがhlcContext.Request.InputStreamからアクセスすることができますが、このストリームは、私はそれを表示する/それを読むことができませんシークではありませんそれからXML-RPC.NETライブラリが必要に応じてそれを使用できるように、その先頭に戻ります。一度読んだら、それは消費され、再読めません。

このような状況を処理する方法の1つは、ストリームをMemoryStreamに変換してシークをサポートしていることを理解していますが、XML-RPC.NETが続行するようにこれを行う方法はわかりませんストリームの代わりにMemoryStreamを使用します。

// hlcContext.Request.InputStream is currently filled 
MemoryStream msInput = new MemoryStream(); 
hlcContext.Request.InputStream.CopyTo(msInput); 
byte[] byteInput = msInput.ToArray(); 
// hlcContext.Request.InputStream is now empty and XML-RPC.NET can no longer use it :(

私は文字列でそれを格納し、ストリームが仕事を続けることができますように、私はストリームから読み取ることができますどのように:ただのMemoryStreamにストリームをコピーすると、その時点の過去、それは使用できなくなり、ストリームを消費しているようですそれ以降のXML-RPC.NET?

+0

方法を使用することができますあなたはXML-RPC.NETにストリームを提供していますか?私はあなたのサンプルコードではそれを見ません。 –

+0

ストリームは、ウェブサイトにアクセスするたびに(http:// localhost/DoSomething)XML-RPC.NETライブラリによって何らかの形で/どこかで作成されます。 – Coder6841

+0

私はコードを調べる時間がありませんでしたが、 'HttpListener'がXML RPC型であると仮定すると、それをサブクラス化して' GetContext() 'がどのように実装されて必要な振る舞いを注入するかを変更できるかもしれません。 –

答えて

1

あなたが合法的な方法を見つけることができない場合は、ここでRequest.InputStreamにストリームを設定するためのハックは、(最後の手段として)である

MemoryStream msInput = new MemoryStream(); 
hlcContext.Request.InputStream.CopyTo(msInput); 
byte[] byteInput = msInput.ToArray(); 
msInput.Seek(0, SeekOrigin.Begin); 

request.GetType().InvokeMember("m_RequestStream", BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic, null, request, new object[] { msInput }); 

今、あなたは自由にbyteInput

+0

このコードについて、ハック/最後の手段とは何ですか?それは不安定性をもたらしますか?アプリケーションが重要なビジネスアプリケーションであるため、予期しない問題が発生する可能性がある場合は、使用しないことをお勧めします。 – Coder6841

+0

@ Coder6841、私は不安定になるとは思わない。このコードを使用すると、 'request'オブジェクトのプライベート変数(' m_RequestStream')にアクセスできます。もしMSがあなたにそれをしたければ、それはそれを公開としてマークします。これは、次のリリースで変更される可能性があることを意味します。ネットフレームワーク(私は過去のバージョンで何の変更も見ていないが) –

+0

これは完璧に動作します、ありがとう! – Coder6841

0

シーク(CanSeek == true)をサポートするストリームで動作するはずです。

MemoryStream msInput = new MemoryStream(); 
var preCopyPosition = hlcContext.Request.InputStream.Position; 

hlcContext.Request.InputStream.CopyTo(msInput); 
byte[] byteInput = msInput.ToArray(); 

// Go back to pre-copy state 
hlcContext.Request.InputStream.Position = preCopyPosition; 
+0

残念ながら、ストリームはシークをサポートしていません。 "hlcContext.Request.InputStream.Position = preCopyPosition;"サポートされていない例外が発生します。 – Coder6841

+2

コピーを防ぐためにこれを残しておきます。 –

関連する問題