高度な Web プログラミングのサンプル

Download sample

このサンプルでは、Windows Communication Foundation (WCF) Web プログラミング モデルのさらに高度な機能の一部を示します。サンプルは次の概念を示します。

  • Uri Template Dispatch – 指定したパターンと一致する外部 URI にサービス操作をバインドできます。

  • HTTP Methods – GET、PUT、POST、DELETE などの任意の HTTP メソッドによってサービス操作を呼び出すことができます。

  • HTTP Headers – サービスは WebOperationContext を使用して HTTP ヘッダーのコンテンツを操作できます。

Noteメモ :

このサンプルをビルドして実行するには、.NET Framework Version 3.5 をインストールする必要があります。Visual Studio 2008 では、プロジェクトとソリューション ファイルを開く必要があります。

サンプルは、メモリに格納されている顧客データの基本的なコレクションを実装します。URI および HTTP メソッドを使用して外部に公開される、基本的な CreateReadUpdate、および Delete 操作をサポートします。

サービス コントラクトと実装

このサンプルでは、サービスはベース URI アドレス (https://localhost:8000/Customers) をリッスンする 1 つのエンドポイントを実装します。次のように、サービスはそのプレフィックスの下の URI の要求を処理します。

  • https://localhost:8000/Customers への GET 要求は GetCustomers() にルーティングされます。

  • システムの顧客ごとに一意の識別子があり、URI に格納されます。これらの URI (https://localhost:8000/Customers/1 など) の GET 要求は GetCustomer() にマッピングされます。

  • HTTP PUT 要求を顧客の URI に発行することにより、個々の顧客を更新できます。

  • HTTP DELETE を顧客の URI に発行することにより、顧客をシステムから削除できます。

  • HTTP POST をベース URI に発行することにより、新しいデータをシステムに追加できます。

[ServiceContract]
public interface ICustomerCollection
{
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "")]
    Customer AddCustomer(Customer customer);

    [OperationContract]
    [WebInvoke(Method = "DELETE", UriTemplate = "{id}")]
    void DeleteCustomer(string id);

    [OperationContract]
    [WebGet(UriTemplate = "{id}")]
    Customer GetCustomer(string id);

    [OperationContract]
    [WebGet(UriTemplate = "")]
    List<Customer> GetCustomers();

    [OperationContract]
    [WebInvoke(Method = "PUT", UriTemplate = "{id}")]
    Customer UpdateCustomer(string id, Customer newCustomer);
}

Service クラスによってサービス コントラクトが実装されます。これには WCF シングルトン インスタンス化を使用します。受信されるすべての要求はサーバーの同じオブジェクト インスタンスにルーティングされ、顧客のハッシュ テーブルを要求間で共有できるようになります。

[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single )]
public class Service : ICustomerCollection
{
   Hashtable customers = new Hashtable();
   ...
}        

HTTP GET 要求をサービスのベース URI (https://localhost:8000/Customers など) に発行することにより、GetCustomers() 操作を呼び出すことができます。Customer 型はData Contract Serializerによってシリアル化されます。

public List<Customer> GetCustomers()
{
    List<Customer> list = new List<Customer>();

    foreach (Customer c in this.customers.Values)
    {
        list.Add(c);
    }

    return list;
}

GET 要求を顧客の一意の URI に発行することにより、個々の顧客を取得できます。たとえば、ID 1 の顧客は、https://localhost:8000/Customers/1 で取得できます。同様に、顧客 2 には http:/localhost:8000/Customers/2 でアクセスできます。どちらの URI もサーバーの GetCustomer(string id) メソッドにディスパッチされます。このマッピングは、GetCustomer() 操作コントラクトに適用される [WebGet( UriTemplate="{id}")] 属性により作成されます。UriTemplate は、GetCustomer() 操作で処理される一連の URI を記述するパターンです。この場合、エンドポイントのベース アドレスの後にセグメントが 1 つだけあるすべての URI がパターンによって記述されます。そのセグメントのコンテンツは {id} テンプレート変数と一致し、WCF ディスパッチャによってメソッド パラメータ id に渡されます。

//[WebGet( UriTemplate=”{id}” )]
public Customer GetCustomer(string id)
{
Customer c = this.customers[id] as Customer;
      
      if (c == null)
      {
          WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound();
          return null;
}

return c;
}

GetCustomer() を実装すると、URI で提供される顧客の ID が参照され、関連付けられている顧客を返します。顧客が見つからない場合は、WebOperationContext メソッドを使用して HTTP 404 応答が返され、応答ステータス コードが設定されます。

また、UpdateCustomer() および DeleteCustomer() メソッドは、GetCustomer() メソッドと同じ URI テンプレートに関連付けられています。これらが別の HTTP メソッドにそれぞれ関連付けられている場合は、WCF Web プログラミング モデルにより、同じ URI テンプレートにバインドされる複数の操作が許可されます。この場合、UpdateCustomer() メソッドは HTTP PUT メソッドにバインドされ、DeleteCustomer() 操作は HTTP DELETE メソッドにバインドされます。

[OperationContract]
[WebInvoke( Method="PUT", UriTemplate="{id}")]
Customer UpdateCustomer(string id, Customer newCustomer);

[OperationContract]
[WebInvoke( Method="DELETE", UriTemplate="{id}" )]
void DeleteCustomer(string id);

AddCustomer() メソッドは、新しい UriTemplate クラスを使用して、特定のパターンに従う新しい URI を作成する方法を示します。WebOperationContext() メソッドを使用して、Location ヘッダー セットと共に、新しく作成された顧客の URI に HTTP CREATED 応答を返します。

public Customer AddCustomer(Customer customer)
{
lock (writeLock)
{
     counter++;
           UriTemplateMatch match = WebOperationContext.Current.IncomingRequest.UriTemplateMatch;

           UriTemplate template = new UriTemplate("{id}");
           customer.Uri = template.BindByPosition(match.BaseUri, counter.ToString());
                
           customers[counter.ToString()] = customer;
           WebOperationContext.Current.OutgoingResponse.SetStatusAsCreated(customer.Uri);
      }

      return customer;
}

サービス ホスティング

サービスは、WebServiceHost() を使用してホストされ、WebHttpBinding() を使用して 1 つのエンドポイントが公開されます。

using (WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("https://localhost:8000/")))
{
    host.AddServiceEndpoint(typeof(ICustomerCollection), new WebHttpBinding(), "Customers");
    host.Open();
    ...}

クライアント

クライアントが WebChannelFactory メソッドを使用して作成され、リモート サービスへのチャネルが作成されます。

using (WebChannelFactory<ICustomerCollection> cf = new WebChannelFactory<ICustomerCollection>())
{
      cf.Endpoint.Binding = new WebHttpBinding();
      cf.Endpoint.Address = new EndpointAddress( baseAddress );
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
ICustomerCollection channel = cf.CreateChannel();

...
}

チャネルを使用するクライアントはサーバーに一連の要求を発行します。これは顧客のコレクションの状態を操作するものです。

出力

POST を使用した一部の顧客の追加 :

Alice 123 Pike Place https://localhost:8000/Customers/1

Bob 2323 Lake Shore Drive https://localhost:8000/Customers/2

PUT を使用した顧客の更新 :

Charlie 123 Pike Place https://localhost:8000/Customers/1

GET を使用した顧客一覧の取得 :

Charlie 123 Pike Place https://localhost:8000/Customers/1

Bob 2323 Lake Shore Drive https://localhost:8000/Customers/2

DELETE を使用した顧客の削除 :

最終的な顧客の一覧

Charlie 123 Pike Place https://localhost:8000/Customers/1

対話が終了すると、プログラムはキーが押されるのを待って終了します。

サンプルを設定、ビルド、および実行するには

  1. Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」が実行済みであることを確認します。

  2. ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「Windows Communication Foundation サンプルのビルド」の手順を参照してください。

  3. 単一コンピュータ構成か複数コンピュータ構成かに応じて、「Windows Communication Foundation サンプルの実行」の手順に従います。

関連項目

その他の技術情報

基本的な Web プログラミング モデルのサンプル

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.