[ASP.NET MVC] さくっと RSS フィードを出力する
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 を選択。「認証の変更」ボタンから認証なしを選びます。
コントローラーの追加
ソリューションエクスプローラーの Controllers フォルダーのコンテキストメニューから[追加]-[コントローラー]を選びます。空のコントローラーを追加します。
Controller クラスの実装
Controller クラスができました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Imports System.Net | |
Imports System.Web.Http | |
Namespace Controllers | |
Public Class SpacoController | |
Inherits ApiController | |
End Class | |
End Namespace |
Get メソッドでアクセスされたとき、XML ファイルを返すようにします。次のメソッドを SpacoController クラスへ追加します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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 |
今から作成する CreateFeed で XML の文字列を返します。Blog などの普通の(?)RSS フィードとは違って、アプリから Web コミックのデータ取得用にも使いたいので、位置と件数をクエリーで指定できるようにしています。
XML 文書の作成
CreateFeed を実装して、XML 文字列を作ります。フィード内の各項目となるクラスは次のように用意しました。すぱこーを公開するための最低限の内容です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
XML 文字列を作る CreateFeed メソッドの内容は次の通り。Web コミックのデータ取得部分は、ここでは扱いません。代わりにダミーを用意します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
XML リテラル と、XML リテラルへの式とクエリーの埋め込み便利すぎでしょ……。上記のように直接コード内に XML を記述でき、変数やループ処理などを埋め込み XML 文書を作れます。RSS 以外の拡張した項目も好きなだけ追加できます。
XML 名前空間は、次のようにファイル冒頭で宣言しておきます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/"> |
完成
以上で、完成です。
必要に応じて、App_Start/WebApiConfig.vb でルーティングを変更します。規定では http://localhost:****/api/spaco のようにアクセスできます。
http://localhost:****/api/spaco?offset=5&count=10 のようにパラメーターの指定もできます。
出力キャッシュを指定
Nuget で Strathweb.CacheOutput.WebApi2 をインストールすると、ASP.NET MVC の Web API で出力キャッシュが使えます。RSS フィードのように更新頻度が低いものは指定しておくと良いです。
次のように属性を指定します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<HttpGet> | |
<CacheOutput(ClientTimeSpan:=100, ServerTimeSpan:=100)> | |
Public Function GetALl(Optional offset As Integer = 0, Optional count As Integer = 100) As HttpResponseMessage | |
' … | |
End Sub |
不要なコントローラーやファイルの削除
プロジェクトにはいろいろファイルがありますが、ほとんど未使用です。不要なコントローラーなどは削除しておきましょう。
余談
RSS フィードなど XML の出力は、もちろん今回の内容の方法だけではありません。RSS/Atom を表す SyndicationFeed クラスなども .NET Framework にはあります。