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のテキストがブラウザに表示されます。