しばやん雑記

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

ASP.NET MVC 3 開発入門 (17) - タグ・コメント登録を実装する

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

それでは残っていたタグとコメントの追加機能を実装しましょう。今までこの二つの機能を実装してこなかった理由は、動画の詳細画面に別のビューの機能を直接埋め込みたくなかったからです。なので、今回は部分ビューを使って分離して実装します。

それでは TagController と CommentController の Create アクションに対して部分ビューを作成しましょう。スキャフォールディングを利用して作成しますが、「部分ビューとして作成する」のチェックを入れてください。

これだけでビューはスキャフォールディングによりほぼ完成していますが、今回は動画詳細画面に埋め込みますのでそのままではパス周りでずれが生じてしまいます。ですので、パスを自動的に決定するのではなく明示的に指定します。

@model MvcVideo.Models.Comment

@* アクションとコントローラを明示的に指定する *@
@using (Html.BeginForm("Create", "Comment")) {
    @Html.ValidationSummary(true)

これでビューの準備はできましたので、次は CommentController のアクションから修正していきましょう。Create アクションを修正しますが、先に修正済みのコードを出します。

//
// GET: /Comment/Create

[ChildActionOnly]
public ActionResult Create()
{
    return PartialView();
} 

//
// POST: /Comment/Create

[HttpPost]
public ActionResult Create(int id, Comment comment)
{
    try
    {
        var video = _videoRepository.Find(id);

        comment.CreatedAt = DateTime.Now;

        video.Comments.Add(comment);

        _videoRepository.Save();

        return RedirectToAction("Details", "Video", new { id = id });
    }
    catch
    {
        return RedirectToAction("Details", "Video", new { id = id });
    }
}

違いとしては GET 時に呼ばれる Create アクションに ChildActionOnly 属性を付加しました。この属性を付けたアクションは URL 指定でアクセスされた時にビューを返さなくなります。そして今までは View メソッドを使っていた部分が PartialView メソッドに変わりました。PartialView メソッドを使うと部分ビューとしてレンダリングを行って出力することができるようになります。

そして POST 時に呼ばれる Create アクションには id パラメータを追加しました。この id はコメントが付けられようとしている動画 ID が入りますので、リポジトリから対象の動画を取得して Comments コレクションに追加しています。Entity Framework を使用しているので、これだけで中間テーブルへのエントリ追加など全て行ってくれます。

コメント追加が成功した場合には表示していた動画の詳細ページへ戻るようにしました。これでフォームなど登録側が完成したので、最後に動画詳細画面にフォームを表示させるコードを追加します。今回のようなシナリオでは Html.Partial や Html.EditorFor が使用できないため、Html.Action を使用します。

@* コメントを表示させたい場所へ書く *@
@Html.Action("Create", "Comment")

これで CommentController の Create アクションで出力されたフォームが動画詳細画面に埋め込まれて表示されるようになります。実際にブラウザで確認すると以下のように表示されます。

フォームに値を入力して「Create」ボタンを押すとちゃんとコメントが追加されます。タグの実装はコメントと全く同じですので省略させていただきます。
しかし、今のままではフォームが空のままで「Create」ボタンを押すとエラーメッセージが表示されませんね。次回はこの問題に対してクライアントサイド検証を利用して対応したいと思います。お疲れ様でした。