連載:実践! WCFプログラミング

第2回 WCFでASP.NET Webサービスを作成する

デジタルアドバンテージ 岸本 真二郎
2008/08/01
Page1 Page2

 前回は、WCF 3.5の新機能であるRSS/Atomフィードの作成方法を紹介した。今回は、これまでのVisual Studioで作成していたようなXML Webサービス(SOAP WebサービスもしくはASP.NET Webサービスとも呼ばれる。以下、単にWebサービス)を、WCFで作成する方法について紹介する。

新しいWebサービスのプログラミング・スタイル

 WCFの登場で、.NETの分散コンピューティング・テクノロジが統合され、従来はASP.NETベースで行っていたXML Webサービスの実装も、このWCFを用いて実現できるようになった。

 これまでのVisual Studioで提供されていたプロジェクト・テンプレート(ASP.NET Webサービス)に加えて、Visual Studio 2008のプロジェクト・テンプレートには、WCFを用いてWebサービスを作成するためのプロジェクトがいくつか用意されている。これらに含まれるプロジェクト・テンプレートを使ってサンプルのWebサービスを作成しながら、これまでのASP.NET Webサービスと同様の機能を作成してみる。

プロジェクトの新規作成

 WCFを使ったWebサービスを、「プロジェクト」として作成する場合は、

「WCF サービス アプリケーション」のテンプレート

を選択でき、「Webサイト」として作成するなら

「WCF サービス」のテンプレート

が選択できる。

 「WCF サービス ライブラリ」というテンプレートを用いてWebサービスを作成することも可能だが、今回は従来のASP.NET Webサービスの置き換えが目的なので、IISでWebサービスを提供することを前提に、構成ファイルや後述するサービス・ファイル(.svcファイル)などがプロジェクト生成時に自動的に生成される を選択する。


WCFサービス・アプリケーションの新規作成

 ただし、 のどちらを選択しても、出来上がるWebサービスは、機能的に同じと考えていいだろう。 でWebサイトを作成した場合、IISの仮想ディレクトリが作成される(実行もIIS上で行われる)のに対して、 でWebアプリケーションとして作成した場合は、(デフォルト設定では)デバッグ時に開発用のWebサーバが起動するようになる。

 生成されたプロジェクトには、すでにWebサービスを提供するためのひな型となるインターフェイスやクラスが作成されている。WCFの詳細については「Windows Communication Foundation概説」を参照されたい。ここでは、WCFによるASP.NET Web サービスと等価なサービスを提供するという点に絞って説明を行う。

Webサービス・プロジェクトの中身

 WCFによるサービスの基本となるのは、インターフェイスの定義(IService.cs/IService.vb)と、インターフェイスを継承したサービス・クラス(Service.svc.cs/Service.svc.vb)である。

 IService.cs/IService.vbに含まれるインターフェイス(IService)は、提供するサービスの骨格の部分を定義する。このインターフェイスには、ServiceContract属性が付けられているが、これは、このインターフェイスがWCFによるサービスを提供することを示す。

 さらにこのインターフェイスに含まれるメソッドには、OperationContract属性が付けられており、サービスに含まれるメソッドとして公開することを表す。

 また、メソッドで扱うパラメータとしてintやstringといった基本データ型ではなく、ユーザーの定義したデータ型(クラス)を受け渡す場合は、そのデータ型(クラス)にDataContract属性を付加する(テンプレートから自動生成されたコードではCompositeTypeクラスがそれに当たる)。クライアントからアクセスされるプロパティには、さらにDataMember属性を付加する。これらの設定によりインターフェイスに含まれる任意のメソッドをクライアントから実行でき、パラメータや戻り値から結果が得られるようになる。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// メモ: ここでインターフェイス名 "IService" を変更する場合は、Web.config で "IService" への参照も更新する必要があります。
[ServiceContract]
public interface IService1
{

  [OperationContract]
  string GetData(int value);

  [OperationContract]
  CompositeType GetDataUsingDataContract(CompositeType composite);

  // タスク: ここにサービス操作を追加します。
}

// サービス操作に複合型を追加するには、以下のサンプルに示すようにデータ・コントラクトを使用します。
[DataContract]
public class CompositeType
{
  bool boolValue = true;
  string stringValue = "Hello ";

  [DataMember]
  public bool BoolValue
  {
    get { return boolValue; }
    set { boolValue = value; }
  }

  [DataMember]
  public string StringValue
  {
    get { return stringValue; }
    set { stringValue = value; }
  }
}
<ServiceContract()> _
Public Interface IService1

  <OperationContract()> _
  Function GetData(ByVal value As Integer) As String

  <OperationContract()> _
  Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType

  ' タスク: ここにサービス操作を追加します。
End Interface

' サービス操作に複合型を追加するには、以下のサンプルに示すようにデータ コントラクトを使用します。
<DataContract()> _
Public Class CompositeType

  Private boolValueField As Boolean
  Private stringValueField As String

  <DataMember()> _
  Public Property BoolValue() As Boolean
  Get
    Return Me.boolValueField
  End Get
  Set(ByVal value As Boolean)
    Me.boolValueField = value
  End Set
  End Property

  <DataMember()> _
  Public Property StringValue() As String
  Get
    Return Me.stringValueField
  End Get
  Set(ByVal value As String)
    Me.stringValueField = value
  End Set
  End Property
End Class
リスト1 テンプレートで生成されたインターフェイス(上:C#、下:VB)

 プロジェクト・テンプレートから自動生成されたもう1つのソース・コードであるService.svc.cs(Service.svc.vb)はサービスの実体を実装するもので、上記のインターフェイスを実装したクラスになっている。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// メモ: ここでクラス名 "Service" を変更する場合は、Web.config および関連する .svc ファイルで "Service" への参照も更新する必要があります。
public class Service1 : IService1
{
  public string GetData(int value)
  {
    return string.Format("You entered: {0}", value);
  }

  public CompositeType GetDataUsingDataContract(CompositeType composite)
  {
    if (composite.BoolValue)
    {
      composite.StringValue += "Suffix";
    }
    return composite;
  }
}
' メモ: ここでクラス名 "Service1" を変更する場合は、Web.config および関連する .svc ファイルで "Service1" への参照も更新する必要があります。
Public Class Service1
  Implements IService1

  Public Sub New()
  End Sub

  Public Function GetData(ByVal value As Integer) As String Implements IRssItemService.GetData
    Return String.Format("You entered: {0}", value)
  End Function

  Public Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType Implements IRssItemService.GetDataUsingDataContract
    If composite.BoolValue Then
      composite.StringValue = (composite.StringValue & "Suffix")
    End If
    Return composite
  End Function
End Class
リスト2 サービスの実体が記述されたクラス(上:C#、下:VB)

 Service1クラスには、GetDataメソッドと、GetDataUsingDataContractメソッドが定義されている。実際にWebサービスを実装する場合は、これらのメソッドは削除し(もちろんインターフェイスからも削除する)、独自のメソッドを実装する。

そのほかのファイル

 IISによるWebサービスの提供に必要なファイルは、このほかにService.svcとWeb.configである。前者の.svcファイルについては、前回の「WCFを使用してRSS/Atomフィーダを作成する」でも触れているが、クライアントがサービスにアクセスする入り口となるものだ。

 従来のASP.NET Webサービスでは“.asmxファイル”を作成していたが、WCFでは“.svcファイル”となる。次のリスト3は.asmxファイルの内容だ。

<%@ WebService Language="C#" CodeBehind="~/App_Code/Service.cs" Class="Service" %>
リスト3 Service.asmxの内容(Visual Studio 2005で自動生成されたもの)

 これに対して、.svcファイルは次のような内容で生成される。

<%@ ServiceHost Language="C#" Debug="true" Service="wcfwebService.service1" CodeBehind="Service1.svc.cs" %>
<%@ ServiceHost Language="VB" Debug="true" Service="wcfwebService.service1" CodeBehind="Service1.svc.vb" %>
リスト4 Service.svcの内容(上:C#、下:VB)
「WebService」が「ServiceHost」になっており、サービス名が追加されている。

 WCFのWebサービスを利用するクライアントは、この.svcファイルに、

http://www.hoge.com/wcfservice/sercie.svc

といったURLでアクセスしてサービスを実行することになる。

Web.configの修正

 Web.configには、WCFサービスに関連する要素が追記されている。

 <system.serviceModel>要素がそれで、WCFの基本となるアドレス、バインディングおよびコントラクト情報が記述されている(これらの詳細については「Windows Communication Foundation概説」を参照)。

 ただし、バインディングにHTTPを用いるサービスの提供では、アドレスはURLで決まるので、Web.configにアドレス情報を記述しても意味はない(そのため<endpoint>要素のaddress属性は空となっている)。

 バインディングは、プロジェクトが生成された時点では「wsHttpBinding」となっているが、これはWS-*(Webサービス拡張仕様。セキュリティやルーティングなどについての標準化された拡張仕様)をサポートするバインディングである。従来のASP.NET Web サービスでは、Webサービス拡張をサポートしていないので、バインディングを「basicHttpBinding」に修正する必要がある。

<system.serviceModel>
  <services>
    <service name="WcfWebService.Service1"
             behaviorConfiguration="ServiceBehavior">
        <!-- Service Endpoints -->
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="WcfWebService.IService1">
          <!--
          展開時に、次の ID 要素を削除または置換して、展開された
          サービスが実行されている ID が反映されるようにする必要が
          あります。
          削除されると、WCF は適切な IDを自動的に推測します。
          -->

        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding"
                contract="IMetadataExchange"/>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="ServiceBehavior">
        <!-- メタデータ情報の開示を避けるには、展開する前に、
        下の値を false に設定し、上のメタデータのエンドポイントを
        削除します -->

        <serviceMetadata httpGetEnabled="true"/>
        <!-- デバッグ目的で障害発生時の例外の詳細を受け取るには、
        下の値を true に設定します。例外情報の開示を避けるには、
        展開する前に false に設定します -->

        <serviceDebug includeExceptionDetailInFaults="false"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>
リスト5 Web.configの内容(一部)
従来のASP.NET Webサービスのクライアントからアクセスできるようにするには、バインディングを「basicHttpBinding」に変更する。

 

 INDEX
  実践! WCFプログラミング
  第2回 WCFでASP.NET Webサービスを作成する
  1.プロジェクトの新規作成/Webサービス・プロジェクトの中身/Web.configの修正
    2.独自のサービスの記述/クライアントから確認してみる
 
インデックス・ページヘ  「実践! WCFプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間