2009年4月13日月曜日

ASP.NET MVCをMonoで動かしてみる

長い戦いだった...。現時点での結論から言えばそれなりに動くけど、型付きViewPageだけはどうにもならない感じでしょうか。

そもそもMonoでASP.NET MVCを動かすことにどれほどの意味があるのかという所だけど、これは凄く意味のあることですよね。なんせ実行環境はすべてオープンソースで構築できるんだから。こうなってしまえば個人的にはJavaに何もメリットを感じない。Google App Engineが羨ましいくらいか。でもPythonあるし、そもそもAzureがあるし。

構築した環境はVista Ultimate 32bitにVMWare Server 1.0.9を入れ(2.0.1だとどうも上手く動かなかった)、Linuxディストリビューション(っていうの?)はCentOS 5.3openSUSE 11.1、Mono 2.4とMonoDevelop 2.0、データベースにMySQL 5.0.45(CentOS上にyum install)。

My Adventures Installing mono 2.0 on CentOS 4 to work with apache via mod_mono « Pale Musings

Linuxを生まれて初めて触ってみたけど、さっぱりチンプンカンプンですね。でも、ネットで検索すればいくらでも情報が出てくるから、とりあえず動かすくらいならどうとでもなるもんです。ちゃんとまともに運用環境を作るにはかなり難しそうな気がするけどね。

何でCentOSとopenSUSEを入れたかたというと、MonoDevelopをCentOSにインストールするのに3日がんばったけどできなかったから。GLibのバージョンが入ってるのじゃダメと言われ、ソースコンパイルからやってみたけど、芋ずる式にアレもコレもダメだと言われ、コンパイルできてmake installで実行しても、Gtk+からちゃんと新しいのが見えないと言われ...。うぎゃ~!!となってやめました。Monoはすんなり入るのにね。で、一番簡単なのはNovellが出してるディストリビューションを使う事だと思って、openSUSEも入れることにしたんです。まぁ一緒だろと思ったらyumじゃなくてzypper(ソフトウエア管理のコマンドライン比較 – openSUSE)だとかよくわかんないことに時間を取られたものの、流石Novellなだけあってワンクリックでインストールもあっという間に完了。

mono1 mono2

MonoDevelopでASP.NET MVCのプロジェクトを新規作成したところ、流石にテンプレートは空っぽでControllerもViewも何もない状態でした。T4無いしね(たぶん)。なので、簡単にControllerとViewを作って動かしてみると、あら素敵。アッサリ動いた。簡単なものだけど、動くとビックリ。スゴイね~。んじゃ、ってことで、コレをCentOSの方にコピーしよと思ってハタと手が止まる。あれ?こういう時ってFTP?それともSSHっていう何かよくわかんないシェル?ふぬ~。あ、産婆。じゃなくてsamba。

Windowsファイルサーバー構築(Samba) - CentOSで自宅サーバー構築

これをCentOSとoenSUSE両方で起動してコピペ。ちなみにVMWareで動かしてるときにopenSUSEは何もしなくてもマウスが動くしGNOME端末での日本語入力もできるのに、CentOSはなんかやらなきゃいけないみたいで。VMWare toolsっていうんですかね。よくわかんないけど、さんざんやって上手く出来なかったから諦めた。いいもん。毎回Alt+Ctrl押すもん。

とりあえず、MonoDevelopだとVisual Studioに慣れた体では開発しにくいし、どうせ動かすのはCentOSだしってことで、ここヵらはCentOSにデプロイ、Vista+VSで開発に戻ります。openSUSEで動かしてもいいんだけどさ~。なんとなくきかん坊が気になるからさ~。

mono3

VSで作ったデフォルトのプロジェクトをそのままの状態でビルド>発行して、CentOSにコピー。んで、Apacheで動かすためにmod_monoの設定をしようかなってところで、XSPっていうのが簡易Webサーバーの役割を果たしてくれるということなんで、コピーしたフォルダをカレントに"xsp2"!アッサリ動くの図↑。

続いてMembershipを使いたいから、データベースを入れなきゃいけないよね。なのでMySQL。入れるのは簡単。とにかくyumさん。なんだこいつ、スゴイヤツだ。sudoさんと仲がいいのか?最初はsuで切り替えてやってたけど、普通のユーザーアカウントで読み取れないフォルダがばかばかできちゃって面倒なことになったから、結局何度もやり直して須藤さんsudo(SuperUser DO?)に任せる事に。

でもって、MembershipProviderがなんかあるはず。

MySQL :: MySQL 5.1 リファレンスマニュアル :: 24.2.2.2 Mono を使用した Unix に Connector/NET をインストールする

あるのね...。Connector/Netと言われても...。GACに登録したいけど、インストールパスってどこなんでしょう。そもそもどこにインストールされてるのかが分からない。"/usr/lib/mono/2.0"にいろいろ入ってみたいだけどここでいいのかな...。とりあえずコピーしてgacutilでグローバルアセンブリキャッシュに入れて見る。エラーは出てないからいいのかな。

んで"nolan bailey's blog: MySQL ASP.NET Membership and Role Provider"や”knowledge shared is knowledge²: ASP.NET and MySQL - membership provider (part 1)”ここに書かれてるようにweb.configをセット。autogenerateschema=”true”にしておくと勝手にテーブルを準備してくれるからaspnet_regsqlやInstallMembership.sqlをどうのこうの気にしなくてもいいから楽ちんです。忘れずにセットしなきゃね。

mono4

うほほ。ちゃんとデータベースに登録されました。

でも、本当はここが最初ちゃんと動かなくて、あれれな感じだったのがプロジェクトのアセンブリに追加したMySql.Webをローカルコピーしとくようにしたらなんとなく先に進むようになるものの、そこからさらにエラーでなんとも動かなくて。

mono5 mono6

ユーザー登録はできたのに、ログインでエラーになるの図。これはなんだも。

System.ArgumentNullException: Argument cannot be null.
Parameter name: type
 at System.ComponentModel.TypeDescriptor.GetConverter (System.Type type) [0x00000]
 at System.Web.Mvc.DefaultModelBinder.BindModel (System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext) [0x00000]
 at System.Web.Mvc.ControllerActionInvoker.GetParameterValue (System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ParameterDescriptor parameterDescriptor) [0x00000]
 at System.Web.Mvc.ControllerActionInvoker.GetParameterValues (System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ActionDescriptor actionDescriptor) [0x00000]
 at System.Web.Mvc.ControllerActionInvoker.InvokeAction (System.Web.Mvc.ControllerContext controllerContext, System.String actionName) [0x00000] 
なんでこんなエラーが...。全然ダメじゃないか。いろいろ検索してみたら同じ現象が起きてる人もいて。

http://go-mono.com/forums/#nabble-to23006435

特に返信もなくて途方に暮れかかったけど、Forumあるならスレッド見ていけばなにかヒントがあるかもと、見ていくと、↓こんな書き込みがありました。

http://go-mono.com/forums/#nabble-to22854337

Windowsで使ってるアセンブリをローカルコピーしとけと。なるほど。確かにバイナリ互換なMonoなんだからそういう手もありだ。System.Web.Mvc.dllをコピーして動かす。

mono7

拡大すると見えるけど、ちゃんとログインできてますね。グレート!

あとはLINQでデータベースにアクセスできれば普通に開発できる。でも、最初に書いたとおり型付きViewPageだけは今のところ解決策が見つからずなので、当面はコードビハインド指定で乗り切ることになるのかな。そんなこんなでここまで5日ほどかかったけど、面白い発見もいろいろあって実行環境としてLinuxも選択肢に入れていこうと思ったり思わなかったり(EC2もWindows Server+SQLServerよりもLinux+Mono+MySQLの方が同じインスタンスでも安く運用できるからね)。