しばやん雑記

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

ASP.NET MVC 3 開発入門 (13) - ビューの実装 (Details アクション)

ASP.NET MVC 3 開発入門 - インデックス

前回は Razor の基本的な文法を説明しましたので、実際にビューを実装していきましょう。まずは簡単な Details ビューから実装していきます。

Details ビューに必要な機能は

  • 動画再生
  • タグ表示、追加、削除
  • コメント表示、追加、削除

となります。以上の機能を考慮すると以下のような画面構成が一般的だと思われます。

それではコードを書いていきますので Views/Video/Details.cshtml を開きます。ファイルには既にビューを追加した時に、以下のようにスキャフォールディングで生成されたコードが書かれています。

@model MvcVideo.Models.Video

@{
    ViewBag.Title = "Details";
}

<h2>Details</h2>

<fieldset>
    <legend>Video</legend>

    <div class="display-label">Title</div>
    <div class="display-field">@Model.Title</div>

    <div class="display-label">Description</div>
    <div class="display-field">@Model.Description</div>

    <div class="display-label">CreatedAt</div>
    <div class="display-field">@String.Format("{0:g}", Model.CreatedAt)</div>

    <div class="display-label">UpdatedAt</div>
    <div class="display-field">@String.Format("{0:g}", Model.UpdatedAt)</div>
</fieldset>
<p>
    @Html.ActionLink("Edit", "Edit", new { id=Model.VideoId }) |
    @Html.ActionLink("Back to List", "Index")
</p>

スキャフォールディングで生成されたコードを見ると、モデルクラスのパブリックプロパティを埋め込むだけのシンプルなものになっています。とりあえず fieldset は不要なのでざっくりと削除してしまいましょう。

そして必要なコードを追加していくのですが、わかりやすい部分として h2 タグの中身を "Details" から動画名に変更しましょう。埋め込みは Razor を使っているので @ 記法を使います。ついでに動画タイトルの下に説明を表示するようにします。

<h2>@Model.Title</h2>
<p>@Model.Description</p>

次は動画再生周りを実装していくのですが、今回は HTML5 Video タグを使います。Silverlight を使ってもいいのですが、IE9 も正式版になりましたし手軽な Video タグを使って勉強してみましょう。ちなみに IE9 が対応している動画ファイルフォーマットは H.264 だけですので注意が必要です。WMV を再生したい場合は Silverlight を使う必要がありそうです。

基本となるタグの書き方は以下のような形になります。見てのとおり src 属性に再生したい動画のパスを指定すれば再生が可能になりますが、そのままだと再生・停止ボタンやシークバーが表示されなくなるので controls 属性を指定します。属性値に名前と同じ値を指定している理由は XHTML5 を意識したからです。

<video src="./videos/sample.mp4" controls="controls"></video>

先日公開された Visual Studio 2010 SP1 をインストールすると HTML 5/XHTML 5 のインテリセンスが動作するようになりますので、時間はかかってしまいますがインストールをお勧めします。

今回のアプリではアップロードされた動画ファイルを ~/Videos/[VideoId].mp4 に保存するようにしていますので、ここでもモデルの値を埋め込んであげればいいですね。

<video src="@Url.Content("~/Videos/" + Model.VideoId + ".mp4")" controls="controls" width="640"></video>

Url.Content という見たことないメソッドが出てきましたね。これは URL ヘルパーと言って、アクション・コントローラからの URL 生成や静的コンテンツへの相対パスの処理など、URL 周りを行ってくれるヘルパーとなっています。HTML ヘルパーと比べて知名度が低いですが、画像へのリンクを行う時など非常に重要になってきます。

後はタグとコメントですが、この二つはコレクションとなっていますので foreach を使って全ての要素を埋め込むようにします。
削除リンクは用意してありますが、まだ追加用のフォームは作成していません。後日 HTML ヘルパーを活用する部分で実装する予定です。

<h3>タグ</h3>
<ul>
@foreach (var tag in Model.Tags)
{
    <li>@Html.ActionLink(tag.Name, "Details", "Tag", new { id = tag.Name }, null) - [@Html.ActionLink("×", "Delete", "Tag", new { id = tag.TagId })]</li>
}
</ul>

<h3>コメント</h3>
<dl>
@foreach (var comment in Model.Comments)
{
    <dt>@comment.Name (@comment.CreatedAt.ToString("g")) - [@Html.ActionLink("×", "Delete", "Comment", new { id = comment.CommentId })]</dt>
    <dd>@comment.Body</dd>
}
</dl>

タグは TagController の Details メソッドへリンクするようにしましたので、これでタグでの絞込みが可能となります。コメントはよくある形へ整形しているだけで、大したことはしていないですね。

今回作成したビューのコードは以下のようになりました。

@model MvcVideo.Models.Video

@{
    ViewBag.Title = "Details";
}

<h2>@Model.Title</h2>
<p>@Model.Description</p>

<video src="@Url.Content("~/Videos/" + Model.VideoId + ".mp4")" controls="controls" width="640">
</video>

<h3>タグ</h3>
<ul>
    @foreach (var tag in Model.Tags)
    {
        <li>@Html.ActionLink(tag.Name, "Details", "Tag", new { id = tag.Name }, null) - [@Html.ActionLink("×", "Delete", "Tag", new { id = tag.TagId })]</li>
    }
</ul>

<h3>コメント</h3>
<dl>
    @foreach (var comment in Model.Comments)
    {
        <dt>@comment.Name (@comment.CreatedAt.ToString("g")) - [@Html.ActionLink("×", "Delete", "Comment", new { id = comment.CommentId })]</dt>
        <dd>@comment.Body</dd>
    }
</dl>

<p>
    @Html.ActionLink("Edit", "Edit", new { id = Model.VideoId }) |
    @Html.ActionLink("Back to List", "Index")
</p>

フォームを実装しなかった理由は、今の知識で実装してしまうと Video と Tag, Comment のコードが混ざってしまうので、分離を行うためです。ネタばれをしてしまうと、ASP.NET MVC の HTML ヘルパーには分離するための機能がしっかりと用意されているからです。

ひとまずこれで動画の再生とタグとコメントの表示*1の実装が完了しました。それでは次回は Create, Edit アクションをまとめて実装していきます。お疲れ様でした。

*1:まだ追加できないですが…