2015年3月30日月曜日

2.3 ASP.NET MVC(4)

データモデルの受け渡し

ここでは、Controller/Viewの紐付けに関する部分のみに焦点を当てる。実際にデータベースにアクセスするやり方なんかはまたあとで。
何はともあれ、まずはデータモデルを定義する。
Imports System
Imports System.Data.Entity

Namespace Nikkei.Models
 'Booksテーブルに対応するデータモデル
 Public Class Book
  Public Property Id As Integer
  Public Property Isbn As String
  Public Property Title As String
  Public Property Price As Integer
  Public Property Publish As String
  Public Property Published As DateTime
 End Class
 
 'コンテキストクラス
 Public Class MyDbContext
  Public Property Books As DbSet(Of Book)
 End Class
End Namespace
Bookクラスの1インスタンスが、データベースのレコード1件に相当。レコードの集合がコンテキストクラス。コンテキストクラスMyDbContextは、Bookクラスの集合であるBooksをメンバに持つ。

モデルを受け渡しするコントローラ/ビュースクリプト

コントローラは、このモデルを使ってデータベースにアクセスし、得られたデータをビュースクリプトに渡す。コードは以下のようになる。
Imports System.Data.Entity
Imports System.Linq
Imports System.Net
Imports System.Web.Mvc
Imports Nikkei.Models

Namespace Nikkei.Controllers
 Public Class BooksController Inherits Controller
  Dim db As MyDbContext = New MyDbContext()
  
  Public Function Index() As ActionResult
   return View(db.Books.ToList()) 
   'db.Books.ToList()は、モデルのコンテキストクラス:全レコードを取得して、Viewに渡す。
   'なんでこの分だけで全レコードを取得したことになるのかは、あとで説明がある。
   'ビューへのデータ渡しはこれだけで完了。
  End Function 
 End Class 
End Namespace
db.Books.ToList()は、Booksテーブルのすべてのレコードを、IEnumerable(Of Book)型として取得している。IEnumerableとはなんぞやというと、自分の理解では、Foreach文で、レコードの全フィールドにアクセスできるようにした型。普通の配列だと、For文で各レコードにアクセスできても、Foreach文でフィールド単位のアクセスはできない。

今回はここまで。次は、上記コントローラがレコードを渡す先であるビュースクリプトの記述をしていきます。実はここでドはまりしていたのですが、いつか分かる日もこようということで先に進むことにしました。その日のために、疑問点は書き留めておくつもりです。

2015年3月20日金曜日

2.3 ASP.NET MVC(3)

ビューヘルパー

ビューヘルパーとは:ビュースクリプト作成の際に役立つメソッド→HTMLとかスクリプトを出力する。
主なビューヘルパーはこんな感じ。
メソッド概要
Html.ActionLink指定されたコントローラ/アクションからハイパーリンクを生成
Html.BeginForm<form>要素を生成
Html.DisplayForモデル定義に応じてデータ表示用のタグを生成
Html.DisplayNameForモデル定義に応じて指定された項目の表示名を出力
Html.EditorForモデル定義に応じてデータ編集用のタグを生成
Html.LabelForラベル(<label>要素)を生成
Html.ValidationMessageFor検証によるエラーメッセージを出力
Html.ValidationSummary検証によるエラーメッセージをサマリー表示
Html.Partial部分ビューを出力
Scripts.RenderJavaScriptライブラリをインポートするための<script>要素を生成
Styles.Renderスタイルシートをインポートするための<link>要素を生成
たとえば、
@Html.ActionLink("詳細", "Details", "Books", New With{.id=Model.Isbn}, New With{.class="menu"})
なんてコードを配置すると
詳細
なんてコードに変換されて出てくるらしい。引数の種類とかそういったものは、おいおい使うようになってから…
これらを使うことによって作業が楽になるんだろうな、たぶん。
それか、VS上でGUIを使ってパーツをポイポイ置いていったら、こういうコードがポイポイ挿入されていくから、意味を知っておけ、という感じのことだろうか。いかんせん手元に環境がないので何とも言えないところで、VSが触れるようになったらまた加筆修正します。

2015年3月19日木曜日

2.3 ASP.NET MVC(2)

ビュースクリプトの実装(Razor)

コントローラで実行したアクションの結果を出力するためのビュースクリプトを作成する。
作成する場所はViewsフォルダ配下で、<コントローラ名>/<アクション名>.vbhtmlという名前にする。
コントローラのViewヘルパーメソッドでビュースクリプト名を指定した場合は、その名前で作成する。

コントローラで設定したビュー変数ViewDataの各プロパティをHTMLに埋め込む感じ。プロパティを新たに設定する場合は、ビュースクリプトの@Code~End Codeの間に書く。
ビュースクリプトの例はこんな感じ。

@Code
 ViewData("Title") = "About"
End Code

@ViewData("Title").

@ViewData("Message")

Use this area to provide additional information.

ViewData("Message")はコントローラで設定済み。ViewData("Title")を"About"としているので、上記ソースの5行目は

About.

と書いたのと等価になる。
ここで分からないのが、ViewDataの前に@をつける場合とつけない場合があること。設定時は@をつけず、出力時には@をつける???

レイアウトの適用

上記で作成したビュースクリプトですが、HTML文書というにはhead要素とかいろいろと足りないものがあります。実はこのビュースクリプトを埋め込んで完全なHTMLを作成する「レイアウト」というのがあり、これはViewsフォルダ配下のShared/_Layout.vbhtmlがそれであるというのです。スタイルなんかをここで定義するわけですね。ここではコードは省略しますが、コード中の「@RenderBody()」というところにビュースクリプトが埋め込まれます。本文では、「ビュースクリプトの結果が埋め込まれる」とあるので、@ViewData("Title")というのは、ViewData("Title")を出力しなさいという命令である、と理解したほうがよさそうです。@がつくと命令ということ?

また、このレイアウトファイルは必ず_Layout.vbhtmlになるのかというとそういうわけでもなく、レイアウトファイルのファイル名を指定しているのは、Views/_ViewStart.vbhtml(ファイル名固定)で、Layout変数で指定したファイルをレイアウトと認識します。Razorはビューの処理に先立ち、まずこの_ViewStart.vbhtmlの処理を行うので、_ViewStart.vbhtmlには、レイアウトファイルの指定のほか、ビュースクリプトに共通の処理があれば、それも記述します。

2015年3月18日水曜日

ソースコードをきれいに載せるSyntaxHighlighter

ソースコードをきれいに載せるために、こちらのサイトの情報を頼りに、SyntaxHighlighterを導入しました。brush alias一覧もあり、非常に助かります。

2.3 ASP.NET MVC(1)

プロジェクトの構成

コントローラクラスファイルはフォルダControllersの下に配置する。

コントローラクラスの実装

コントローラクラスの動作
  • 配下のメソッドはアクションメソッドと呼ばれ、これがURLの一部となる。
    URLは<コントローラ名>/<アクション名>
  • ビュー変数をViewDataオブジェクトのプロパティとして設定する
  • ヘルパーメソッドで、ActionResultオブジェクトを返す
ページ表示までの流れとしては、
コントローラ、アクションをURLで指定
→ビュー変数を設定
→ヘルパーメソッドでActionResultクラスを継承したクラスのオブジェクトを返す
→返されたオブジェクトに含まれるメソッド(コンストラクタ?)で、ページを表示したり、リダイレクトしたりする。
ということか。

ヘルパーメソッドと、返された時の動作
  • View:引数で指定された名前のビューで出力を生成
  • Content:引数で指定されたテキストを出力
  • File:引数で指定されたデータを出力
  • Redirect:引数で指定されたURLにリダイレクト
  • RedirectToAction:指定されたアクションにリダイレクト(コントローラ名も指定できる)
  • HttpNotFound:「404 Not Found」を出力
本書に書いてあるコントローラは、Imports部分を除くとこんな感じで書ける。
本書ではC#で書いてあるが、自分が使うときはVB.NETで書く可能性が高いので、VB.NETに書き換える。
というよりも、プロジェクト作成時にVBを選択していたら、これは勝手に生成された。
Returnが使えると思っていなかったのは、VBAから抜け切れてないのか。

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult
        Return View()
    End Function

    Function About() As ActionResult
        ViewData("Message") = "Your application description page."

        Return View()
    End Function

    Function Contact() As ActionResult
        ViewData("Message") = "Your contact page."

        Return View()
    End Function
End Class

例えば、URLがhttp://....../Home/Aboutだとしたら、HomeControllerのAboutメソッドが呼ばれる。文字列"Controller"は自動でオミットされるのかな?このメソッドの中で変数ViewDataに値を設定、Viewメソッドで「ViewData変数をあげるから、これを使って表示しなさい」という動作を指定している。で、ページを表示するときに、ビューはViewDataの各プロパティを、HTMLの中に埋め込んで、表示させるということですね。。

とりあえずこれで動かしてみた

ちなみに、このままデバッグ開始したら、Index()が呼ばれた様子。デフォルトではそうなんでしょうね。
さらに、VS2013では、普通にプロジェクト作成したらMVC4のプロジェクトができます。なので、プロジェクト作成時に、ダイアログボックスの上の方から「.NET Framework4.5.1」を選択すること。そうするとMVC5のプロジェクトができる。備忘録。