いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

WCF入門-019 (基本的なサンプル, webHttpBinding, RSS, Atom 1.0, WebGet, SyndicationFeed, フィード配信)


webHttpBindingの基本についてのメモ。
CodeProjectにWCF RESTサービスについての素晴らしい記事があったので
それを参考にしたメモです。


WCFでは、.NET Framework 3.5よりRSSATOMフィードを配信する機能が追加されました。
フィードを配信する際に利用するクラスは以下のものです。

System.ServiceModel.Syndication.SyndicationFeed

System.ServiceModel.Syndication.SyndicationItem


使い方としては、最初に配信内容としてSyndicationItemのリストを
構築し、それをSyndicationFeedにセットします。
セットした後は、SyndicationFeedのSaveAsAtom10メソッド、または、SaveAsRss20メソッド
を呼び出すと内容が出力されます。


WCFで利用する場合は、SyndicationFeedを作成した後に
Atom 1.0/RSS 2.0に対応したフォーマッターを作成します。
以下のクラスです。

System.ServiceModel.Syndication.SyndicationFeedFormatter

しかし、SyndicationFeedFormatterクラスは抽象クラスとなっていますので
派生クラスである以下のどちらかを使います。

System.ServiceModel.Syndication.Atom10FeedFormatter

System.ServiceModel.Syndication.Rss20FeedFormatter


尚、SyndicationFeedクラスにはLoadという静的メソッドが
存在しており、このメソッドにURLを指定するとそのサイトの
RSSを取得してインスタンスを構築することも出来ます。


以下、サンプルです。
サンプルでは、URLにatom10パラメータとsiteパラメータを
テンプレートとして指定しています。どちらも型はbooleanです。


atom10にtrueを指定すると、出力されるフィードがATOM 1.0になります。
siteにtrueを指定すると、MSDNの最新ニュースのフィードを取得してそれを
出力します。

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

namespace Gsf.Samples.WCF
{
  [ServiceContract(Namespace="http://Gsf.Samples.WCF")]
  [ServiceKnownType(typeof(Atom10FeedFormatter))]
  [ServiceKnownType(typeof(Rss20FeedFormatter))]
  public interface IMyService
  {
    [OperationContract]
    [WebGet(UriTemplate="rss?atom10={atom10}&site={site}", BodyStyle=WebMessageBodyStyle.Bare)]
    SyndicationFeedFormatter GetFeed(bool atom10, bool site);
  }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Xml;

namespace Gsf.Samples.WCF
{
  public class MyService : IMyService
  {
    public SyndicationFeedFormatter GetFeed(bool atom10, bool site)
    {
      if (site)
      {
        return GetSiteFeed(atom10);
      }
      else
      {
        return CreateDummyFeed(atom10);
      }
    }

    private SyndicationFeedFormatter GetSiteFeed(bool atom10)
    {
      // MSDN最新情報のRSS
      const string url = @"http://www.microsoft.com/japan/msdn/rss.xml";

      SyndicationFeed feed = null;
      using (XmlReader reader = XmlReader.Create(url))
      {
        feed = SyndicationFeed.Load(reader);
        reader.Close();
      }

      return GetFormatter(atom10, feed);
    }

    private SyndicationFeedFormatter CreateDummyFeed(bool atom10)
    {
      List<SyndicationItem> items = new List<SyndicationItem>();

      for (int i = 0; i < 500; i++)
      {
        SyndicationItem newItem = new SyndicationItem();

        newItem.Title = new TextSyndicationContent(string.Format("Item Title-{0}", i));
        newItem.Content = new TextSyndicationContent(string.Format("Item Content-{0}", i));
        newItem.Links.Add(new SyndicationLink(new Uri(@"http://d.hatena.ne.jp/gsf_zero1")));

        items.Add(newItem);
      }

      SyndicationFeed feed = new SyndicationFeed();

      feed.Title = new TextSyndicationContent("Test Feed.");
      feed.Description = new TextSyndicationContent("This is a test feed.");
      feed.Authors.Add(new SyndicationPerson("xxxx@gmail.com", "gsf_zero1", @"http://www.google.co.jp"));
      feed.Categories.Add(new SyndicationCategory(@"C#"));
      feed.Items = items;
      feed.LastUpdatedTime = DateTime.Now;

      return GetFormatter(atom10, feed);
    }

    private SyndicationFeedFormatter GetFormatter(bool atom10, SyndicationFeed feed)
    {
      SyndicationFeedFormatter formatter = null;
      if (atom10)
      {
        formatter = new Atom10FeedFormatter(feed);
      }
      else
      {
        formatter = new Rss20FeedFormatter(feed);
      }

      return formatter;
    }
  }
}


最後にアプリケーション構成ファイル。
webHttpBindingを利用する場合、EndpointBehaviorが必須となりますので注意が必要です。

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="Gsf.Samples.WCF.MyService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8093/MyService"/>
          </baseAddresses>
        </host>
        <endpoint name="epWebHttp"
                  address=""
                  binding="webHttpBinding"
                  contract="Gsf.Samples.WCF.IMyService"
                  behaviorConfiguration="webHttpEndpointBehavior" />
        <endpoint name="epMex"
                  address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpEndpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>


起動させた後、以下のURLにアクセスします。

ttp://localhost:8093/MyService/rss?atom10=true

すると、ブラウザ上に以下のデータが表示されます。
IEで見ると以下のような感じです。


次に、以下のURLにアクセスします。

ttp://localhost:8093/MyService/rss?atom10=true&site=true

すると、ブラウザ上にMSDNのフィードデータが表示されます。



サンプルは以下の場所にアップしてあります。
https://sites.google.com/site/gsfzero1/Home/WCFSample-018.zip?attredirects=0&d=1



================================
過去の記事については、以下のページからご参照下さい。