Japanここで書かれてるコードが↓これ。Console.WriteLine(row.ToShortDateString());}※今年かどうか判定する条件の部分が代入になってるよ~。LINQを使うっていうお題なんだから日付の生成部分もList<DateTime>に生成して入れておく、なんてことをしないで、そこもLINQに含めちゃった方がオシャレ感でると思うよ~。ブログをBloggerに移行します。FeedBurner経由でFeedを購読してる場合は、そのままのでOKです。MVCに関するエントリーは移行しました。その他のエントリーは、移行せずそのままにしておきます。今後、こちらのブログでの更新がメインになります。あと、Tumblrはそのまま継続使用デス。Limitまさか、自分がこの制限に引っかかるとは...。調子に乗って、前ブログからエントリーを移行させるという行為が仇になった。Writer経由でのエントリーが出来ませぬ。Writerで書き込もうとすると...。postsと、悲しいメッセージが出てくる。50件あたりで出てきた気がする...。ブラウザ経由でも、API経由でも出るみたいだから、一気にやるならImport機能のフォーマット似合わせたXMLファイルを作成して、それを取り込むのがいいんだろうね。画像をPicasaに入れてimgタグのsrc書き換えとかゲンナリするし。MVC関係のエントリだけを移行させようと思ってるから手作業でやるさ。Gears面白いエントリー発見。Gearsは最初のリリースの時に少し触ってみた程度で、名前からGoogleが消えたあたりから全く状況を追いかけてないんだけど、このサンプルがかなり面白い。エントリーには2つソリューションがあって、1つはMVCオンリーでもう一つがGears対応版。両方見比べると分かりやすいんだけど、なにせDBファイル込みになってるから少しサイズが大きいのが難点。どっちにも共通して存在してる(デフォルトで作成されるファイルを除く)のが、NoteControllerとそのView達(List/Detail/Edit/Create)。Gears対応版では、Routeにmanifest.jsonへのリクエストに応えるためのルート登録をして(GearsController)、関連jsファイルが含まれててそれをインクルードするためにSite.Masterが少し違うだけ。MVC部に注目してみると、GearsControllerのIndexアクションが~/Contentと~/Scriptsフォルダの全ファイルのURL、それとMVCがViewを返すURL(/Homeや/NoteList)、データ詳細のURLをJsonで返すだけに見える。一体全体どこでデータとViewのHTMLとを分離するコードがあるんだろう。テンプレート的な物が定義されてるんだとばかり思ってたけど、そんなコードが見あたらない。demo_offline.jsはGearsを有効にしたり、無効にしたときのローカルストアの操作と、完全オフラインになったときに編集用リンクを無効にしたり、オフラインかどうかを監視するコードだけっぽい。gears_init.jsはいじらないコードだよね。formやinputのname属性とかを見て自動で判断してくれてるのかな。Gearsの仕様を確認すれば分かることなんだろうけど、まぁ、ねぇ。今はそんなに興味ないって言うか。それにしても、Gearsはずいぶんスゴイ事になってる気がするし、MVCとの連携がこれほどシンプルに出来るのもViewStateとPostBackがないおかげだよね。MVCのDefaultModelBinder(IModelBinder)が汎用的になったかを取り上げましたね。以前の投稿で見事に見逃してたのが「必須入力ではないけど、入力形式の不正メッセージを表示したいな」というところ。日付フィールドがあってモデルのプロパティはDateTimeなら当然日付形式の文字列じゃないとキャスト出来ないから、入力エラー。数値型ならintで当然アルファベットとか勘弁してくれよ、と。必須フィールドならRequire属性でいいですよね。キャストに失敗した場合、何もセットされず型初期値(default(T))が入ったままだから、エラーメッセージに「ちゃんと入力してね(ハート)」って表示すれば。それでも、初期値が数値で0だと困る!って時にはNullable<Int32>とかでnullにしとけば、初期値のまま処理が進んじゃうって事も防げますから。必須じゃない場合に「キャスト出来ませんでした」なんていうシステム固定のメッセージを出すのは、どうなのよ、なんて時があるもん。社内システムとかならそういうモンだから、で済むかもしれないけど、ネットに公開するならそういうメッセージはダサイ。いや、社内システムでもダサイけど、対象ユーザー層を考えれば、それでもまぁいいじゃん、っていうかね。ちなみに、DataAnnotationsを使って、入力検証を実装した以前の実装だと、キャストエラー表示してくれないもんね。ModelStateDictionaryには(モデルを復元したタイミングで)ちゃんとエラーとして入ってるんだけど、ModelErrorクラスのErrorMessageにはメッセージが入って無くて、Exceptionプロパティに例外情報として入ってるから展開されないんです。以前のテストプロジェクトにここで登場してもらいましょう。1箇所変更点として、PersonViewModelクラスのAgeプロパティについてるRequire属性を削除して、Range属性だけにしてみます。クラス定義は以下の通り。}}太字のところですね。これで、入力値に整数以外を入れて、ポストしたときのスクリーンショットが↓これです。ViewがRenderされるときに、ModelStateDictionaryがどうなってるかをブレークポイントをセットして確認してみましょう。クリックすると大きく見れます。Render時には、ModelState内のModelErrorは存在してるけど、ErrorMessageは""空文字で、ExceptionにInvalidOperationExceptionが入ってるのが分かります。このExceptionをエラーメッセージとして表示するなら、そのまま取り出して、ErrorMessageに入れてしまうようなコードを書いてしまえばいいですね。有効な値ではありません。」と、出ちゃうんですよね。Int32って...。そんなこと表示されても普通の人は理解できないし。そもそもどのタイミングでメッセージの取り出し処理をすればいいでしょうね、って展開になります。そこで、登場するのがIModelBinderのオーバーライド出来るメソッド群。これまたオレルールの方のエントリーの一番最後に書いてるIModelBinderのイベント発生順がキーになります。結論から言うと、OnModelUpdatedのタイミング(モデルの復元完了時)に、ModelStateDictionary内のModelErrorに上記例外が含まれてるかチェックしてしまえばいい、という事になります。意味の分かりにくいエントリーになってきてますね~。コードとしてはシンプルに↓こんな感じで動きます。LINQ部がかなり適当...。ないかチェックして、あれば入力エラーメッセージをここでいれる。コレクションには入れたままにしておく。"入力形式の間違った項目があります。}}こんな感じで、DefaultModelBinderを派生させたクラスを作成し、このModelBinderをDefaultBinderにしちゃいます。Global.asaxのApprication_Startの所に以下のコードを追加。{...}って、書きましょう。この状態で、もう一度動かしてみます。今度はちゃんと、ValidationSummary()で表示されるようになりました。今回のコードは無理矢理エラー項目のキーに"__InvalidOperationException__"と入れて、複数のエラーメッセージが出ないようにしてますが、もちろん項目毎に表示してもいいですよね。若干気になるのは、なんでInvalidOperationExceptionを発生させるようにしてるのかな~、というところ。なんとなくだけど、InvalidCastExceptionのほうがシックリ来ないですかね~。MVCに含まれるValueProviderResultクラスのConvertSimpleTypeメソッド。この中でTypeDescriptor.GetConverter()で取得したコンバーターのConvertToを呼び出すところらへん。MVCに関するエントリーだけでも全部こっちに持ってくればいいのかな。今はそれ以外の事を書く事もほとんどないし。MVCのエントリは全部移行しました。NETTUTSまだ、作ったことないっていうかjQuery自体まだ使ったことないってばよ。fnに入れればいいんでしょ?そのくらいしか、知識がないので、ビデオでお勉強。シンプルなプラグインだけど、まずはシンプルな物を理解しないとね!(function($){...})(jQuery);っていうのは基本みたい。jQuery本体を引数に渡して$でショートカット。不思議に思ったのがthisの扱い。Enumerable(っていうのかな)なリストに対して、プラグインを実行すると、プラグイン内でのthisがこのリストを指す。プラグイン内でそのリストをeachで回したときのthisはDOMエレメント(だよね?)。each内では$(this)でjQueryでかぶせて色々便利になるようにしないといけない。hoverに渡すfunctionがmouseenterとmouseoutの両方なのが素敵な感じがする。ビデオ中ではmouseoutの時に$(‘tooltip’).hide()って書いてるけど、これじゃ、無限に同じIDのtooltipが出来ちゃうからダメじゃん!と思ってたけど、デモで使ってるコード(ブログエントリの最後のコードも)ではちゃんとremove()になってる。前もそうだったけど、ここで取り上げるビデオな何かしら引っかけがあるよね。thisでエレメントのリストをそのまま返すあたりも、jQuery流なのかな。これしないと、"."で区切って続けていろいろ出来ないもんね。この例だと、fnに単一のfunction(内部では無名関数使ってるけど)を入れてるだけの、シンプルな物だけどもっと大きなプラグインを作る時にはどうするか気になる。そこはすでに公開されてる他のプラグインをいくらでも参照すればいいから、さぁ、作ってみよう!って言うときにはそれほど問題にならないよね、きっと。jQuery2009年2月19日木曜日AreasサンプルがRCに対応Philさんすげーよ。あんたやっぱり最高だよ。RCに対応させたAreasのコードがアップロードされてる。MVCRouteCollectionの簡単登録ヘルパーと、Viewの位置を解決させるためだけのカスタムViewEngine。何でこれだけで出来るのか不思議だ。コントローラのパスだってデフォルトの名前空間だって違うのに、ControllerFactoryを作ることなく出来るんだよ。いつだったか忘れた(ベータだっけな~?もっと前?)けど、ルーティングのDataTokensにNamespacesを入れとけば、コントローラのNamespaceに自動で入れてくれるっていう仕様になったような。気になったらとめられない。RCのソースをチェック。ControllerFactoryあたりだろう。