しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET MVC 3 でも使えるフィード表示ヘルパーを作った

はてなモジュールに似てるなぁと思ったので、RSS や Atom フィードを表示するヘルパーを作りました。フィード系を表示したくなることって結構ありますよね。

今回は .NET 3.5 から追加された SyndicationFeed クラスを使ってお手軽に実装してみました。なので System.ServiceModel.Web を参照に加えてくださいね。

@helper ShowFeed(string url, string templateName, int count = 10)
{
    var cacheKey = string.Format("showfeed_{0}_{1}", url, count);

    var feed = (System.ServiceModel.Syndication.SyndicationFeed)Cache.Get(cacheKey);
    
    if (feed == null){
        var xml = System.Xml.XmlReader.Create(url);
        feed = System.ServiceModel.Syndication.SyndicationFeed.Load(xml);
        Cache.Insert(cacheKey, feed, null, DateTime.UtcNow.AddMinutes(1), System.Web.Caching.Cache.NoSlidingExpiration);
    }

    ViewBag.Count = count;
    
    Html.RenderPartial(templateName, feed);
}

XmlReader で指定されたフィードを読み込んで、それを SyndicationFeed.Load に渡してインスタンスを得てるだけです。ごちゃごちゃしているのは読み込んだフィードをキャッシュしているからですね。

盛大に手抜きをしたので、Html.RenderPartial には SyndicationFeed インスタンスを直接渡すことにしました。RenderPartial を使った理由は表示部分を別テンプレートにしたかったからです。では今回使う表示用のテンプレートです。

@model System.ServiceModel.Syndication.SyndicationFeed

<h3>@Model.Title.Text</h3>
<ul>
@foreach (var item in Model.Items.Take((int)ViewBag.Count))
{
    <li><a href="@item.Links[0].Uri.AbsoluteUri">@item.Title.Text</a></li>
}
</ul>

フィードのタイトルと項目のタイトルをリストで表示するようにしています。本来はビューモデルを作った方が良いんでしょうけど、今回は ViewBag.Count を使って手抜きしちゃいました。

使い方はフィードの URL と使用するテンプレート、そしてオプションで表示する項目数を渡すだけです。

@ShowFeed("http://www.atmarkit.co.jp/rss/rss.xml", "ShowFeed")

では準備がすべて完了したので実行してみましょう。表示するフィードは @IT を使ってみます。

フィードのタイトル、そして項目のタイトルとリンクが表示されていますね。ちゃんとキャッシュしているので 2 回目以降は素早く表示されます。

それでは次はテンプレートを入れ替えて TwitPic のフィードを表示させてみます。TwitPic のフィードにはサムネイルの URL が含まれているので、正規表現を使って取得することにします。

@model System.ServiceModel.Syndication.SyndicationFeed
           
<h3>@Model.Title.Text</h3>
<ul>
@foreach (var item in Model.Items.Take((int)ViewBag.Count))
{
    var url= System.Text.RegularExpressions.Regex.Replace(item.Summary.Text, "^.*src=\"(.+?)\".*$", "$1");
    <li style="display: inline;"><a href="@item.Links[0].Uri.AbsoluteUri"><img src="@url" /></a></li>
}
</ul>

画像だけを表示して、それ以外のテキストは表示しないようにしました。使い方はさっきと同じですが、テンプレート名を変更しましょう。

@ShowFeed("http://twitpic.com/photos/shibayan/feed.rss", "Twitpic", 8)

ではこれも実行させてみましょう。フィードは私の Twitpic を使いました。

画像が指定した件数だけちゃんと表示されていますね!テンプレートを準備するだけで簡単に表示をカスタマイズできます。

ヘルパー作るの楽しいですね。