2009年8月28日金曜日

ボフったー

本日BoFに参加してくださったみなさま!ありがとうございました!

超、緊張しました。結構あれこれとしゃべること用意してたんですが、全然しゃべれませんでした。自己紹介を途中棄権ってなんだよ!みたいな。

内容的にはちゃんと「適材適所で使い分け」というのを入れたかったんですが、なにもかもが後の祭り。だって、管理画面なんか小野さんのサンプルみたいにゼロコーディングで出来たら最高ですよね。ViewState/PostBackなPage Controllerスタイルで、コントロールに処理を完全に委譲してしまうWebFormは最強です。それらの機能を少し横取りして、Pageからすべての機能を切り離し(この時点でもうアーキテクチャスタイルが違うので比較することじたいに無理があるんですけど)Front ControllerスタイルにしたASP.NET MVCによるスクラッチ開発は面白さ爆発です!

とにかくまず最初に驚いたのがASP.NET MVCで何か作ったことのある開発者の方が思ってた以上に多かったこと。ビックリしました。可能性たっぷりですね!フレームワークと名乗るにはまだまだ万人向けなものにはなってないMVCですが、何となくこの路線を突っ走って欲しいという個人的には思ってます。だってチャップリンも言ってるじゃないですか。

人生は恐れなければ、とても素晴らしいものなんだよ。
人生に必要なもの。それは勇気と想像力、そして少しのお金だ。

うん、全然関係無い言葉だね!

えと、ちなみにデスね、今日話したかったメモを以下に残しておきます。

  • 共通のnamespaceはImportでaspx/ascx毎にしていするんじゃなくて、web.configで指定しておこう。
  • HTML入力を受け付ける時にはValidateInput属性で指定しよう。Pageディレクティブやweb.configでのValidateRequestはController関係無いよ!
  • csprojのMvcBuildViewsをtrueにしてViewのコンパイルを強制するのが便利なときもある。
  • JavaScript無しで機能を実装したあとに、JavaScriptでのUX向上を目指すのが王道。でも、こだわらなくてもいいかもね。
  • URLはリソース指向に考えてルーティングに定義しよう。
  • RepositoryとServiceを作成しといて、アクションでは単なる呼び出しがいい。
  • DB Modelと View Modelを分ける(相互にマッピングする)。
  • テストしやすくするために、HttpContextへの依存をControllerからなくす(UserNameとIsXhr)。依存性が無いならテストは結構楽ちん!
  • 全体共通なBaseControllerを定義しておくと何かと楽ちん(abstractでね!)。
  • Viewでの作業を楽にするためにヘルパーを定義。
  • Controller名やAction名のマジックストリングをなくすために、T4MVCを活用。
  • 入力検証を楽にするためにDataAnnotationsModelBinderを活用。
  • もっと複雑になるならDIでRepository/Serviceの依存性注入。
  • マッピングも大変ならAutoMapperやら(自分で書いてもいいけど)。
  • テストが複雑になりそうなら(依存性を持ったもののテストをしたいとか)Mockを使おう。MoqやらRhino.Mocksやら。
  • カッコ良くRESTfulな実装にしたいならREST for ASP.NET MVC!

参考にするといいかもなURL

お勧め書籍

サンプルに実装してる項目もあれば、無い項目もあります(DIやMockや)が、こういうのを取り入れると楽しく開発出来るっていうのを話したかったデス。

サンプル一式は↓こちらからどうぞ。

動かすにはSQLServer2008Express以上が必要になります。Databasesフォルダ内の2つのMDFをそれぞれAspNetDBとMyTimeDataという名前でアタッチ(MS SQL Server 2008 Attach Database .MDF File)するとそのままで動くんじゃないかと思います。

※App_Dataに入れてAttachDbFilenameをConnectionStringに指定する方が簡単なんですが、それだとウェブのプロジェクトとテストのプロジェクトで同じインスタンス名でDB作成しようとして動かないんで気をつけてください。

機能的な物はBoFで紹介したとおり、Membershipによるユーザー管理とログイン、作業時間の追加・更新・削除と合計表示のみです。これにチャートコントロールでの表示やら、月内デイリー合計なんかの機能をつければ、それなりに使える物になるんじゃないかと思いますがどうでしょうかね。プロジェクトの名前を「ボフったー」にしなかったのが「エドったー」に完全に負けてるところデス!

細かいサンプルの説明は...、必要ならしますが、どうなんでしょう。週末だし書くかもしれないですが、ホッケーもしたいので微妙です。たけはらが書かなくてもチャックが説明してくれると思います!無茶ぶり返し!

最後に。

こういう機会を与えてくれた、小野さんとナオキさんには感謝しきれません。ボスにはいろんな人を紹介してもらってマジ感謝です。一人だと誰とも知り合えずに過ごす事になったこと間違い無しです。MSの方達も、こんなどこの馬の骨なのか分からないチンピラ開発者の話に耳を傾けてくれてホント嬉しかったです。

BoFでたけはらの話に耳を傾けてくれた人たちの暖かさには、感謝しても仕切れません。マジ泣ける。本当にありがとうございました。

コンカレント

Tech ED2日目。今日はボスと別行動もあって、ちょっぴり大人の仲間入り?

まぁ、最初のセッションは同じのだったけど、別々にセッションルームに入ったので別行動ってことでいいですかね?今日も熊澤さんの話を聞きに行ったんですが、ちょいちょい熊澤さんが明後日の方向を向いて話をするわけですよ。ナゼ正面向いて話をしないんだろうかと思って目線の先を見るとボスが立って見てた...。そこ、マンツーなんですか。何でですか。見に来てる人100人くらいいる感じなんですが、マンツーで説明なんですか。そーですか。NUMAの話で盛り上がり、アンドキュメンテッドな動的管理ビューを紹介してくれたりと、初日に続いて濃厚な内容でした。

とりあえずBoFって何?みたいな状態を打破するために他の方のBoFを見てみることにしました。ボスとべーさんの言うとおりみんなスーツでした。な、わけねーよ。誰もスーツじゃないじゃないか!でも、不安だったからMSの人に「スーツじゃないとダメなんですか?」って聞いたら「そんなことないです」って教えてくれました。隣で渋木さんが「おまえ、ばらしてんじゃねーよ」という目でMSの人のこと見てた...。その目はまるで熊。ハンマー持った熊。

なんやかんやで、セッション全終了の後、休憩ルームでおしゃべりしてたら、ナオキさんが「ガンダムの人がいます!」と呼んできてくれて、少しお話しすることが出来ました。もうね、とにかくね、ガンダムは分からないから違う例えにしてください、と。攻殻機動隊か電脳コイルなら分かるので、そっちでお願いしますと。Azureの話をもっとしたかったけど途中で渋木さんと赤間さんも参加して、猫バス事件の話になって...。面白かったからいっか。でも、あれだ、みんな日常会話で使う単語が変。誰もなんの突っ込みもなく普通にそういう単語なんだもんよ。技術の話をしてるわけじゃなく、風呂とトイレがコンカレントだとか、会話がかみ合うのをプロトコルが一致するとか、食事に合流するのをジョインするとか、日常会話でそれはおかしいと思うんだ。オレおかしいと思うんだ。オレがおかしいのか??

夕食の時に、今度は荒井さんが同席。The Root of .NET Frameworkでハートを鷲づかみにされた荒井さん。なんかね、今までどんな人が本を書いてるとか、ブログを書いてるとか全然意識したこと無かったんですよ。自分とは関係無い世界の人たちっていうか。実際会って話をするなんて考えたこと無かったし。でも、なんかみんな素敵な人ばっかりでさ~。食事の後、途中まで電車が一緒でマンツーマンで荒井さんとおしゃべり出来て得した気分。名もない開発者な自分の話をずっと聞いてくれて、答えを返してくれて。あ、そうそう、自分もだけど、荒井さんも気がついてないだろう接点を発見した。荒井省三のBlog : The Root of .NET Framework の書評で荒井さんがたけはらタンブラのThe root ofの感想へリンクしてくれてた。う~ん、今日一緒に話をするまえに知ってたら、もっと楽しかったかも!でも、明日もあるし、会ったらその話をふってみようかな。

んでもって明日は、とうとうBoFに登壇(最後の枠のBoF-14 ASP.NET Web Form vs. ASP.NET MVC in Japanデス)。小野さんは「なんとかなるよ」と言ってくれてるけど、全く打ち合わせもなく、かなりドキドキなんですけど...。チャックが初日のセッションで無茶ぶりするもんだから胃が痛くてしょうがねーす。たぶん小野さんとナオキさんの陰に隠れて小さくなってると思います。

2009年8月27日木曜日

ボスと一緒に

2009だけど初めての参加。なんか15周年ってキーノートで言ってたから、ずいぶんと周回遅れだね!9/5からクイーンズスクエア内にクリスピークリームの店がオープンするっていうデカイポスターもあって、そっちのほうが気になるとは言いづらい。

IMG_2524

まぁ、ドーナツパーリーはまだ出来ないのでからいいとして、今回のTech EDは小野さんナオキさんに誘われ、BoFで前にでるっていう状況での参加。しかもそんな感じの参加なもんで参加証も持ってない。入り口でいきなり「帰れ!」とか言われたら泣きながら帰ることになるだろーな、と不安になりながら会場に向かってたら、パシフィコで海のエジプト展やってるって書いてあったからいざとなったらエジプト展でも見て帰ろう。

IMG_2526

前日にボスに不安な胸の内を打ち明けてみると「行けば何とかなる」と猪木ばりに男前なことを言われてしまい涙目。超不安なまま受付に行ったら、こっちじゃなくてあっちいけ、いやこっちじゃなくて君はあっち、とたらい回しのあげく、奇跡的にも小野さんと同時に受け付けするというナイスな展開。そのままくっついてキーノート聞き終わると小野さんは「じゃ、MVPのランチがあるから」と去っていき、会場出口でナオキさんにメールしたら、もちろん「MVPのランチです」と返事が返ってきて、完全に親とはぐれたアザラシの子供状態。おかしい。横浜在住なのに完全なるアウェー感。横浜大会で散々行きまくったはずのパシフィコで超アウェー。こんな時にはボスに頼ろう。急いでボスに電話をしたら何とか落ち合うことが出来ました。Tech EDこえ~。

なんと言っても、勝手知らないTech ED。で、ここからどうすればいいんでしょう。ご飯食べたはいいけど...。とりあえず「SQL Server チューニング」のセッションは絶対聞いた方がいい、熊澤さんのセッションはパネー、と言われたのでそれを聞くことにしました。ボスと一緒に。これがまた恐ろしく濃い内容で、話す内容とスライドとデモとがマジパネースピードで「今回使ったクエリは後でどこかからダウンロード出来るようなる思います」と熊澤さんが言うんだけど、それがどこになるのかが分からないという罠。ちなみにスピーカーテーブルの真ん前の特等席でボスと2人で「はえ~」やら「すげ~」やらはしゃぎながらもとてもすばらしい内容で感動しました。Tech EDぱねー。

その後、続けてASP.NET MVCのセッションが同じ場所で始まり、もちろんそこにも参加。

IMG_2527

チャック

で、デモが今回作ったサンプルとほとんどかぶってる感じで切なくなりました。エドったーめ!そういえば今までTwitterを登録はしてても使ってなかったのをボスに突っ込まれ、チャックのセッションでも話しが出てきたってので、勢いでボスとチャックをフォローしてみた。

その後はライトニングトークっていうのをボスと一緒に聞きに行って、更にボスの宿泊先で渋木さんとおしゃべり。挙げ句の果てにボスと渋木さんと3人で食事に行って、オモロ話で盛り上がる。渋木さんは肉が似合いすぎる。

結局、一人では何も出来ず、いつも以上にボスにべったりなTech ED初日でした。Tech EDおもしれ~。

2009年8月22日土曜日

BoF

ナオキにASP.NET(仮) : Tech Ed Japan 2009 最終日の BoF 「ASP.NET Web Form vs. ASP.NET MVC in Japan」に登壇します

と、言うわけで当日はお手柔らかに(特にボス)。

こんなサンプル見てみたいという要望があれば持参もあるかもよ~。ないかもよ~。

ナカジその3、3on3

ホッケーを愛する日本全国の人々へ:COVERAGE(カバリッジ)~ステップ3「3 on 3」 - livedoor Blog(ブログ)

1on1,2on2とくれば次は3on3。

というわけで、ナカジのすばらしい守り方の第3弾。今回も延長線上での考え方なので、2on2までが理解出来てれば難しい話ではないけど「ゴール前にいろ」が通用しないというのが大事なポイント。相手との距離を測らずに(スティック1本)立ってても役にたたない。

DFの1~3はそれぞれのポジション毎に役割が変わるので、自分の役割は1つだけだと決めつけるようなプレー(この人をマーク!とかココに立ってればいい!っていうのはチームプレーにならない)をすると全然機能しなくなるので要注意。

2009年8月21日金曜日

2009年8月18日火曜日

はしご

先週末の土曜(8/15)、サンピア日立に行ってきた。ホッケーしに。前回行ったのが2年前のロー連の大会で、今回で2度目。しかもお盆休みまっただ中で、行きはまだしも帰りは超渋滞が予想される日帰り強行日程。合宿のお手伝いってことでホントは土日2日間なんだけど、オグさんがどーしてもっていうから日帰りで。

いつもは単独行動で一人ドライブなんだけど、今回は日帰りだからオグさんと大島さんとイマイちゃんと4人でゴー!みんなでおしゃべりしながらのドライブを楽しみつつ、途中のサービスエリアにあるスタバで朝食を取ったのが運の尽き。オグさんと二人で食事直後にゲリラ豪雨。しかもトイレに立ち寄ったサービスエリアではビッグルーム激混み。もう無理。もう限界と諦めかけたところで、ギリギリ入れた。マジ漏らすかと思ったよ。先行き不安。

サヨちゃん整腸剤ありがとう。

IMG_2516 IMG_2515

10:00練習開始で16:00まで練習して、帰りの渋滞で便意をもよおしたらパネーことになるんで、再度薬を飲んでおく。泊まり組はこの後ボインボインクイーンBBQだけど日帰り組はすぐに帰らないと今日中にたどり着かないんで、そそくさと撤収。途中、魚のおいしいお店があるってことで、食事をしてたら、BBQ担当ミチアキさんの買い出しにばったり遭遇。「今帰ったって渋滞なんだからBBQしようよ」と明らかに一人残されるのが寂しいという目で誘いかける。「いや、帰る」と無下に断り、子犬のような目をしてるミチアキさんを残し出発。

渋滞40kmとか表示出てたけど、あれよあれよと3時間で到着。思いのほか早く着いたんで荷物を詰め替えて22:00から新横でアイス。ホッケーのはしごしてやった。てへ。

更に、翌日「戸塚集合」と呼び出されて、ハタ君とミチと3人で(少なすぎるだろ)ひたすら1対1。超疲れたけど、やりきった感のある週末でした。

2009年8月9日日曜日

なかじスゲ~!

ホッケーを愛する日本全国の人々へ:COVERAGE(カバリッジ)~ステップ1「1 on 1」 - livedoor Blog(ブログ)

まずは1オン1の守りの説明。この時点でかなりグッとくる。

ホッケーを愛する日本全国の人々へ:COVERAGE(カバリッジ)~ステップ2「2 on 2」 - livedoor Blog(ブログ)

続いて2オン2の説明。感動的。

マンツーマークは10年前の発想だと言い切るところがすばらしい。利にかなってないもん。そこで「マンツーなんだから、おまえのせいだ!」なんて話はうんざりっすよ。

ASP.NET MVC 2 Preview1でのArea

ふぅ~。出遅れ。かなり出遅れでしょんぼり。

ASP.NET MVC V2 Preview 1 Released - ScottGu's Blog
日本語はもちろんこちら→ASP.NET MVC V2プレビュー1がリリース - @IT

少しずつ順番に見ていこうと思います。順番なのでまずはArea機能。もともとPhilさんがこの機能をV1の時から紹介(Grouping Controllers with ASP.NET MVC)してて、V1のPreviewのいつだか忘れたんですがRouting登録時にControllerのnamespaceを指定出来るようになってるんです。それを使って違うnamespaceのControllerを指定することを"Area"と呼んでるという感じです。RouteControllerへのArea登録用拡張メソッドの作成でV1は実現して他のをV2では最初から用意しといたら便利かもね~、な流れ(特に開発規模が大きくなって分業始める事を考えると)でしょうか。

とりあえず、使ってみましょう。と、いっても上記記事を見てもやり方は書いてないのでサッパリ分からないですよね。でも今回からはMSDNにすでにドキュメントが用意されてます。

Walkthrough: Organizing an ASP.NET MVC Application by Logical Areas

MSDNマガジンを機械翻訳にするなら、その分のリソースをこっちにさいて日本語化しといてくれよ、なんてぼやきは無しでいきましょう。ぶつぶつ。

まず、通常通りにMVC 2のプロジェクトを作成。”MainSite”という名前で作ってみました。

area1

そうそう、V1とV2はそれぞれ参照するアセンブリが違うので、一緒にインストールしててもなんの問題もないので、ガンガン入れて試すといいと思います。

area2

プロジェクトテンプレートももちろん最初から日本語版のVSで動きますね。こなれてきてます。

ドキュメントに書かれてる手順でサブプロジェクトを作っていきましょう。ソリューションに新しく「ソリューションフォルダ」を追加して、その中に"Sub1"と"Sub2"という名前でMVC2のプロジェクトを作成。でもって、不要なファイル達をゴッソリ削除。とにかくControllersフォルダとルートのweb.configだけが残ってればよろしデス。

area3

↑こんなようになってればOK。

で、ルーティング登録用のファイルを各サブプロジェクトに作っておけと、ドキュメントに書かれてるのでそれに従います。ん?それだと面白味に欠ける?分かりました。んじゃ、MainSiteのルーティングにまとめて書くやり方でやってみましょう!(本来はきちんと分けた方が機能分離出来て分担しやすいはずです)

MainSiteのGlobal.asaxのルート登録を以下のように書き換えます。

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

      routes.MapAreaRoute(
        "AreasSub1",
        "Sub1Default",
        "s1/{controller}/{action}/{id}",
        new {controller = "Home", action = "Index", id = ""},
        new[] {"Sub1.Controllers"}
      );

      routes.MapAreaRoute(
        "AreasSub2",
        "Sub2Default",
        "s2/{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" },
        new[] { "Sub2.Controllers" }
      );

      routes.MapAreaRoute(
        "MainSite",
        "Default",
        "{controller}/{action}/{id}",
        new { controller = "Home", action = "Index", id = "" },
        new[] { "MainSite.Controllers" }
      );

      //routes.MapRoute(
      //    "Default",                                              // Route name
      //    "{controller}/{action}/{id}",                           // URL with parameters
      //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
      //);

    }

デフォルトで登録されてるMapRouteがコメントアウトになって、MapAreaRouteで登録し直してるのには理由がありまして、Areas内のHome/Indexを表示したりしてるときに、MainSiteへのリンクをActionLinkで出力する際にエリア名を指定しておく必要があるんですね。その時、デフォルトの登録だとエリア名がないので、ちゃんとリンクを出力できなくなります。気をつけて!

MainSiteのHome/IndexにSub1とSub2へのリンクを書きます。

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

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

  <% = Html.ActionLink("MainSite Home","Index","Home") %><br />
  <% = Html.ActionLink("Sub1 Home", "Index", "Home", new { area = "AreasSub1" }, null)%><br />
  <% = Html.ActionLink("Sub2 Home", "Index", "Home", new { area = "AreasSub2" }, null)%><br />

</asp:Content>

これで一度動かしてみます。

area4

ぬほ!ちゃんと動く。リンクをクリックしてもエラーでない。でも、まだ、Sub1/Sub2用のIndex Viewを作成してないのですべてのリンクで全く同じViewが出てきます。とりあえず、この状態でレンダリングされるHTMLは↓こんな感じで予想通り。

  <a href="/">MainSite Home</a><br />
  <a href="/s1">Sub1 Home</a><br />
  <a href="/s2">Sub2 Home</a><br />

そりゃそうっすね。特になんの説明もなくここまで進みましたが、少し捕捉。MapAreaRouteの台1引数のエリア名とActionLinkなんかで指定するRouteValueDictionaryのarea指定が一致しないとちゃんと解決出来ないので気をつけましょう。そこだけです。上記の例で言えばAreasSub1/AreasSub2がそれぞれエリア名に当たるんで、同じものをActionLinkのareaに指定しなきゃダメです。あと、まだPreviewだからだと思いますが、今のところHtmlAttributeの指定がなくてもActionLinkの引数にはnull指定で全部していするようにしないと、これまたリンクが出力されません。overload実装が部分的。

続いて、Sub1/Sub2用のViewを定義します。これがデスね、勘でやってると気がつかない(Sub1/Sub2のプロジェクトにおきたくなるよね?)んですが、MainSiteに置いておく必要があります。いや、必須じゃないけどWebFormViewEngineを書き換えれば他のプロジェクトに置いておいてもいいけど、デフォルトはメインのプロジェクトのViewsフォルダを探すようになってるので、その辺気をつけましょう。

なので、MainSite/Views/Areas/AreasSub1/Home、MainSite/Views/Areas/AreasSub2/HomeにそれぞれのIndex.aspxをおきます。ここでもAreasSub1/AreasSub2とルーティングで指定したエリア名を使う事になってます。

area5

↑こんな感じで。それぞれのIndexが区別出来るように、AreasSub1の内容は

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>AreasSub1のHome/Index</h2>

</asp:Content>

AreasSub2の内容は

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>AreasSub2のHome/Index</h2>

</asp:Content>

と、しておきます。ドキュメントには以下のようなサンプルが載ってるので、これで試して見るとルーティングのデータが見れるので分かりやすいかも。

<div id="main">
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
        <p>
            Controller: <%= ViewContext.RouteData.Values["controller"] %><br />
            Action: <%= ViewContext.RouteData.Values["action"] %><br />
            Area: <%= ViewContext.RouteData.DataTokens["area"] %>
        </p>
    <div id="footer">
    </div>
</div>

areaの情報(どこのnamespaceを参照するのか)が、DataTokensに入ってControllerの解決時に参照されるのが分かりますね。ソースをテケテケ追いかけてみるとですね、MapAreaRouteがMapRouteを呼び出した後に、Defaults/Constraints/DataTokensそれぞれにareaを設定してる。内部ではこれまで通り"Namespaces"で参照するようになってるので、DefaultControllerFactoryでControllerTypeを取得する部分のコードには変化無しです。

area7 area6

実際には、これだけだと、Home/Aboutそれぞれの参照先がs1/s2のArea内に入ってしまって、MainSiteを参照しなくなってしまうので、そこら辺のActionLinkにもすべてareaを指定するように変更する必要があります(デフォルトのMapRouteを消した理由はココに絡んできます)。

ちなみに、Philさんのエントリで「Single Project Areas With ASP.NET MVC 2 Preview 1」というのがありまして、同じプロジェクト内でのAreaの作り方を説明してくれてます。こっちのほうがViewsも分離(WebFormViewEngineのパスを変更)出来るし、最初からこの方がいいんじゃないかと思わずにはいられないところです。

とにかくMVCはV2になっても目が離せないですね。

最後に気になる問題がASP.NET Forumsにあがってたので紹介。

MVC2 InvalidOperationException - ASP.NET Forums

ViewへViewDataを型付きで指定して渡すとき、インターフェースを指定して渡す事も出来るんですが、その時に渡されたインスタンスを使ってEditorForで出力しようとすると型が分からないといってInvalidOperationExceptionが発生するという話。解決策としてはダサイけどEditorForに"Object"と固定でテンプレート名を渡すことで、デフォルトテンプレートを参照してくれるようになるんだそうです。リリースノートのKnown Issuesにちゃんと書かれてるけど、解決方法は書かれてないよね。

追記です。今回みたいに複数のMVCプロジェクトをソリューションに追加して実行した場合、アプリケーションのインスタンスがプロジェクト毎に起動して(今回なら3つ)無駄使い感が漂います。なので、以下のようにデバッグ時に起動しないようするとエコなんじゃないかなと思うところです。

area8

2009年8月4日火曜日

LIFE

歌ネットはいつからログインしなくても良くなったんだろう。

キマグレン LIFE [無料]歌詞検索の歌ネット

今朝、この歌の歌詞を口ずさまずにはいられなかったのは、昨日のめざましライブがキマグレンだったからなわけじゃない。

IMG_2501

泣きたくて、笑いたくて...。

いや、まじ、もうメガネかけたまま寝るのはやめようよ。学習しようよ。

話変わって、土曜日、恒例の港南区子供会主催(港南区関係無いのに呼ばれるのはナゼなんだ...)のアイススケートイベントのお手伝い。朝8時から3コマ使って15:30まで氷に乗りっぱなしでした。子供達相手に一緒にスケート滑ったり教えたりするんだけど、ずっと中腰で疲れたっす。でも、ちょこっとホッケーして見せたりして楽しかったよ!

IMG_2495

朝一はすっからかん。

IMG_2497

ちょこっとホッケー体験コーナーもあり。

IMG_2498

全3枠で756人だって。多いよ...。次回は来年2月6日だそうで。もうリンクの予約は入れてるからスケジュール空けといてだってさ。がんばる...。

2009年8月2日日曜日

MVC V2のチラ見

やっと、ため込んだFeedの処理に追いついて、ビデオの確認ができた。

Hanselminutes on 9 - ASP.NET MVC 2 Preview 1 with Phil Haack and Virtual Scott | Scott Hanselman | Channel 9

内容も15分と短いので、是非。

ってことで、このビデオ見つつ少しだけv2のソースも少しだけ確認。Editor/EditorFor(EditorTemplateフォルダ)、Display/DisplayFor(DisplayTemplateフォルダ)がそれぞれあって、なおかつLabelForがFuturesから標準に入ってきてる。ここでTextBoxForを作ろうとして、これは拡張性に問題がありそうだと気がついて、Dynamic Dataで使われてるTemplateベースのレンダリングを参考に拡張方法を変えたのかな。前のFuturesには入ってたモンね、 TextBoxFor。

なので、TemplateHelperがかなり重要なポジションをしめる気がする。さらにModelBinderの時と同じようにDefaultDisplayTemplate/DefaultEditorTemplateを用意して、ある程度は自動テンプレート出力をしてくれる模様。すばらしい。

v2 のリリースノートをチラ見した時には「えぇ~、そっちかよ~!」と思ったけど、中身を見ると素敵かも。ITemplateでのテンプレート処理じゃなくてあくまで、HTMLをベースにascxでのテンプレート処理にこだわることで、ViewStateを取り込まないし、クリーンHTMLをはき出せるしで、 MVCらしさをそのまま引き継いだ上での拡張っす!System.Web.UI.WebControls.DataBoundControlModeがInitializeDataCellDataControlRowStateを使わなくて良くしてくれてるんでしょう。

Scott Hanselman's Computer Zen - Hanselminutes on 9 - ASP.NET MVC 2 Preview 1 Released

↑ここにも書かれてる通り、Preview1ではそれほど大量の機能追加はなくて、Preview2が本気リリースっぽい。なので、V2に関しても順を追って追いかけて行くことで、一度に沢山の機能を調べなくて済む感じです。

DataAnnotationsの取り込みがどの程度のものなのか。その片鱗をこのビデオで垣間見れた気がします。Dynamic Dataと同じくらい取り込もうとしてますね。DataType、DisypayNameにUIHint、それらもしっかりとUIの出力(TemplateHelperとDefaultEditorTemplate)に反映されてる。前まではDataAnnotaionModelBinderを使って、システムに対して入力方向での連携で入力値検証でしか利用してなかったのが、V2からは出力方向にもしっかり活用。なので、Templateベースの出力になってるのもうなずける。

大枠はいつものごとく、ガスリーさんところで書かれてるから、そこで確認。

ASP.NET MVC V2 Preview 1 Released - ScottGu's Blog

まだちゃんと見てないけどね!

すでにフィルさんところでAreaに関する投稿(Single Project Areas With ASP.NET MVC 2 Preview 1)もあるし、Maartenさんとこ(ASP.NET MVC 2 Preview 1 released!)にも簡単な説明が出てるので、これから少しずつ見ていこうと思います。

つか、この週末でちゃんと調べる予定だったのに、全然観れなくてちょっと残念...。

T4MVC再び

世界中でMVC v2祭りな雰囲気の中、少し前にリリースのあったT4MVC 2.4.0.1について。早くMVC祭りに参加したいところだけど、そこは焦らずに少しずつ...。

Angle Bracket Percent : T4MVC 2.4 updates: settings file, sub view folders, ActionName support and more

前回のT4MVCの投稿でActionNameをサポートするようttファイルの書き換えを行ったけど、新しいバージョンではしっかりとその辺も含めた改良が施されてます。なので、もうActionNameで名前を変えたものを指定したいからと、たけはらエディションを使う必要は全く無くなりました。

どうやってActionName属性を取り出すのかなと確認したところ、メソッドのCodeAttribute2を取り出してActionNameAttributeが付いてるかを見てました。ActionMethodInfoが変更かかってるのも合わせて、やり方はだいたい同じですね。間違ってなくてホッとした。変更前のAction名が選択肢に出てくるあたりの仕様も同じだし。

HomeControllerに以下のIndexPostを追加してみる。

    public virtual ActionResult Index()
    {
      ViewData["Message"] = "Welcome to ASP.NET MVC!";

      return View();
    }

    [AcceptVerbs(HttpVerbs.Post)]
    [ActionName("Index")]
    public virtual ActionResult IndexPost(string value)
    {
      ViewData["Message"] = "Welcome to ASP.NET MVC!";

      return View();
    }

このIndexPostを参照するようにIndex.aspxにFORMを書いてみる。

    <% using (Html.BeginForm(MVC.Home.Actions.IndexPost, MVC.Home.Name))
       { %>
       
       <input type="submit" value="送信" />
       
    <% } %>

結果、出力されるHTMLは↓。

    <form action="/" method="post">
       
       <input type="submit" value="送信" />
       
    </form>

それから、既定ではMVCがクラス名だったり、ViewsフォルダやControllersが固定だったけど、今回からT4MVC.settings.t4というファイルで変更出来るようになってます。なので、MVC.Home.~じゃ無くてMy.Home.~とかに変更も可能。サブディレクトリを再帰(なんちゃらRecursive関数達)で潜っていくようになってるので、より実用的に。

Actionの引数をなくしたoverloadを定義してるみたで、上記BeginFormの書き方を以下のように変えてもOKらしい。

    <% using (Html.BeginForm(MVC.Home.IndexPost()))
       { %>
       
       <input type="submit" value="送信" />
       
    <% } %>

だけど、これで出力されるURLがなんかキモイ。

    <form action="/?RouteValues=System.Web.Routing.RouteValueDictionary" method="post">
       
       <input type="submit" value="送信" />
       
    </form>

変なの。と、思って出力されたコードを確認してみたけど、今回のような使い方の場合、上記のようにBegineFormを使うと、標準のHtmlHelper.BeginFormが呼ばれるから変なURLになる。正しくは↓こう。

    <% using (Html.BeginForm(MVC.Home.IndexPost(), FormMethod.Post))
       { %>
       
       <input type="submit" value="送信" />
       
    <% } %>

ちゃんと、FormMethodを指定しましょう。じゃないと、T4MVCで定義してるBeginFormのoverloadに入ってこないもん。こうすれば、ちゃんとURLが出てくるようになりました。にゃろめ。ちなみにルーティング登録時(MapRoute)でもマジックストリングを使わずに登録できるようになってるT4MVC。

最高です。