こんにちは。以前からやってみたかったMacでのASP.NETをやってみました。 というか先週くらいにやって、つまづいたりハマったりしてたので時間かかりました。
結論から言うと、やはりWindowsのVisual Studio様は素晴らしいということに尽きます。 あんなに至れり尽くせりなのにMacでやろうというのはどうかと思います。 でも、できたらMacでもやってみたいじゃないですか。
レガシーのASP(Active Server Pageと呼ばれてたやつですね)は10数年前に経験してて、.Netになってからはその時の辛さを思い出して手を出していませんでした。 もちろんASP.NETのFormなんかは情報として仕入れてましたが…
また、MVCというのもrailsかじったくらいでしかなくて、本当に理解してるかと言われると怪しいです。 いまいちどういう仕組みで実現してるのかなんてことはrailsのソースなんかも読んでないですし、rubyの黒魔術を駆使して作られてるとかいうことだったので敬遠してた気がします。 バージョン3くらいからRackアプリになったので、なんとなくレベルの理解です。
ということで、いきなりMVCじゃなくても良さそうなのですがやってみました。
どうやるかはまったくわからないので、Windowsのときとは違ってGetting Startみたいなものを探しました。 すると公式にあるのでそれを順にやっていきました。
Installing ASP.NET 5 On Mac OS X — ASP.NET documentation
https://docs.asp.net/en/latest/getting-started/installing-on-mac.html
こちらを参考にしますと、コマンドラインからのインストールということであります。 順番としては
Visual Studio Codeをインストールする
ASP.NET5 for Macをインストールする
という段取りですすめていきます。 わたしは1と2はすでに導入済みだったので3からでした。
monoはHomebrewから導入するのが便利だと思います。 Visual Studio Codeは以下からダウンロードしてインストールですね。
Download Visual Studio Code - Mac OS X, Linux, Windows
https://code.visualstudio.com/download
さて、では本題のASP.NETですがHomebrewなんかと同じような導入の仕方のようです。
curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh
これで意味がわからないかもしれませんが.Netのランタイムを切り替えするためのDNVMというツールが導入できます。 Dot Net Version Manager だそうです。なんじゃそりゃ。rbenvとかSDKMAN!みたいなものですかね。 これはあくまでもバージョン管理ツールで、ASP.NETはまだこれからです。
次にランタイムとしてDNX(Dot Net Execution environment)を導入していきます。 これはさきほど導入したDNVMを利用していきます。
installではなくupgradeなのがちょっと気持ち悪いですが、これでサクッと入ります。
そうしたら次はMonoのDNXです。 なぜ両方必要なのかは後ほど嫌という程効いてきます。
これで導入できます。この実行にはmonoが導入されている必要があります。
導入したDNXの一覧は以下のコマンドで見る事ができます。
じゃあ、と思うところですが、まだまだ先があります。 次はプロジェクトの雛形作成のためにYeomanを導入します。
Yeomanということは…そうです。node.jsが必要です。 わたしは電子書籍制作のために導入済みなので必要なパッケージ導入からでした。
まずはYeoman、Bower、Grunt、Gulpなどを入れていきます。
npm install -g yo bower grunt-cli gulp
そしてASP.NETの雛形を作成するパッケージを入れます。
npm install -g generator-aspnet
まずはプロジェクトの雛形をYeomanに作ってもらいます。 プロジェクトフォルダをつくりたいところへ移動して、次のように実行します。
今回は認証機能なしのWeb Applicationにしてみます。 ご覧いただくとわかるとおり、コンソールアプリも作成できるようです。 プロジェクト名を聞かれるので、適当に入力して実行するとサクッとプロジェクト雛形が作成されます。
いやー便利。 そして作成完了したところへそっと書いてくれているのが、次の内容を実行しましょうというものです。
cd MyWebApp dnu restore dnu build dnx web
実際このとおり実行します。 最初は「dnu restore」が時間かかりますが、2度目以降は早いです。 なお、デフォルトでは「yo aspnet」はGulpを利用します。 Grunt派の方は「--grunt」とオプションをつけるとよいそうです。
ということで「dnx web」を実行すると「http://localhost:5000」へブラウザアクセスすればすでに雛形アプリの状態で表示されます。 Windowsに比べたらどっちが早いかなーと思いますが、yo aspnetからだけを見れば誤差かもしれません。 Visual Studioでやっても裏で同じことが起きてますからね。
ところで、.Net CoreのDNXでビルドしてしまった方はビルドに失敗すると思います。
いまのところビルドにはまだmonoが必要ということです。 ですからdnvm listしてcoreclrに「*」がついてる場合は以下を実行してmonoのDNXへ切り替えてから実行しましょう。
dnvm use -r mono [dnvm listででてくるバージョン]
はい、もう動いてますね。ここまでは便利。ここまでは。
コントローラやビューについてはyo aspnetにサブジェネレータが搭載されているのでそこから作成することができます。
yo aspnet:MvcController PostsController
これでプロジェクトフォルダ内のControllersフォルダへ「PostsController.cs」が作成されます。
yo aspnet:MvcView PostsView
これで実行したカレントフォルダ内に「PostsView.cshtml」ファイルが作成されます。 Viewsフォルダには入りません。またさらにフォルダを用意してまとめたい場合には手動で作成、移動が必要です。
モデルに関してはMVC専用のサブジェネレータがないようで、クラス作成のサブジェネレータを使います。
これで実行したカレントフォルダに「Post.cs」が作成されます。 Modelsフォルダは雛形にありませんので自分で作成して移動するようにします。
さらにDbContextクラスを継承したクラスファイルはサブジェネレータがありません。 自分で記述していきます。
そういうことで、つくっていって「あー、そうなるね」というのをやってみていたんですが、いくつかハマってしまいました。
まずbowerをつかって静的コンテンツ用のライブラリを導入したのですが、いきなりビルドできなくなってしまいました。
調べてみると次のIssueに当たりました。どうやらこれのようです。
Can't return a View on OSX when npm or bower packages have been installed #2348
https://github.com/aspnet/Mvc/issues/2348
利用していたmonoのバージョンが古かったようで(この時点では4.2.1でした)、バージョンを上げると解消しました。
EntityFrameworkのmigrationが失敗する
次にハマったのはEntityFrameworkの利用です。 どうあがいても利用できませんでした。 しかしよくよく調べてみると、これは.Net CoreのDNXで実行する必要があるようです。 そこでDNXを切り替えてみると動作するようになりました。
なおEntityFrameworkを利用するにはWindowsではPowerShellから導入できますが、Macではproject.jsonの「dependencies」へ以下を追記するようになります。 バージョンはNuGetで検索して確認してみてください。
"EntityFramework.Sqlite": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final"
また、コマンドとして利用できるように同じくproject.jsonの「commands」へ以下のようにefを追記します。
"commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" },
これでEntityFrameworkを利用することができます(.Net CoreのDNXならね)。
dnx ef migrations add Initial dnx ef database update
SQLiteのファイルがプロジェクト内に作成されるはず。
ここでホッとして気をぬくと、ブラウザからお目当のコントローラへアクセスするとエラーがでまくります。 自分で作成したDbContextが見つからない、といった内容です。 それはそうです。次の作業が抜けているからです。
DbContextを紐付けするのは「Startup.cs」の「ConfigureServices」メソッド内に記述することでできます。 こちらにもがっつり記述されています。
ASP.NET 5 Application to New Database — Entity Framework 7.0.0 documentation
https://docs.efproject.net/en/latest/platforms/aspnetcore/new-db.html
手元ではSQLiteを利用するので次のような感じになります。
public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddEntityFramework() .AddSqlite() .AddDbContext<MyBlogContext>(); services.AddMvc(); }
ここでいう「MyBlogContext」がDbContextを継承したクラスです。
もちろんusingで以下を加えておく必要があります。
実はまだCRUDつくってみて「ふーん」という段階ですので慣れるまでもう少しかかりそうな気がしますがEntityFrameworkがDNX切り替えなしでビルドと両立するようになるといいですね。 テキストエディタとしてはVisual Studio Codeで十分な気がしなくはありません。 もっと込み入ったことをやりはじめると「ぐぬぅ」となるのかもしれませんが、現時点ではわかりません。
それでもまだまだ改良が進められているので楽しみではあります。