[ASP.NET MVC] さくっと RSS フィードを出力する

DevelopmentASP.NET, Visual Basic

Qiita ASP.NET Advent Calendar 2015 の18日目と Qiita プロ生ちゃん Advent Calendar 2015 15日目(穴埋め)の投稿です。

RSS フィードを作る

プロ生ちゃんこと暮井 慧らが活躍する Web コミック「すぱこー」。Web マンガ更新チェッカー【ピンガ】でも更新チェックできます(少し反映遅いかも?)。このピンガでの取り扱いがきっかけで、コミックのみの RSS フィードを作りました

すぱこー

すぱこーでも活躍するプロ生ちゃんが、「アキバで見かけた萌えキャラコンテスト」にエントリーされています。「暮井 慧(プロ生ちゃん)」への投票お願いします(12/18 20時まで)。プレゼントも当たります。

というわけで、さくっと RSS フィードなど XML 文書を返すサービスを ASP.NET MVC 5 での作り方を紹介します。

ASP.NET プロジェクト作成

開発環境は Visual Studio 2015 Update 1 です。新規に Visual Basic の ASP.NET プロジェクトを作ります。Web API を選択。「認証の変更」ボタンから認証なしを選びます。

ASP.NET

コントローラーの追加

ソリューションエクスプローラーの Controllers フォルダーのコンテキストメニューから[追加]-[コントローラー]を選びます。空のコントローラーを追加します。

ASP.NET

ASP.NET

Controller クラスの実装

Controller クラスができました。

Imports System.Net
Imports System.Web.Http
Namespace Controllers
Public Class SpacoController
Inherits ApiController
End Class
End Namespace

view raw
SpacoController.vb
hosted with ❤ by GitHub

Get メソッドでアクセスされたとき、XML ファイルを返すようにします。次のメソッドを SpacoController クラスへ追加します。

<HttpGet>
Public Function GetALl(Optional offset As Integer = 0,
Optional count As Integer = 100) As HttpResponseMessage
If offset < 0 Then
offset = 0
End If
If count < 0 OrElse count > 100 Then
count = 100
End If
Dim res = New HttpResponseMessage(HttpStatusCode.OK)
res.Content = New StringContent(CreateFeed(offset, count), Encoding.UTF8, "application/xml")
Return res
End Function

view raw
SpacoController.vb
hosted with ❤ by GitHub

今から作成する CreateFeed で XML の文字列を返します。Blog などの普通の(?)RSS フィードとは違って、アプリから Web コミックのデータ取得用にも使いたいので、位置と件数をクエリーで指定できるようにしています。

XML 文書の作成

CreateFeed を実装して、XML 文字列を作ります。フィード内の各項目となるクラスは次のように用意しました。すぱこーを公開するための最低限の内容です。

Public Class ComicItem
Property Title As String
Property Description As String
Property PubDate As DateTime
Property ModifiedDate As DateTime
Property Link As String
Property Id As String
Property Volume As Integer
Property IsAvailable As Boolean
Property MediaUrl As String
Property ThumbnailUrl As String
Property Creator As String
Property Guid As String
End Class

view raw
Model.vb
hosted with ❤ by GitHub

XML 文字列を作る CreateFeed メソッドの内容は次の通り。Web コミックのデータ取得部分は、ここでは扱いません。代わりにダミーを用意します。

Private Function CreateFeed(offset As Integer, count As Integer) As String
' ダミーデータ作成
Dim channelPubDate = Now
Dim items = New List(Of ComicItem)
For i = offset + 1 To count
Dim item = New ComicItem With {
.Title = "タイトル" & i.ToString,
.PubDate = Now.AddDays(count i),
.ModifiedDate = Now.AddDays(count i),
.Link = "http://pronama.jp/?" & i.ToString,
.Id = i.ToString,
.Volume = i,
.IsAvailable = True,
.MediaUrl = "http://pronama.jp/?media" & i.ToString,
.ThumbnailUrl = "http://pronama.jp/?thumbnail" & i.ToString,
.Creator = "Creator",
.Guid = "http://pronama.jp/?" & i.ToString}
items.Add(item)
Next
' XDocument 作成
Dim xml =
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcndl="http://ndl.go.jp/dcndl/terms/"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:p="http://pinga.mu/terms/"
>
<channel>
<title>すぱこー</title>
<link>http://pronama.azurewebsites.net/tag/spaco/</link>
<description>高校生の暮井 プロ生ちゃん部活情報処理研究会のメンバー 戸増千由莉とフィネスヒルヴィレッジが活躍する Web 4コマ漫画すぱこー」!</description>
<pubDate><%= channelPubDate.ToString("r") %></pubDate>
<image>http://pronama.azurewebsites.net/wp-content/uploads/2015/05/spaco_banner.png</image>
<dc:creator>池村ヒロイチ/プログラミング生放送</dc:creator>
<%= From i In items
Select <item>
<title><%= i.Title %></title>
<dc:creator><%= i.Creator %></dc:creator>
<link><%= i.Link %></link>
<pubDate><%= i.PubDate.ToString("r") %></pubDate>
<description><%= i.Description %></description>
<dcndl:volume><%= i.Volume %></dcndl:volume>
<dc:modified><%= i.ModifiedDate.ToString("s") %></dc:modified>
<p:isAvailable><%= If(i.IsAvailable, "true", "false") %></p:isAvailable>
<media:content url=<%= i.MediaUrl %>></media:content>
<media:thumbnail url=<%= i.ThumbnailUrl %>></media:thumbnail>
<guid isPermaLink="false"><%= i.Guid %></guid>
</item>
%>
</channel>
</rss>
' XML 文字列を返す
Return xml.ToString
End Function

view raw
SpacoController.vb
hosted with ❤ by GitHub

XML リテラル と、XML リテラルへの式とクエリーの埋め込み便利すぎでしょ……。上記のように直接コード内に XML を記述でき、変数やループ処理などを埋め込み XML 文書を作れます。RSS 以外の拡張した項目も好きなだけ追加できます。

XML 名前空間は、次のようにファイル冒頭で宣言しておきます。

Imports <xmlns:dc="http://purl.org/dc/elements/1.1/">
Imports <xmlns:dcndl="http://ndl.go.jp/dcndl/terms/">
Imports <xmlns:media="http://search.yahoo.com/mrss/">
Imports <xmlns:p="http://pinga.mu/terms/">

view raw
SpacoController.vb
hosted with ❤ by GitHub

完成

以上で、完成です。

必要に応じて、App_Start/WebApiConfig.vb でルーティングを変更します。規定では http://localhost:****/api/spaco のようにアクセスできます。

feed

http://localhost:****/api/spaco?offset=5&count=10 のようにパラメーターの指定もできます。

出力キャッシュを指定

Nuget で Strathweb.CacheOutput.WebApi2 をインストールすると、ASP.NET MVC の Web API で出力キャッシュが使えます。RSS フィードのように更新頻度が低いものは指定しておくと良いです。

次のように属性を指定します。

<HttpGet>
<CacheOutput(ClientTimeSpan:=100, ServerTimeSpan:=100)>
Public Function GetALl(Optional offset As Integer = 0, Optional count As Integer = 100) As HttpResponseMessage
' …
End Sub

view raw
SpacoController.vb
hosted with ❤ by GitHub

不要なコントローラーやファイルの削除

プロジェクトにはいろいろファイルがありますが、ほとんど未使用です。不要なコントローラーなどは削除しておきましょう。

余談

RSS フィードなど XML の出力は、もちろん今回の内容の方法だけではありません。RSS/Atom を表す SyndicationFeed クラスなども .NET Framework にはあります。