WCF REST Starter Kit Preview の Sample である PushStyleStreaming ではURLパラメタによって、コンテンツタイプがimage/jpegやtext/plain のストリームを返す方法を掲載しています。これは、Preview版に含まれる AdapterStream を使用することによって、本来Streamを扱えない.NET のクラスをWCF のストリーミングプログラミングモデルに適合させることによって、実現されています。今回はこの機能を調べて見ます。
- 動作環境:IIS6.0 on Windows Server 2003
- 実装確認: Visaul Studio 2008 Professional
- .NET 3.5 SP1, WCF REST Starter Kit Preview版
1. AdapterStream
AdapterStream を使用することで、本来 Stream を返さない .NET のクラスを WCF の ストリームモデルに適合するように扱うことができるようにできます。AdapterStream を使用したサンプルは WCF REST Starter Kit Preview 版の PushStyleStreaming に含まれています。
ImageGenerationService.svc.cs のServiceクラスのソースプログラムのBitmapを返すオペレーションは次のように定義されています。
[WebHelp(Comment = "Returns a dynamically generated image based on input text")] [WebGet(UriTemplate = "image?text={text}")] [OperationContract] Stream GetImage(string text) { if (string.IsNullOrEmpty(text)) { throw new WebProtocolException(HttpStatusCode.BadRequest, "text must be specified", null); } Bitmap theBitmap = GenerateImage(text); WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; return new AdapterStream((stream) => theBitmap.Save(stream, ImageFormat.Jpeg)); }
たったのこれだけで、画像をレスポンスとして出力できるようになりました。すばらしいです。重要なのは、 ContentType を image/jpeg にしていることとAdapterStreamのコンストラクタで設定されている、Action<Stream>のラムダ式です。ラムダ式で、 stream に画像を保存するようにすることで、 Stream の出力を実現しています。補足ですが、GenerateImageは引数の文字列を画像として含むようにプログラム上でBitmapを作成するメソッドでソースファイル上に定義されています。
サンプルにはもうひとつ、コンテンツタイプ text/plain を返すオペレーションメソッドが定義されています。
[WebHelp(Comment = "Generates response text dynamically based on input")] [WebGet(UriTemplate = "text?text={text}")] [OperationContract] Stream GetText(string text) { if (string.IsNullOrEmpty(text)) { throw new WebProtocolException(HttpStatusCode.BadRequest, "text must be specified", null); } WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain"; return new AdapterStream((writer) => { writer.WriteLine("You said: "); writer.WriteLine(text); writer.WriteLine("Didn't you?"); writer.Flush(); }, Encoding.UTF8); }
AdapterStreamの引数に今度は、文字列を出力するラムダ式が設定されていることが確認できます。動作させると、コンテンツタイプがtext/plainのテキストがブラウザに表示されます。
2. おまけ
こりずに、Sample である、PushStyleStreaming の readme.txt の内容を翻訳してみます。
本サンプルでは、ビットマップやデータベースのAPIなど、ストリームを返さない.NET の API を WCFのストリーミングプログラミングモデルで使用する方法を説明しています。
本サンプルを動かすには
=================
本プロジェクトを実行します。ブラウザのアドレスに<host,port>/ImageGenerationService.svc/image?text=hello と入力します。ビットマップファイルが返されます。
サンプルのImageGenerationService.svc.csのソースを確認すると分かりますが。 /ImageGenerationService.svc/text?text=hello とアドレスに入力すると、コンテンツタイプがtext/plainのテキストがブラウザに表示されます。
さんのコメント: さんのコメント: