方法: WCF REST プログラミング モデルを使用して任意のデータを受け入れるサービスを作成するHow to: Create a Service That Accepts Arbitrary Data using the WCF REST Programming Model

開発者は、データがサービス操作から返される流れを完全に制御する必要が生じることがあります。Sometimes developers must have full control of how data is returned from a service operation. これは、サービス操作をする必要があります形式でデータがサポートされていません byWCF を返す場合に、ケースです。This is the case when a service operation must return data in a format not supported byWCF. このトピックでは、WCF REST プログラミング モデルを使用して、任意のデータを受信するサービスを作成するについて説明します。This topic discusses using the WCF REST Programming Model to create a service that receives arbitrary data.

サービス コントラクトを実装するにはTo implement the service contract

  1. サービス コントラクトを定義します。Define the service contract. 任意のデータを受信する操作には、Stream 型のパラメーターが必要です。The operation that receives the arbitrary data must have a parameter of type Stream. さらに、このパラメーターは要求の本文に渡される唯一のパラメーターでなければなりません。In addition, this parameter must be the only parameter passed in the body of the request. この例で説明されている操作では、filename パラメーターも使用できます。The operation described in this example also takes a filename parameter. このパラメーターは要求の URL に格納されて渡されます。This parameter is passed within the URL of the request. UriTemplateWebInvokeAttribute を指定すると、パラメーターが URL に格納されて渡されるように指定できます。You can specify that a parameter is passed within the URL by specifying a UriTemplate in the WebInvokeAttribute. この場合は、URI は、呼び出しに使用では、このメソッドは、「UploadFile/一部のファイル名」で終了します。In this case the URI used to call this method ends in "UploadFile/Some-Filename". URI テンプレートの"{filename}"部分は、操作の呼び出しに使用される URI 内で操作の filename パラメーターが渡されることを指定します。The "{filename}" portion of the URI template specifies that the filename parameter for the operation is passed within the URI used to call the operation.

     [ServiceContract]  
    public interface IReceiveData  
    {  
        [WebInvoke(UriTemplate = "UploadFile/{fileName}")]  
        void UploadFile(string fileName, Stream fileContents);  
    }  
    
  2. サービス コントラクトを実装します。Implement the service contract. コントラクトには、ストリーム内の任意のデータのファイルを受け取る UploadFile というメソッドが 1 つだけあります。The contract has only one method, UploadFile that receives a file of arbitrary data in a stream. 操作では、ストリームを読み取り、読み取ったバイト数をカウントしてから、ファイル名と読み取ったバイト数を表示します。The operation reads the stream counting the number of bytes read and then displays the filename and the number of bytes read.

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

サービスをホストするにはTo host the service

  1. コンソール アプリケーションを作成し、サービスをホストします。Create a console application to host the service.

    class Program  
    {  
       static void Main(string[] args)  
       {  
       }  
    }  
    
  2. 変数を作成し、Main メソッド内のサービスに使用するベース アドレスを保持します。Create a variable to hold the base address for the service within the Main method.

    string baseAddress = "http://" + Environment.MachineName + ":8000/Service";  
    
  3. サービスの ServiceHost インスタンスを作成して、サービス クラスとベース アドレスを指定します。Create a ServiceHost instance for the service that specifies the service class and the base address.

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

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

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

プログラムによってサービスを呼び出すにはTo call the service programmatically

  1. サービスの呼び出しに使用する URI で HttpWebRequest を作成します。Create a HttpWebRequest with the URI used to call the service. このコードでは、ベース アドレスは "/UploadFile/Text" と組み合わされています。In this code, the base address is combined with "/UploadFile/Text". URI の "UploadFile" 部分で呼び出す操作を指定します。The "UploadFile" portion of the URI specifies the operation to call. URI の "Test.txt" 部分で UploadFile 操作に渡す filename パラメーターを指定します。The "Test.txt" portion of the URI specifies the filename parameter to pass to the UploadFile operation. これらの項目はいずれも操作コントラクトに適用された UriTemplate にマップされます。Both of these items map to the UriTemplate applied to the operation contract.

    HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");  
    
  2. MethodHttpWebRequest プロパティを POSTContentType プロパティを "text/plain" にそれぞれ設定します。Set the Method property of the HttpWebRequest to POST and the ContentType property to "text/plain". この設定により、サービスはコードがデータを送信し、そのデータがプレーン テキストであることを認識します。This tells the service that the code is sending data and that data is in plain text.

    req.Method = "POST";  
    req.ContentType = "text/plain";  
    
  3. GetRequestStream を呼び出すと、要求ストリームの取得や送信するデータの作成ができます。また、そのデータの要求ストリームに書き込んだり、ストリームを閉じることもできます。Call GetRequestStream to get the request stream, create the data to send, write that data to the request stream, and close the stream.

    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 を呼び出してサービスから応答を取得すると、応答データをコンソールに表示できます。Get the response from the service by calling GetResponse and display the response data to the console.

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

    host.Close();  
    

Example

この例で使用されているコードの完全な一覧を次に示します。The following is a complete listing of the code for this example.

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

コードのコンパイルCompiling the Code

  • コードのコンパイル時には、System.ServiceModel.dll と System.ServiceModel.Web.dll を参照します。When compiling the code reference System.ServiceModel.dll and System.ServiceModel.Web.dll

関連項目See also