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

第1回 WCFを使用してRSS/Atomフィーダを作成する

デジタルアドバンテージ 岸本 真二郎
2008/06/27
Page1 Page2 Page3 Page4

RSS/Atomフィーダのプログラミング

 とにかく実際に作って動かして自分で確かめるのが一番、ということでVisual Studio 2008(以下、VS 2008)で新規プロジェクトを作成し、RSS/Atomフィーダを作成してみることにしよう。実はVS 2008には、「配信サービス・ライブラリ」として、RSS/Atomフィーダ用のプロジェクトのひな型が用意されている。

■WCFのプロジェクト

 新規プロジェクトとしては[プロジェクトの種類]で「WCF」を選択し、[テンプレート]として「配信サービス ライブラリ」を選択する。ここではプログラミング言語としてC#を選択している(が、以下のコード例ではVisual Basic(VB)版も併せて示す)。


RSS/Atomフィーダを作成するプロジェクト

■プロジェクトに含まれる自動生成されたファイル

 新規にプロジェクトを作成すると(ここではプロジェクト名を「SyndicationServiceLibrary1」とした)、IFeed1.cs、Feed1.cs、App.configの3つのファイルが自動的に作成される。

  • IFeed.cs

 IFeed1.cs(リスト4)は、ファイル名からも分かるように、IFeed1インターフェイスを定義している。このコードでは、このインターフェイスがWCFで提供されるサービスであることを示すサービス・コントラクトの属性や、RSS 2.0(Rss20FeedFormatter)とAtom 1.0(Atom10FeedFormatter)のサービスを提供することなどが属性により宣言されている。これにより、IFeed1インターフェイスを実装したクラスは、WCFによりサービスとして公開されるようになる。

namespace SyndicationServiceLibrary1
{
  // メモ: ここでインターフェイス名 "IFeed1" を変更する場合は、App.config で "IFeed1" への参照も更新する必要があります。
  [ServiceContract]
  [ServiceKnownType(typeof(Atom10FeedFormatter))]
  [ServiceKnownType(typeof(Rss20FeedFormatter))]
  public interface IFeed1
  {

    [OperationContract]
    [WebGet(UriTemplate = "*", BodyStyle = WebMessageBodyStyle.Bare)]
    SyndicationFeedFormatter CreateFeed();

    // タスク: ここにサービス操作を追加します。
  }
}
' メモ: ここでインターフェイス名 "IFeed1" を変更する場合は、App.config で "IFeed1" への参照も更新する必要があります。
<ServiceContract()> _
<ServiceKnownType(GetType(Atom10FeedFormatter))> _
<ServiceKnownType(GetType(Rss20FeedFormatter))> _
Public Interface IFeed1

  <OperationContract()> _
  <WebGet(UriTemplate:="*", BodyStyle:=WebMessageBodyStyle.Bare)> _
  Function CreateFeed(ByVal arg As String) As SyndicationFeedFormatter

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

End Interface
リスト4 Visual Studio 2008が生成したインターフェイス(上:IFeed1.cs、下:IFeed1.vb)

 また、このIFeed1インターフェイスには、オペレーション・コントラクト属性(OperationContract)が付けられたCreateFeedメソッドが宣言されている。これによりCreateFeedメソッドがサービス・コントラクトに含まれる公開メソッドとして構成されるようになる。

 WCFでは通常、このようなインターフェイスを定義してサービスの定義を行う。WCFを利用してサービスを公開する場合は、どのようなサービスでもサービス・コントラクトやオペレーション・コントラクトが必要になる。

 CreateFeedメソッドに指定されているWebGet属性は、サービスが呼び出される際のテンプレートを指定している。自動生成されたコードではパラメータで「*」が設定されているが、これはワイルドカードを示している。

 (RSSフィーダの)URLからパラメータを取得する場合(例:「feed?type=rss」)は、ここでテンプレートを指定することでパラメータの内容を取得できるようになる。この場合は、「*」の代わりに、「feed?type={arg}」と記述する。{ }で囲まれた部分は変数を表し、この変数をメソッドの引数に対応付けることができる(この詳細はオンライン・ドキュメントを参照)。

 自動生成されたコードでは、IFeed1.csで、URLに含まれるパラメータを直接取得している。

  • Feed1.cs

 もう1つのソース・ファイルであるFeed1.csには、公開するサービス(ここではRSSの配信)の実体を記述する。ここで定義されているFeed1クラスは、前述したIFeed1インターフェイスを実装する。Feed1クラスにはIFeed1で宣言されたCreateFeedメソッドの定義だけが記述されている。このCreateFeedメソッドでRSS/Atomの配信に必要な内容を記述する。

■フィードの内容を作成する

 上述したように、RSSもAtomもサイトの概要を示すチャネル(Atomではfeed)と、更新されたページの情報を含む複数のアイテムにより構成されている。WCFで提供されるフィード用のクラスもこれに対応しており、チャネルに対応するクラスとしてSyndicationFeedクラスが、アイテムに対応するクラスとしてSyndicationItemクラスが用意されている。これらのインスタンスを作成してその内容を設定していけばフィードが出来上がるというわけだ。

 自動生成されたコードでは、SyndicationFeedクラスのコンストラクタで、フィードのタイトルと概要を設定している。3番目の引数にはnullがセットされているが、必要ならここにlink(RSS/Atomを配信しているサイトのURL)を指定する。

namespace CSSyndicationServiceLibrary1
{
  // メモ: ここでクラス名 "Feed1" を変更する場合は、App.config で "IFeed1" への参照も更新する必要があります。
  public class Feed1 : IFeed1
  {
    public SyndicationFeedFormatter CreateFeed()
    {
      // 新しい配信フィードを作成します。
      SyndicationFeed feed = new SyndicationFeed("Feed Title", "A WCF Syndication Feed", null);
      List<SyndicationItem> items = new List<SyndicationItem>();

      // 新しい配信アイテムを作成します。
      SyndicationItem item = new SyndicationItem("An item", "Item content", null);
      items.Add(item);
      feed.Items = items;

      // クエリ文字列に基づき ATOM または RSS を返します。
      // rss -> http://localhost:8731/Design_Time_Addresses/……
      // atom -> http://localhost:8731/Design_Time_Addresses/……
      string query = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];
      SyndicationFeedFormatter formatter = null;
      if (query == "atom") {
        formatter = new Atom10FeedFormatter(feed);
      } else {
        formatter = new Rss20FeedFormatter(feed);
      }

      return formatter;
    }
  }
}
' メモ: ここでクラス名 "Feed1" を変更する場合は、App.config で "IFeed1" への参照も更新する必要があります。
Public Class Feed1
    Implements IFeed1

  Public Function CreateFeed(ByVal arg As String) As SyndicationFeedFormatter Implements IFeed1.CreateFeed
    ' 新しい配信フィードを作成します。
    Dim feed As SyndicationFeed = New SyndicationFeed("Feed Title", "A WCF Syndication Feed", Nothing)
    Dim items As List(Of SyndicationItem) = New List(Of SyndicationItem)()

    ' 新しい配信アイテムを作成します。
    Dim item As SyndicationItem = New SyndicationItem("An item", "Item content", Nothing)
    items.Add(item)
    feed.Items = items

    ' クエリ文字列に基づき ATOM または RSS を返します。
    ' rss -> http://localhost:8731/Design_Time_Addresses/……
    ' atom -> http://localhost:8731/Design_Time_Addresses/……
    Dim query As String = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters.Get("format")
    Dim formatter As SyndicationFeedFormatter = Nothing
    If (query = "atom") Then
      formatter = New Atom10FeedFormatter(feed)
    Else
      formatter = New Rss20FeedFormatter(feed)
    End If

    Return formatter
  End Function

End Class
リスト5 Visual Studio 2008が生成したコード(上:Feed1.cs、下:Feed1.vb)

 アイテムの設定にはSyndicationItemクラスを使用する。SyndicationFeedクラスには、SyndicationItemオブジェクトのリストを設定するItemsプロパティが用意されている。

 自動生成されたコードでは1個のアイテムのみを追加しているが、実際にはこの部分で任意の数の更新情報をアイテムとして設定していく。この部分については、後ほどデータベースからアイテム情報を設定するように変更する。

■フィードを返す

 フィードの中身が出来上がったら、その内容をサービスの呼び出し元に返して、処理が終了する。ここまでの処理ではRSSとAtomの区別はないが、最後にAtom10FeedFormatterクラスとRss20FeedFormatterクラス(いずれもSystem.ServiceModel.Syndication名前空間)のどちらかを使って要求された形式のフィードを返すようにする。これらはSyndicationFeedFormatterクラスの派生クラスだ。

 自動生成されたコードでは、フィードの要求を行うURLに「format=atom」というパラメータを付加すると、Atom 1.0でフィードを配信し、パラメータが指定されていなければRSS 2.0でフィードを配信するようになっている。どちらか一方でのみ配信する場合は、このような処理は不要だ。それぞれの書式化を行うクラスに、先ほど作成したSyndicationFeedオブジェクトを指定してインスタンスを生成する。

 オペレーション・コントラクタとして定義したCreateFeedメソッドは、最後にこのSyndicationFeedFormatterクラスのインスタンスを戻り値として返して終了する。

■App.config

 設定ファイルであるApp.configには、WCFでRSS/Atomの配信を行うために必要な<system.serviceMode>要素が追加されている(リスト6)。

 自動生成されたコード中にもコメントで注意点が記述されているが、サービス・コントラクタを定義しているインターフェイス名を変更した場合は、App.configで記述されているサービス名(<service>要素)を併せて変更する必要がある。それ以外の部分は修正する必要はない。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="SyndicationServiceLibrary1.Feed1">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/SyndicationServiceLibrary1/" />
          </baseAddresses>
        </host>
        <endpoint contract="SyndicationServiceLibrary1.IFeed1" address="Feed1" binding="webHttpBinding" behaviorConfiguration="SyndicationServiceLibrary1.Feed1Behavior"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="SyndicationServiceLibrary1.Feed1Behavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>
リスト6 自動生成されたApp.configの内容(C#の場合)

■プロジェクト・テンプレートの実行

 ここまでVS 2008により自動生成されたコードについて説明したが、VS 2008が提供するRSS/Atom配信用のプロジェクトのテンプレートは、一切コードを修正しなくても機能する。デバッグ・モードでビルドしてプロジェクトを実行すると、WcfSvcHost(WCFサービスをホストするプログラム)が起動し、Internet Explorerからリクエストを実行してフィードを取得できる。


プロジェクトをデバッグ実行
コードを一切付け加えなくてもRSS/Atomの配信を確認できる。

 実際に配信された内容は次のようになっている。フィードを作成する処理を実装していないので、内容はVS 2008が自動生成したコードに記述されていたダミー・データだけになっている。

<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom">
 <channel>
  <title>Feed Title</title>
  <description>A WCF Syndication Feed</description>
  <item>
   <title>An item</title>
   <description>Item content</description>
  </item>
 </channel>
</rss>
実際に配信されたフィードの内容(RSS)

<feed xmlns="http://www.w3.org/2005/Atom">
 <title type="text">Feed Title</title>
 <subtitle type="text">A WCF Syndication Feed</subtitle>
 <id>uuid:bcd40d68-6e34-46c0-8794-1ffa326d5030;id=1</id>
 <updated>2008-06-09T13:17:56Z</updated>
 <entry>
  <id>uuid:bcd40d68-6e34-46c0-8794-1ffa326d5030;id=2</id>
  <title type="text">An item</title>
  <updated>2008-06-09T13:17:56Z</updated>
  <content type="text">Item content</content>
 </entry>
</feed>
実際に配信されたフィードの内容(Atom)

 結局、プログラマーの行わなくてはならない作業は、CreateFeedメソッドの中で行っているフィードの構築部分だけだ。なおサービス名を変更する場合は、リファクタリング機能を使うことで簡単に行えるが、上述したようにApp.configも修正することを忘れないように。


 INDEX
  実践! WCFプログラミング
  第1回 WCFを使用してRSS/Atomフィーダを作成する
    1.WCFとは?/RSS/Atomとは?
  2.RSS/Atomフィーダのプログラミング
    3.フィード本体の作成
    4.実際にどのように配信するか?/IISでフィードを配信する
 
インデックス・ページヘ  「実践! 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 記事ランキング

本日 月間