読者です 読者をやめる 読者になる 読者になる

きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

WCFとの連携を試してみた

業務アプリ分野にSilverlightを利用するとしたら、バックエンドのデータのやり取りの本命はやはりWCFなんだろうな、ということで、ちょっと試してみました。

1.Silverlightプロジェクトの新規作成

まず、VS2008からSilverlightのプロジェクトを新規に作成します(言語は、何となくVBを選んでみました。深い意味はありません)。
SilverlightをホストするWebプロジェクトをどうするかの選択肢では、
[コントロールをホストするためのWebをソリューションに追加する]
を選択しました。これは、ここで追加したWebにWCFのサービスを追加するためです*1。また、今回はWebアプリケーションを選びました。これも深い意味はありません。

2.WCFのサービスを追加

プロジェクトのテンプレートが出来上がったら、先にWCFのサービスを作ってしまいます。
追加したWebサイトのプロジェクトに、WCFサービスを追加します。[あたらしい項目の追加]から[WCFサービス]を追加します。今回は面倒なので、名前とかかえていませんので、Webのプロジェクト内に『IService1.vb』と『Service1.svc』が追加され、Web.Configにも幾ばくかの追記がされます。

3.WCFのサービスのメソッドを作成

作成されたテンプレートには、DoWorkという名前のメソッドがサンプルとして書かれていますが、こいつは値を返さないから面白くないので、値を返すメソッドを追加してやります。ただし、StringとかInt32とか返しても面白くないので、なんかクラスを返してやろうと思うので、まずはクラスを作ります。


※注意※
私は、WCFはホントに何も知らないので、今回ここに記述する内容はMSDN Libraryのサンプルなどから適当に切りはりしたレベルです。何とか動いてはいますが、WCF的に正しいものでは無い可能性があります。というか、たぶん「とりあえず動いてるけど出鱈目」っぽい自信があります。くれぐれも鵜呑みにだけはしないでください。あと、詳しい方、突っ込み等があれば頂けるとありがたいです。

[1]メソッドの戻り値として渡すクラスを作成

適当にクラスを作ります。面倒なので、とりあえずService1.svcの中に書いちゃいました*2

<Serializable()> _
Public Class HogeData
    Private _HogeName As String
    Public Property HogeName() As String
        Get
            Return Me._HogeName
        End Get
        Set(ByVal value As String)
            Me._HogeName = value
        End Set
    End Property

    Private _HogeID As Int32
    Public Property HogeID() As Int32
        Get
            Return Me._HogeID
        End Get
        Set(ByVal value As Int32)
            Me._HogeID = value
        End Set
    End Property
End Class
[2]さっきのクラスを返すメソッドをServiceContractのInterface に定義

IService1.vbに、先ほどのHogeDataクラスを返すGetHogeDataメソッドの定義を書いておきます。

<ServiceContract()> _
Public Interface IService1

    <OperationContract()> _
    Sub DoWork()

    '' ↓を追加
    <OperationContract()> _
    Function GetHogeData() As HogeData

End Interface
[3]Service1クラスにGetHogeDataメソッドの実装をかく

Service1.svcのService1に、先ほどのGetHogeDataメソッドの実相を書いてやります。

Public Class Service1
    Implements IService1

    Public Sub DoWork() Implements IService1.DoWork
    End Sub

    Public Function GetHogeData() As HogeData Implements IService1.GetHogeData
        Return New HogeData With {.HogeID = 10, .HogeName = "HogeHoge"}
    End Function
End Class

……どうでもいいけど、VS2008からのオブジェクト初期化子って楽でいいですね。

4.basicHttpBindingでできるように、Web.Configを書き換え

現在のSilverlight 2.0 Beta1ではbasicHttpBindingしか使えないらしいので、既定ではwsHttpBindingになっている所を書き換えます。とりあえずここは、正直WCFを全然知らない私にはよく解らなかったので、MSDNライブラリのサンプルからの適当な切りはりです。不要な記述や不適切な記述等あると思いますが、今日のところは勘弁してください。とりあえず、system.serviceModelディレクティブ以下を、以下のように書き換えました。

 <system.serviceModel>
  <behaviors>
   <serviceBehaviors>
    <behavior name="SilverlightApplication_Web.Service1Behavior">
     <serviceMetadata httpGetEnabled="true" />
     <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
   </serviceBehaviors>
  </behaviors>
  <services>
   <service behaviorConfiguration="SilverlightApplication_Web.Service1Behavior"
    name="SilverlightApplication_Web.Service1">
    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="SilverlightApplication_Web.IService1">
     <identity>
      <dns value="localhost" />
     </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
   </service>
  </services>
  <bindings>
   <basicHttpBinding>
     <binding name="Binding1"
       hostNameComparisonMode="StrongWildcard"
       receiveTimeout="00:10:00"
       sendTimeout="00:10:00"
       openTimeout="00:10:00"
       closeTimeout="00:10:00"
       maxReceivedMessageSize="65536"
       maxBufferSize="65536"
       maxBufferPoolSize="524288"
       transferMode="Buffered"
       messageEncoding="Text"
       textEncoding="utf-8"
       bypassProxyOnLocal="false"
       useDefaultWebProxy="true" >
         <security mode="None" />
     </binding>
    </basicHttpBinding>
  </bindings>
 </system.serviceModel>

とりあえず、これでビルドし、WebプロジェクトでService1.svcをスタートページにして実行、ブラウザにサービスの説明の画面が出れば成功です。

ここからが本番……ですが、ちょっとエントリが長くなったので、いったんここでののエントリを終わります。
もちろん、続きます。

*1:別にあとから付けてもいいし別のソリューションで作っても良い、とりあえずのお試しのつもりなので、楽な方で、というくらいの意味でやってます

*2:実験ということで、細かいことは気にしない。