だるろぐ

明日できることは、今日しない。

RSS 2.0 を実装する

http://sample.com/Post/LastUpdated.rssRSS が吐かれるようにしてみたかった。

まずはルーティング。

#Global.asax.cs

routes.MapRoute(
    "Mode", // ルート名
    "{controller}/{action}.{mode}", // パラメーター付きの URL
        new { controller = "Home",
        action = "Index",
        id = UrlParameter.Optional,
        mode = "html" } // パラメーターの既定値
);

次はコントローラー。IPagedList は自分で作ったページング機能付きのリスト。"http://sample.com/Post/LastUpdated?mode=rss" でアクセスしてもいい。

レポジトリパターンにしたのにここで IPagedList 作ってるのはダサいので、あとで直そう…

#Post.cs

//
// GET: /Post/LastUpdated

public ViewResult LastUpdated(int current = 1, int items_per_page = 10, string mode = "html")
{
    var posts = new PagedList<Post>(
        repository.GetList().OrderByDescending(p => p.UpdatedAt),
        current, items_per_page);

    switch (mode)
    {
        case "rss":
            return View("LastUpdated.rss", posts);
        default:
            return View(posts);
    }
}

最後にビュー。"LastUpdated.rss.cshtml"ってのを追加する。XML宣言をファイルの先頭にしたほうがいいのかな。あと、Response.ContentType に "application/rss+xml" を設定して、「今から返すんはRSSやで!」と教えておく。

<?xml version="1.0" encoding="utf-8"?>

@model IEnumerable<Daruwiki.Models.Post>

@{
    Layout = string.Empty;
    Response.ContentType = "application/rss+xml";

    var Title = App.Name;
    var SiteUrl = "http://" + Request.Url.Authority;
    var RssUrl = Request.Url;
    var Description = "";
    var LastUpdated = GetUnixTime(Model
        .OrderByDescending(p => p.CreatedAt).First().CreatedAt);
}

@functions
{
    private static DateTime UNIX_EPOCH =  new DateTime(1970, 1, 1, 0, 0, 0, 0);
    
    public static long GetUnixTime(DateTime targetTime)
    {
        targetTime = targetTime.ToUniversalTime();
        TimeSpan elapsedTime = targetTime - UNIX_EPOCH;
        return (long)elapsedTime.TotalSeconds;
    }
}

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>@Title</title>
  <link>@SiteUrl</link>
  <atom:link href="@RssUrl" rel="self" type="application/rss+xml" />
  <description>@Description</description>
  <language>ja</language>
  <lastBuildDate>@LastUpdated</lastBuildDate>
@foreach (var item in Model)
{
  <item>
    <title>@item.Title</title>
    <link>@SiteUrl/@item.Title</link>
    <guid>@item.PostId</guid>
    <pubDate>@item.CreatedAt</pubDate>
    <description><![CDATA[@Html.Raw(item.FormattedBody)]]></description>
  </item>
}
</channel>
</rss>

でけた。でも、その直後に RssResult っていうのがあるっぽいことを知った

Twitter

@daruyanagi WCF とか使えば出力できそうな気が

Twitter

勉強が足りない。