方法: WCF REST プログラミング モデルを使用して任意のデータを受け入れるサービスを作成する

開発者は、データがサービス操作から返される流れを完全に制御する必要が生じることがあります。 たとえば、WCF ではサポートされない形式のデータを、サービス操作から返す必要がある場合です。 このトピックでは、WCF REST プログラミング モデルを使用して任意のデータを受信するサービスの作成方法について説明します。

サービス コントラクトを実装するには

  1. サービス コントラクトを定義します。 任意のデータを受信する操作には、Stream 型のパラメーターが必要です。 さらに、このパラメーターは要求の本文に渡される唯一のパラメーターでなければなりません。 この例で説明されている操作では、filename パラメーターも使用できます。 このパラメーターは要求の URL に格納されて渡されます。 UriTemplateWebInvokeAttribute を指定すると、パラメーターが URL に格納されて渡されるように指定できます。 この場合、このメソッドの呼び出しに使用する URI は "UploadFile/Some-Filename" で終わります。 URI テンプレートの "{filename}" 部分は、操作に使用する filename パラメーターが操作の呼び出しに使用する URI に格納されて渡されるように指定します。

     [ServiceContract]  
    public interface IReceiveData  
    {  
        [WebInvoke(UriTemplate = "UploadFile/{fileName}")]  
        void UploadFile(string fileName, Stream fileContents);  
    }  
    
  2. サービス コントラクトを実装します。 コントラクトには、ストリーム内の任意のデータのファイルを受け取る UploadFile というメソッドが 1 つだけあります。 操作では、ストリームを読み取り、読み取ったバイト数をカウントしてから、ファイル名と読み取ったバイト数を表示します。

    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);  
        }  
    }  
    

サービスをホストするには

  1. コンソール アプリケーションを作成し、サービスをホストします。

    class Program  
    {  
       static void Main(string[] args)  
       {  
       }  
    }  
    
  2. 変数を作成し、Main メソッド内のサービスに使用するベース アドレスを保持します。

    string baseAddress = "http://" + Environment.MachineName + ":8000/Service";  
    
  3. サービスの ServiceHost インスタンスを作成して、サービス クラスとベース アドレスを指定します。

    ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));  
    
  4. コントラクト、WebHttpBinding、および WebHttpBehavior を指定するエンドポイントを追加します。

    host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());  
    
  5. サービス ホストを開きます。 サービスは要求を受け取る準備ができました。

    host.Open();  
    Console.WriteLine("Host opened");  
    

プログラムによってサービスを呼び出すには

  1. サービスの呼び出しに使用する URI で HttpWebRequest を作成します。 このコードでは、ベース アドレスは "/UploadFile/Text" と組み合わされています。 URI の "UploadFile" 部分で呼び出す操作を指定します。 URI の "Test.txt" 部分で UploadFile 操作に渡す filename パラメーターを指定します。 これらの項目はいずれも操作コントラクトに適用された UriTemplate にマップされます。

    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");  
    
  2. MethodHttpWebRequest プロパティを POSTContentType プロパティを "text/plain" にそれぞれ設定します。 この設定により、サービスはコードがデータを送信し、そのデータがプレーン テキストであることを認識します。

    req.Method = "POST";  
    req.ContentType = "text/plain";  
    
  3. 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();  
    
  4. GetResponse を呼び出してサービスから応答を取得すると、応答データをコンソールに表示できます。

    HttpWebResponse resp = (HttpWebResponse)req.GetResponse();  
    Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode, resp.StatusDescription);  
    
  5. サービス ホストを閉じます。

    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 を参照します。

関連項目