場合によっては、開発者はサービス操作からデータを返す方法を完全に制御する必要があります。 これは、サービス操作が、BYWCF でサポートされていない形式でデータを返す必要がある場合です。 このトピックでは、WCF REST プログラミング モデルを使用して、任意のデータを受信するサービスを作成する方法について説明します。
サービス コントラクトを実装するには
サービス コントラクトを定義します。 任意のデータを受け取る操作には、 Stream型のパラメーターが必要です。 さらに、このパラメーターは、要求の本文で渡される唯一のパラメーターである必要があります。 この例で説明する操作は、ファイル名パラメーターも受け取ります。 このパラメーターは、要求の URL 内で渡されます。 パラメーターを URL 内で渡すように指定するには、UriTemplateでWebInvokeAttributeを指定します。 この場合、このメソッドの呼び出しに使用される URI は "UploadFile/Some-Filename" で終わります。 URI テンプレートの "{filename}" 部分は、操作のファイル名パラメーターが、操作の呼び出しに使用される URI 内で渡されることを指定します。
[ServiceContract] public interface IReceiveData { [WebInvoke(UriTemplate = "UploadFile/{fileName}")] void UploadFile(string fileName, Stream fileContents); }サービス コントラクトを実装します。 コントラクトには、ストリーム内の任意のデータのファイルを受け取るメソッド
UploadFile1 つだけがあります。 この操作は、読み取られたバイト数をカウントするストリームを読み取り、ファイル名と読み取られたバイト数を表示します。public class RawDataService : IReceiveData { public void UploadFile(string fileName, Stream fileContents) { byte[] buffer = new byte[10000]; int bytesRead, totalBytesRead = 0; do { bytesRead = fileContents.Read(buffer, 0, buffer.Length); totalBytesRead += bytesRead; } while (bytesRead > 0); Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead); } }
サービスをホストするには
サービスをホストするコンソール アプリケーションを作成します。
class Program { static void Main(string[] args) { } }Mainメソッド内でサービスのベース アドレスを保持する変数を作成します。string baseAddress = "http://" + Environment.MachineName + ":8000/Service";サービス クラスとベース アドレスを指定するサービスの ServiceHost インスタンスを作成します。
ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));コントラクト、 WebHttpBinding、および WebHttpBehaviorを指定するエンドポイントを追加します。
host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());サービス ホストを開きます。 これで、サービスは要求を受信する準備ができました。
host.Open(); Console.WriteLine("Host opened");
プログラムでサービスを呼び出すには
サービスの呼び出しに使用する URI を使用して HttpWebRequest を作成します。 このコードでは、ベース アドレスが
"/UploadFile/Text"と組み合わされています。 URI の"UploadFile"部分は、呼び出す操作を指定します。 URI の"Test.txt"部分は、UploadFile操作に渡すファイル名パラメーターを指定します。 これらの項目はどちらも、操作コントラクトに適用される UriTemplate にマップされます。HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");MethodのHttpWebRequest プロパティを
POSTに設定し、ContentType プロパティを"text/plain"に設定します。 これにより、コードがデータを送信しており、データがプレーン テキストであることをサービスに通知します。req.Method = "POST"; req.ContentType = "text/plain";GetRequestStreamを呼び出して要求ストリームを取得し、送信するデータを作成し、そのデータを要求ストリームに書き込み、ストリームを閉じます。
Stream reqStream = req.GetRequestStream(); byte[] fileToSend = new byte[12345]; for (int i = 0; i < fileToSend.Length; i++) { fileToSend[i] = (byte)('a' + (i % 26)); } reqStream.Write(fileToSend, 0, fileToSend.Length); reqStream.Close();GetResponseを呼び出してサービスから応答を取得し、応答データをコンソールに表示します。
HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);サービス ホストを閉じます。
host.Close();
例
この例のコードの完全な一覧を次に示します。
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;
using System.Net;
namespace ReceiveRawData
{
[ServiceContract]
public interface IReceiveData
{
[WebInvoke(UriTemplate = "UploadFile/{fileName}")]
void UploadFile(string fileName, Stream fileContents);
}
public class RawDataService : IReceiveData
{
public void UploadFile(string fileName, Stream fileContents)
{
byte[] buffer = new byte[10000];
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileContents.Read(buffer, 0, buffer.Length);
totalBytesRead += bytesRead;
} while (bytesRead > 0);
Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead);
}
}
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");
req.Method = "POST";
req.ContentType = "text/plain";
Stream reqStream = req.GetRequestStream();
byte[] fileToSend = new byte[12345];
for (int i = 0; i < fileToSend.Length; i++)
{
fileToSend[i] = (byte)('a' + (i % 26));
}
reqStream.Write(fileToSend, 0, fileToSend.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);
host.Close();
}
}
}
コードのコンパイル
- コード参照の System.ServiceModel.dll と System.ServiceModel.Web.dll をコンパイルする場合