.NET 3.5 から追加されたWebHttpBindingとSystem.ServiceModel.Syndicationネームスペースのクラスを使って、RSS2.0とATOM1.0のフィードを作成するプログラムを作成します。WcfServiceHostを使用したサンプルはMSDNにあったので、IIS6でホストするように構成します。フィード作成用のWCFはWebアプリケーション内に作成するものとし、シンジケーションサービスライブラリテンプレートは使用しません。

動作確認環境

  • WCFホスト先IIS7 (Vista Enterprise), IIS6(Windows Server 2003 R2)
  • 開発環境 Visual Studio 2008 Professional
  • .NET 3.5

1. WCFサービスクラスの作成

既存もしくは新規に作成したWebアプリケーションプロジェクト(以降プロジェクト)のApp_Codeフォルダを右クリック(存在しない場合は作成)→新規項目の追加からクラスを作成します。作成したファイルを選択して、Build ActionがCompileになっていることを確認してください。Visual Studio 2008の場合はContentになってしまいます。

サービスクラスを次のように作成しました。(以下実装例)
流れは掲載されていますが、プログラムは不完全な形式になっています。SyndicationItem,SyndicationFeedを使い方はMSDNのAPIヘルプを参照して、各アプリケーションで適当な方法で作成して下さい。例ではIFeedServiceはサービスコントラクト,FeedServiceがサービスクラスとなっています。

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;

namespace Sample.Syndication
{
    [ServiceContract(Namespace = "")]
    interface IFeedService
    {
        [OperationContract]
        [ServiceKnownType(typeof(System.ServiceModel.Syndication.Atom10FeedFormatter))]
        [ServiceKnownType(typeof(System.ServiceModel.Syndication.Rss20FeedFormatter))]
        [WebGet(UriTemplate="Feed?format={format}")]
        SyndicationFeedFormatter GetArticlesFeed(string format);
    }

    public class FeedService : IFeedService
    {
        #region IFeedService Members

        public SyndicationFeedFormatter GetArticlesFeed(string format)
        {
            SyndicationFeed feed = new SyndicationFeed("タイトル", "デスクリプション", 
                            new Uri("http://tempuri.org/"));
            List<SyndicationItem> items = new List<SyndicationItem>();
            List<Article> articles = ... 適当なフィード情報元ソースを取得する処理;
            foreach (Article article in articles)
            {
                SyndicationItem item = new SyndicationItem(article.Title, article.Content, 
                                                            new Uri("http://tempuri.org/ArticleUri"), 
                                                            article.ID.ToString(), article.ReleaseDate);

                items.Add(item);
            }
            feed.Items = items;
            if (format == "rss")
            {
                return new Rss20FeedFormatter(feed);
            }
            else
            {
                return new Atom10FeedFormatter(feed);
            }
        }

        #endregion
    }
}

2.svcファイルを作成

Webアプリケーションのプロジェクトを右クリック新規作成でテキストファイルを選択し、FeedService.svcのファイル名でファイルを作成します。
ファイルは次のように記載します。

<%@ServiceHost Service="Sample.Syndication.FeedService" Language="C#"  %>

3.Web.configを編集

Webアプリケーションのconfigurationタグの内側に次の定義を追加します。

<system.serviceModel>
    <services>
      <service name="Sample.Syndication.FeedService">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration=""
          contract="Sample.Syndication.IFeedService" behaviorConfiguration="FeedServiceBehavior" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="FeedServiceBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

 endpointBehaviorsタグ内のwebHttpBehaviorは必要ですので忘れないで下さい。

4.動作確認

この状態でVisual Studioからデバッグ実行して"http://.../アプリケーションルート/FeedService.svc/feed?format=rss"とすればrssフィードが取得できるようになっています。format=atomとするとAtom1.0準拠のフィードが取得できます。以上で確認終了

5.IIS6で動作させるための設定(私の環境の場合)

VisataのIIS7ではなにもしなくてもWebアプリケーションとして配備するだけで動作しましたが、私の環境ではIIS6ではFeedService.svcは動作しても、FeedService.svc/feed?format=rssとしてURLをブラウザから参照するとファイルが見つかりませんとブラウザに表示されました。そのときに行った対応方法を記載します。以降の記載はWindows Server 2003のIIS6に対して行った設定です。

  1. スタートメニューから,[管理ツール]→[インターネットインフォメーションマネージャ]をクリックして起動します。
  2. Webアプリケーションの仮想フォルダを右クリック→プロパティを選択して、プロパティダイアログを表示する。
  3. 仮想ディレクトリタブの構成ボタンをクリック,アプリケーションの構成ダイアログを表示。
  4. アプリケーションの拡張子のグループボックスで追加ボタンをクリック
  5. アプリケーションの拡張子マッピングの追加/編集ダイアログで拡張子を.svc,
    実行ファイルを%SystemRoot%\Microsoft.net\framework\フレームワークのバージョン\aspnet_isapi.dllとしてOKボタンをクリック (下図参照)

 

 

 私の環境では拡張子がsvcの場合のマッピングがありませんでしたので、追加したら動作しました。IIS 7.0では上記が設定済みでした。