連載:マイクロソフト技術による標準化志向Web開発ことはじめ

第2回 ASP.NET MVCの全体像と、Webフォームとの使い分け

マイクロソフト 井上 章
2011/01/17

コントローラの実装

 ここで、簡単にコントローラの実装例を見ておこう。

 次に示すのは、「ASP.NET MVC 2 Web アプリケーション」プロジェクト・テンプレートによって既定で作成されるHomeControllerクラスの実装コード(C#/Visual Basic)だ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplicationDemo.Controllers
{
  [HandleError]
  public class HomeController : Controller
  {
    public ActionResult Index()
    {
      ViewData["Message"] = "ASP.NET MVC へようこそ";

      return View();
    }

    public ActionResult About()
    {
      return View();
    }
  }
}
<HandleError()> _
Public Class HomeController
  Inherits System.Web.Mvc.Controller

  Function Index() As ActionResult
    ViewData("Message") = "ASP.NET MVC へようこそ"

    Return View()
  End Function

  Function About() As ActionResult
    Return View()
  End Function
End Class
既定で作成されるHomeControllerクラスの実装コード(上:C#、下:VB)
このコードは、Controllersフォルダ内に自動生成されたHomeController.cs/.vbファイルのもの。

 この実装コードにあるIndexやAboutといったメソッドは、「コントローラ・アクション・メソッド」と呼ばれ、クライアント側からのHTTPリクエストによってコントローラで最初に実行されるメソッドだ。例えば、「http://www.example.com/Home/Index」というURLでHTTPリクエストを処理する場合、後述するURLルーティングによって既定ではHomeControllerクラスのIndexアクション・メソッドが実行されることになる。そして、そのアクション・メソッドではリクエストの内容に従い、モデルとなるデータ(後述)を用意してからHTMLコードを生成するためのビューに制御を移す(つまり、Viewメソッド*1を呼び出す)。

 上記のIndexアクション・メソッドのコード例のようにViewDataプロパティ(=ViewDataDictionaryオブジェクト)*1を用いて、文字列などのオブジェクトをモデル・データとしてビューに受け渡すことができる。さらには、ADO.NET Entity Frameworkを用いたEDM(Entity Data Model)やLINQ to SQLなどを使用して、データ・ベースから取得した複数のレコードをモデル・データとしてビューに受け渡すことも能だ。

*1 ViewメソッドやViewDataプロパティは、HomeControllerクラスの基本クラスであるControllerクラス(System.Web.Mvc名前空間)のメンバである。

ビュー定義

 コントローラ・アクション・メソッド内でViewメソッドが呼び出されると、アクション・メソッドに関連付けられたビュー定義(.aspxファイル)を基に、ASP.NET MVCフレームワークのビュー生成エンジン(ViewEngine)がHTMLコードをレンダリングして、クライアント側へHTTPレスポンスを返すことになる。

 一例として、上記のコントローラのIndexアクション・メソッドに既定で関連付けられたビュー定義(Index.aspxファイル)を見てみよう。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
  ホーム ページ
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
  <h2><%: ViewData["Message"] %></h2>
  <p>
    ASP.NET MVCの詳細については、<a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a> を参照してください。
  </p>
</asp:Content>
Indexアクション・メソッドに関連付けられたビュー定義(Index.aspx)

 ASP.NET MVC 2のビュー記述におけるポイントは、「コードナゲット」と呼ばれる「<% ... %>」の構文を用いて.aspxファイル内にインラインでコード・ブロックを記述することにある(上記のコードで背景色が黄色になっている個所)。これは、ASP(Active Server Pages)における.aspファイルとほぼ同じ記述方法となるため、Webフォームで進化したWebページ記述が、ASP.NET MVCでは退化してしまったともいえるかもしれない。

 現在のところ、Visual Studio 2010のデザイン・ビュー表示においても、コードナゲット個所のプレビュー表示などはサポートされていないため、基本的には.aspxファイルのソース・コード・ベースでコーディングしていくことになる。これまでのWebフォームの開発手法に慣れている開発者であると、コード・ベースのビュー記述は面倒に思えるであろう。

 一方では、Webフォームの経験はないが、HTMLやCSS、JavaScriptなどを使ったWebサイト制作やASP開発の経験がある方であれば、ASP.NET MVC 2は習得しやすい開発フレームワークともいえる。また、PHPにも比較的近い記述になるため、既存のPHP開発者にとっても、これからASP.NET開発を始めるのに「良い入り口」となり得る。

コントローラとビューの命名ルール

 コントローラ・アクション・メソッドとビューの間には、「規約は設定に勝る」(CoC: Convention over Configuration)のコンセプトの下で、単純な命名ルールで関連付けが行われている。具体的には、コントローラのアクション・メソッドに対応するビュー・ファイルは、下記の命名ルールの下、プロジェクト・フォルダ内の.aspxファイルが選択される。

プロジェクト・フォルダ
  ┗━ 「Views」フォルダ
      ┗━ 「<コントローラ名>」フォルダ
           ┗━ 「<アクション・メソッド名>.aspx」ファイル

 例えば、ここまで例で取り上げてきたHomeControllerクラスのIndexアクション・メソッドに関連付けられるビュー定義ファイルは、

プロジェクト・フォルダ
  ┗━ 「Views」フォルダ
      ┗━ 「Home」フォルダ
           ┗━ 「Index.aspx」ファイル

が使われることになる。次の図は、[ソリューション エクスプローラー]内の該当フォルダ/ファイルの表示例である。

図 HomeControllerのIndexアクション・メソッドに関連付けられているIndex.aspx
HomeControllerクラスのIndexアクション・メソッドで使われるビューは、「<Views> − <コントローラ名> − <アクション・メソッド名>.aspx」のファイルが既定で選択される。
設定ファイルやソース・コードで明示的にアクション・メソッドに関連付けるビューを指定しているわけではなく、単純な命名ルールの下、プロジェクトのフォルダ名やファイル名だけで関連付ける形を採っている。

 設定ファイルやソース・コードで明示的にアクション・メソッドに関連付けるビューを指定しているわけではなく、プロジェクトのフォルダ名やファイル名だけで関連付けを行っているのが特徴だ。これによって、コントローラとビューを疎結合状態に保つことができるため、コントローラ部分の単体テストやビューの差し替え・変更などが行いやすくなるといったメリットがある。

HTMLヘルパー・メソッド

 ASP.NET MVC 2のビュー記述では、コードナゲットによるインラインの埋め込みコード・ブロックを用いることを先に述べたが、加えてWebフォームで使用していたような各種サーバ・コントロールは一部のコントロールを除いて基本的には使用することができない。つまり、ほとんどのビュー記述をHTMLコードとしてコーディングすることになる。

 これは、開発者やWebデザイナが想定したとおりのHTMLコードを柔軟に設計し、記述できるといったメリットがある半面、HTMLそのものの知識が必要になるため、そういったWeb開発の経験がない開発者にとっては敷居の高いものになるであろう。この状況をできるだけ緩和し、HTMLのコーディング・ベースでもある程度の粒度でUI部品化されたものを使用できるようにした「HTMLヘルパー・メソッド」(単純に「ヘルパー」と記述する場合もある)と呼ばれる仕組みが用意されている。

 例えば、アンカー・タグ(<a>タグ)を使って、「/Home/Index」というURLへのリンクを記述する場合、ActionLinkヘルパー・メソッドを用いて次のように書くことができる(HTMLヘルパー・メソッドは、ビューのメンバであるHTMLプロパティ経由で呼び出せる)。

<%: Html.ActionLink("ホーム", "Index", "Home") %>

↓ 生成されるアンカー・タグ

<a href="/Home/About">ホーム</a>
ActionLinkヘルパー・メソッドを使用したアンカー・タグの生成

 また、<input>タグでテキストボックスを記述する場合は、TextBoxヘルパー・メソッドを使用することができる。

<%: Html.TextBox("Name", "チャック") %>

↓ 生成されるinputタグ

<input id="Name" name="Name" type="text" value="チャック" />
TextBoxヘルパー・メソッドを使用した<input>タグの生成

 次の表には、ASP.NET MVC 2で使用できる代表的なHTMLヘルパー・メソッドを示す。これら以外にも、多くのヘルパー・メソッドが用意されている(詳細はMSDNライブラリ「ASP.NET MVC での HTML ヘルパーによるフォームのレンダリング」などを参照)。さらに、カスタム・ヘルパー・メソッドを独自に実装することも可能である。

ヘルパー名 概要
ActionLink アクション名やコントローラ名から<a>タグを生成
BeginForm <form>タグを生成
TextBox <input>タグによるテキスト入力フィールドを生成
Password <input>タグによるパスワード入力フィールドを生成
ListBox <select>タグによるリストボックスを生成
CheckBox <input>タグによるチェックボックスを生成
表 代表的なHTMLヘルパー・メソッド

 これらのヘルパー・メソッドを使用することで、例えばデータ・ベースから取得した複数のレコードなどのモデル・データをHTMLタグに埋め込む場合などでは、直接HTMLコードを書くより簡単にビューを記述できる。

URLルーティング

 ASP.NET MVC 2の特徴的な機能として忘れてはならないのが、URLルーティングだ。これは、.NET Framework 3.5 SP1から使用できるようになったASP.NETの新機能で、この機能をASP.NET MVCフレームワークでは標準で使用している。

 通常は、Webサーバ上に配置された物理ファイル・パスと、それに付随するHTTP GET形式のクエリ・パラメータでURLが構成される場合が一般的だ。

 一方、URLルーティングでは、アクション・メソッド名やクエリ・パラメータなどをURLの一部として用いることで、実際のWebサーバ上の物理ファイル・パスに依存しない形式のURLを自由に定義することができる。これにより、URLそのものがシンプルで分かりやすくなるうえ、URLに明示的に任意の文字列を埋め込むこともできるため、SEO(Search Engine Optimization)対策などにも有効だ(次表を参照)。

一般的なURL例 URLルーティングを使用した場合
/Products/List.aspx?category=car /Products/Car/List/
/Products/Details.aspx?category=car&id=5 /Products/Car/Details/5
表 URLルーティングの例

 ASP.NET MVCフレームワークでは、このURLルーティングの機能を用いて、既定で次のようなルーティング定義が行われている。

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

  routes.MapRoute(
    "Default", // ルート名
    "{controller}/{action}/{id}", // パラメータ付きの URL
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // パラメータの既定値
  );
}
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}")

  ' MapRouteメソッドは次のパラメータを順番に受け取ります:
  ' (1) ルート名
  ' (2) パラメータ付きの URL
  ' (3) パラメータの既定値
  routes.MapRoute( _
    "Default", _
    "{controller}/{action}/{id}", _
    New With {.controller = "Home", .action = "Index", .id = UrlParameter.Optional} _
  )

End Sub
Global.asaxファイルのコードビハインド・ファイルのRegisterRoutesメソッドで定義されるURLのマッピング(上:C#、下:VB)

 この既定のURLマッピング(=MapRouteメソッド内)では、コントローラ名とアクション・メソッド名、そしてパラメータを用いた形式でURLルーティングが定義されている。これにより、例えば「/Home/Details/2」というURLのHTTPリクエストでは、HomeControllerクラスのDetailsアクション・メソッドがパラメータ「2」で呼び出されることになる。

 ここまでで、ASP.NET MVCフレームワークの基本機能を解説した。これ以外にもさまざまな機能が用意されているが、前述したとおり、本連載ではそれらの詳細な解説は割愛する。より詳しい開発方法などは、各種オンラインで公開されているプログラミング記事などを参照してほしい。

WebフォームとASP.NET MVC

 続いて、前回解説したWebフォームと、今回解説したASP.NET MVCについて、それぞれの特徴を踏まえたうえでの使い分けのポイントをまとめておく。両者ともASP.NETをベースとしたWebアプリケーション開発には非常に有用なフレームワークであるが、それぞれのフレームワークの特徴をよく理解して、どちらのフレームワークを使うかを検討することが大切だ。

 WebフォームとASP.NET MVCの特徴を1つの図にまとめたものを次に示す。

図 WebフォームとASP.NET MVCの特徴

 この図に示すように、同じASP.NETベースの開発フレームワークとはいえ、そのコンセプトは大きく異なっている。これらの特徴を踏まえて、それぞれのフレームワークがどのようなスキル・セットを持った開発者に適しているのか、またどのような目的のWeb開発に適しているかをまとめると、次の図のようになる。

図 WebフォームとASP.NET MVCの使い分け

 ASP.NET MVCは、HTMLやJavaScriptを使ったWeb開発経験者や、Web標準への準拠などを重視した、比較的インターネット向けのWebアプリケーション開発に適したフレームワークといえる。一方、Webフォームは、これまでVisual BasicやWindowsアプリケーション開発を行ってきた開発者や、その開発プロジェクトで新たにWebアプリケーション開発を行う場合などに適しているといえるであろう。

 ここまでで、ASP.NETをベースとしたWeb開発を行うに当たり、WebフォームとASP.NET MVCという大きく2つの入り口が用意されていることがご理解いただけたと思う。また、開発者のスキル・セットだけではなく、プロジェクトの要求、チーム編成、納期なども踏まえたうえで、WebフォームとASP.NET MVCを適材適所で使い分けることが重要だ。

 次回は、ASP.NET MVCのビューの機能と特徴について、Web標準やHTML5への対応、さらには携帯サイト開発といった観点で、さらに掘り下げて解説していく。end of article


 INDEX
  [連載]マイクロソフト技術による標準化志向Web開発ことはじめ
  第2回 ASP.NET MVCの全体像と、Webフォームとの使い分け
    1.MVCパターン
  2.ASP.NET MVC 2を使ったWeb開発概要

インデックス・ページヘ  「マイクロソフト技術による標準化志向Web開発ことはじめ」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間