読者です 読者をやめる 読者になる 読者になる

きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

WebMatrix(ASP.NET WebPages)でDapperを使う

dapper WebMatrix ASP.NET Razor

.NET用のMicro-ORMであるDapper dot net (Daper.NET)は、WebMatrixでも利用する事が出来ます。

WebMatrixには元々簡易ORM的な機能を持ったDatabaseクラス (WebMatrix.Data.Database) が標準で用意されています。しかし、自分で用意したクラスにマッピングすることはできませんし、明示的にトランザクションを使用したい場合も利用できません*1

もしDatabaseクラスに物足りなくなったら、次の選択肢としてはDapperがお勧めです。

導入方法等をを軽く紹介してみたいと思います。

 

WebMatrixでDapperを使う手順

1.NuGetでDapper dot netをインストール

NuGetギャラリーを「dapper」で検索し、Dapper dot netを探してインストールしてください。WebMatrix向けパッケージとしても公開されていますので、そのまま検索すれば出てきます。

f:id:kiyokura:20131028024105p:plain

[インストールする]をクリックした後、いくつかライセンスや確認画面が出てきますので、画面の指示に従い操作してください。さくっと入ると思います。

 

2.usingする(Importsする)

Dapperの主な機能は拡張メソッドで提供されていますので、利用する場合はそのソースコードの先頭でusing(VB.NETの場合はImports)されている必要があります。Razorの場合は、「@uging(VB.NETの場合は@Imports)」という構文を使います。

Razor(C#)でのDapperのusing

以上で利用準備は終了です。

 

dapperを使ったサンプル

最後に、少しだけDapperを使ったサンプルを。今回DBはSQL Server CEを利用したサンプルコードになっていますが。SQL ServerMySQLの場合でもほぼ同じように利用できます*2

1.Database.Queryと同じように使う場合

Database.Queryと同じように、dynamicで結果を受ける場合はこんな感じでいけます。 RazorでのDapperサンプル(dynamicで受け取る場合)

 

2.クラスにマッピングする場合

あらかじめ用意したクラスにマッピングする場合はこんな感じです。マッピング先のクラスUserEntityは、今回は@functionsを使ってインナークラスとして定義しましたが、もちろん別ファイルにしてApp_Codeフォルダ内に配置してもかまいません。 RazorでのDapperサンプル(用意した型で受け取る場合)

こうしてやれば、利用箇所では当然、コード補完が効くようになります。これもメリットですね。

f:id:kiyokura:20131028024133p:plain

 

3.トランザクションを使ったUpdate文を実行する場合

最後に、トランザクションを使いつつUpdateするサンプルです。 RazorでのDapperサンプル(トランザクション使ってUpdate)

 

まとめ

いかがでしたでしょうか。 単純に利用するだけなら使用感はDatabaseとさほど変わらないように思いますし、"ちょっとだけ込み入った"事をしたい場合も"ちょっとだけ手間を増やす"事で比較的シンプルさを保ったまま対応できると思います。

ASP.NET WebPagesでどこまでヤヤコシイことをやるか?』という話はあるかもしれません。しかし、更新系で少し込み入ったことをやろうとすれば、トランザクションの処理が必要になる局面は少なくないように思います。そんな時、選択肢の一つとして考えてみてはいかがでしょうか。

Dapper自体について知りたい方は、Dapper dot netの公式サイトを見ていただくか、概要レベルであればこちらのスライド『ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた』もよければご覧になってください。

*1:DataBase.ConnectionプロパティはSystem.Data.Common.DbConnectionなので一見使えそうですが、DataBase.Query()メソッド等がDbTransactionを考慮しない。結果的に生ADO.NETでやるのと同じになる。

*2:Connectionオブジェクトさえ作ってしまえばほぼ同じ。パラメタライズドクエリのバインド変数の書き方がDBごとに違う場合があるくらいだと思います。

WebSecurityクラスを理解する:(3)サンプル実装を追ってみる-その2

Razor

今回はいよいよサンプルのコードを追ってみます。

ただし、単にソースを追いかけても面白く無いと思います。...ので、この「スターターサイト」テンプレートに対して、ちょっとだけ仕様を追加・変更する事を例に挙げながら、やってみようと思います。

「スターターサイト」に対して追加・変更する仕様

  • ログイン時に利用するIDを、メールアドレス無く英数字からなる一意の「ログインID」とする
    • メールアドレスも保持する
  • ユーザ情報として、氏名と年齢の入力を受け付ける
  • ログインIDは変更させないが、その他の氏名、年齢、メールアドレスは変更可能にする
  • 情報を格納するファイル名を「StarterSite.sdf」ではなく「MySite.sdf」とする
  • ユーザ情報を格納するテーブル名は「UserInfo」とする

情報の粒度が若干アレですが、とりあえずは上記を実装することを目標にしたいと思います。

1:第一歩、WebSecurityの初期化コード

WebSecurityクラスに関わるまず最初の一歩は、「_AppStart.cshtml」から始まります。

ASP.NET Web Pagesにおいて先頭が「_(アンダースコア)」から始まるファイルはちょっと特殊なファイルという扱いになっています。例えばブラウザから直接アクセスしても、表示することができません。
それらのうち、「_AppStart.cshtml」という名前のファイルはさらに特別扱いされていて、『ブラウザからいかなるファイルにアクセスがあった際にも必ず最初に実行される』という性質があります。

例えば「~/Default.cshtml」というファイルがあって、ブラウザから「http://localhost/Default.cshtml」とアクセスしたときにでも、まず先に暗黙で_AppStart.cshtmlが先に呼び出されてからDefault.cshtmlが呼び出される、という動きになります。
すなわち、この_AppStart.cshtmlに書かれているコードは必ず最初に実行される、という事になります。



ではこのファイルを開いて中を見てみましょう。左のファイル一覧から_AppStart.cshtmlをダブルクリックすると、開くことができます。
すると、

  • @{}で囲まれたコードブロックが一つある
  • コードブロックの一行目に「WebSecurity.InitializeDatabaseConnection」の記述がある
  • 2行目から、WebMailクラスを使った記述が書かれ、コメントアウトされている

事が見て取れると思います。

もちろん、注目するのはWebSecurity.InitializeDatabaseConnectionの行です。

WebSecurity.InitializeDatabaseConnection("StarterSite", "UserProfile", "UserId", "Email", true);

こんな風に書いてあると思います。


ここで、WebSecurity.InitializeDatabaseConnectionのリファレンスを見てみましょう。
WebSecurity.InitializeDatabaseConnection Method (WebMatrix.WebData)


引数の個数が違うオーバーロードがありますが、とりあえず一つ目(引数の数が少ない方)を見てみてください。
せっかくですので引数の意味を一つ一つ見ていきましょう。こっちです。
WebSecurity.InitializeDatabaseConnection Method (String, String, String, String, Boolean) (WebMatrix.WebData)

  • 第1引数:connectionStringName(接続文字列)

文字通り、データベースの接続文字列を指定します。
SQL Server CEの場合は、拡張子抜きのファイル名で指定します。
SQL Server等のデータベースを使う場合は、Web.ConfigのconnectionStringsセクションに記述した接続情報を指定するNameを書きます。

今回のサンプルコードを見てみると、"StarterSite"と書いてあります。前回確認した通りこのサンプルが規定で持っているSQLCEのファイル名は"StarterSite.sdf"ですので、ここではこのSQLCEのファイルを指定していることがわかります。

  • 第2引数:userTableName(ユーザテーブル名)

これも文字通りユーザ情報を格納するテーブル名を指定します。
サンプルコードには"UserProfile"と書いてありますね。これも前回確認した、ユーザ情報が格納されていうテーブルと一致していると思います。ユーザ情報を格納するテーブル名を変更する(した)場合は、ここも変更する必要があります。

  • 第3引数:userIdColumn(ユーザID格納カラム名

第2引数で指定したテーブルにて、ユーザIDを格納するカラムの名前を指定します。ここで指定されたカラムに格納される値は、webpages_Membership等関連テーブルとのリレーションのキーになりますし、WebSecurityクラスの各種プロパティやメソッドで「UserID」として利用されます。(たとえば、CurrentUserIdプロパティ等)。変更することでユーザIDとして使用するカラムの名前を変更することができますが、型はintである必要があります。

  • 第4引数:userNameColumn(ユーザ名称格納カラム名

第3引数と同様、ユーザ名として利用されるカラムの名称を指定します。ここで指定されたカラムに格納される値はWebSecurityクラスの各種メンバで、UserNameとして利用されます。通常、ログインIDとして利用されたりします。

  • 第5引数:autoCreateTables(ユーザテーブル名)

最後の引数は、自動的にユーザテーブルを作成するかどうかです。trueを指定すると、同名のテーブルがデータベースに存在していない場合に自動作成されます。なお作成されるのは第2引数で指定された名称のユーザーテーブルだけではなく、webpages_Membership等のwebpages_*のテーブルについても同様です。ただし、trueを指定した場合でも「データベース自身」は自動作成されません。データべース自体はいかなる場合でもあらかじめ作成しておく必要があります。




以上で、引数の役割が理解できたと思います。割と単純だったのではないでしょうか?これが理解できると、先に挙げた今回試みる予定の仕様変更についても、いくつかここでやっておく必要があることに気が付くかもしれません。


…が、今はとりあえずここまでにして、もうちょっとだけ先に進みます。


ちなみに、今回触れなかった、引数が一つ多いオーバーロードについては、以前に日記で触れていますのでそちらも参照してください。

WebMatrix.Data.StronglyTypedとな!?

Razor

※シリーズ(?)の途中というかまだ始まってもない感じですが、ちょっと別の話題です。忘れないうちのメモです。

@ishisaka さんのtweetで知ったのですが、上記のとおり、WebMatrix.Data.StronglyTyped なるものがあるとか。

https://github.com/JeremySkinner/WebMatrix.Data.StronglyTyped/tree/master/src/WebMatrix.Data.StronglyTyped

名前からもご想像に難くないとも追いますが、以下の通り、WebMatrix.Data.Databaseでクエリを投げたときに、型付けされたオブジェクトに反してくれるとう素敵ライブラリのようです。
http://www.jeremyskinner.co.uk/2011/01/24/strongly-typed-data-access-with-webmatrix-data/ から抜粋すると、

public class User {
  public int Id { get; set; }
  public string Surname { get; set; }
  public string Forename { get; set; }
  public string FullName {
    get { return Surname + ", " + Forename; }
  }
}

こんな風にエンティティクラスを作っておいて、

using(var db = Database.Open("MyDatabase")) {
   var users = db.Query<User>("select Id, Surname, Forename from Users");
   foreach(var user in users) {
     Console.WriteLine(user.FullName);
   }
}

という感じで使えるみたい。


で、Nugetのパッケージも公開されてるようですので、さっそく使ってみました
http://nuget.org/packages/WebMatrix.Data.StronglyTyped




これはなかなか素敵!!

WebSecurityクラスを理解する:(2)サンプル実装を追ってみる-その1

Razor

とりあえず、どんな機能があって、どういう風に実装していくのか、サンプルコードをベースに見ていきましょう。

今回は、実際に細かくソースを見ていく前の下準備をしたいと思います。

具体的には、

  • Web Matrixのインストール
  • 「スターターサイト」テンプレートの展開
  • 「スターターサイト」テンプレートの構成の確認
  • ちょっとした動作確認

という具合に、順をおってやっていきたいと思います。

1:WebMatrixのインストール

今回は、せっかくなので(?)Web Matrixでやってみたいと思います。Web Matrixとは、Microsoftがリリースしている無償のWebアプリケーション開発環境です。

http://www.microsoft.com/web/webmatrix/
上記サイトにアクセスして、「今すぐダウンロード」をクリックして下さい。

※サイトデザインが変わったりして、変更されている場合もあるかと思いますが、そんな感じのボタンかリンクを探してみてください。



そうすると今度は「Web Platform Installer」(移行、WebPIと省略)というツールがダウンロード・実行されます。

このWebPIから、WebMatrixをインストールすることになります。

ボタンを数回クリックするだけでインストールされますので、そのまま進めて行けばインストールが完了します。


WebMatrixのセットアップについては、以下などが参考になると思います。
http://www.forest.impress.co.jp/docs/special/20110901_473168.html
WebMatrixそのものの解説や、WebPIについての簡単な解説もありますので、ぜひ、ご覧になることをお奨めします。


またVisual Studioや無償版のVisual Web Developerでやりたい方も、以降についてははっきり言ってほとんど同じです。コードなどについてもほぼそのまま読んでいただけると思います*1。が、もしまだ使ったことがなえれば、ぜひWeb Matrixも試してみてください。

2:サンプルコードの準備

では、WebMatrixでサンプルコードを展開してみましょう。

WebMatrixを起動してクイックスタート画面が表示されたら、その中にある「テンプレートからサイトを作成する」をクリックしてください。

テンプレートがいくつか並んだ画面が表示されますので、そのなかから「スターターサイト」を選んでください。ちなみに下記画面のように[スターターサ...]と表示される場合は、一方が日本語版でもう一方が英語版です。

今回のは正直どちらでも変わらないのですが、右側が日本語なので、日本語が良い場合はそちらを選んでください。サイト名を変更したい場合は入力し、OKボタンを押してください。




テンプレートの展開が終わったら、こんな感じで画面が表示されると思います。

3:サンプルサイトの構造

実行する前に、サンプルサイトの構造をちょっと見てみましょう。

WebMatrixの左のメニューから、Fileをクリックしてください。

これですね。

すると、左側にファイルビューが展開されます。フォルダをすべて展開すると、こんな感じです。

これが、このスターターサイトに含まれている全てのファイルになります。

「Account」フォルダの下にそれっぽい名前のファイルが沢山ありますが、お察しの通りログインやユーザ登録などの機能はここにサンプルとして実装されています。…というよりむしろ、ユーザ登録周りしか無いサンプルと言っても差し支えないでしょう*2


また、「App_Data」フォルダのはいかにも注目してください。StarterSite.sdfというのがあります。この拡張子sdfというファイルは、SQL Server Compact Edition(以下SQLCE)用のデータベースファイルです。SQLCEは軽量のSQLデータベースエンジンで、SQL ServerMySQLなどのようにサーバ(サービス)を必要とせず、アプリケーションに組み込む形で利用できるものです。2012年1月現在の最新版であるVer4.0から、ASP.NETのアプリケーションでも利用できるようになりました。このASP.NET Web Pagesでも利用できます。


ついでに、このStarterSite.sdfに何が入っているかも見ておきましょう。WebMatrixには、SQLCEのファイルの中身のテーブルをGUIで操作する機能があります。
左のメニューから、[データベース]を選択してください。

ツリー形式でStarterSite.sdfが表示されるので、▲マークをどんどんクリックしてドリルダウンしてみてください。

テーブルが4つあるのがわかると思います、このうち、上の二つ「UserProfile」と「webpages_Membership」が、今回の対象となるWebSecurityクラスが関係するものになります。

残り二つも全く無関係ではないのですが、名前のとおりRole(役割)に関するもので、直接WebSecurityクラスの持つ機能とは関係ありません。これらについてもいつか機会があれば取り上げたいと思いますが、気になる方はこちらのドキュメントなどを参照してください。


ちなみに、Wisual Studioでやった場合は、App_Code配下のDBファイルがSQL Server用のDBファイル「StarterSite.mdf」になっていますが、それ以外はたぶん同じと思います。

4:ちょっと触ってみよう

実際にコードを見ていく前に、少し動作を確認してみましょう。WebMatrixの上部のリボンにある、「実行」ボタンをクリックしてください。ブラウザーが起動し以下のような画面が表示されると思います。


実行した画面の右上に注目すると、[登録]と[ログイン]というリンクがありますね。せっかくなので、ユーザを登録してログインしてみましょう。

右上のリンク[登録]をクリックしてください。
下記のような、ユーザ―登録画面が表示されました。

ログインIDとしてのメールアドレスとパスワードを入力して登録するだけのとても単純な登録画面です(下の方にCAPTCHAの記述とかありますが、とりあえず無視してください)。


では早速、登録してみましょう。適当に入力して、登録をクリックしてください。入力にエラーが無ければ登録完了し、ログインされた状態でトップページに戻ってきた状態になっていると思います。

右上を見ると、さっきと様子が変わっていて[へようこそ <メールアドレス>][ログアウト]となっていて、ログイン状態にあることが解ります*3

この状態で[へようこそ <メールアドレス>]の部分をクリックするとパスワード変更機能が利用できますし、[ログアウト]をクリックするとログアウトします。もちろん、再度ログインすることも可能です。色々と操作してみてください。



サンプルで実装されている基本的なユーザ登録やログインの操作のうち、ごくごく基本の部分の動きや機能なこんな感じです。

まとめ

今回は

  • Web Matrixのインストール
  • 「スターターサイト」テンプレートの展開
  • 「スターターサイト」テンプレートの構成の確認
  • ちょっとした動作確認

をやってみました。

いよいよ次回から、この基本の動きをソースコードから追いつつ、さらに少しカスタマイズも行いながらWebSecurityクラスを理解していきたいと思います。

*1:Visual Studio/Visual Web Developerの場合の導入方法などは、こちらを参照。http://msdn.microsoft.com/ja-jp/asp.net/hh180212

*2:まあサンプルというか、テンプレートですので。

*3:『へようこそ<メールアドレス>』となっているのはきっと、Welcome hogehogeという英語のを直訳して語順を直さなかったというおちゃめさんだと思います

WebSecurityクラスを理解する:[1]WebSedurityクラスとは?

Razor

Blogにもぽつぽつと投稿していますが、ここ最近、ASP.NET Web Pagesをよく触っています。

このASP.NET Web Pages『カジュアルなWebアプリケーションフレームワークとしてはよくできているなー』というのが、ここ最近触ってみての改めての感想です。


その一端に、WebSecurityクラスによるユーザ認証機能があります。
とても簡単にログイン認証やユーザー登録などの機能を自分のアプリケーションに実装することが出来るような機能を提供するもので、WebMatrixの「スターターサイト」やVisual Studioの「ASP.NET Webページ(Razor)」テンプレートで展開されるサンプル実装でもこれが使われています。


このしばらく、このサンプルをいじりまわしながらカスタマイズしたり機能を調べたりしていましたので、せっかくなのでその調べた事をここでシェアしてみたいと思います。

WebSecurityクラスの概要

まずは、MSDNのリファレンスを見てみましょう。
http://msdn.microsoft.com/en-us/library/webmatrix.webdata.websecurity%28v=vs.99%29.aspx


まず、メンバが列挙されています。
そんなに数が無く、比較的シンプルそうなのが解ります。そんなに数が無い…とはいえ、一つ一つメンバを列挙して解説するのも面白くないし面倒なので、これらは後々触れることにします。

とりあずぱっと見て目につくのは、WebSecurityクラスのメンバすべてstatic(VBでいえばShared)なメンバであることでしょうか。C#でいうと、WebSecurityクラス自体がstaticです。



次にRemarkを見ると…ASP.NET Web Pagesのリファレンスには珍しく、結構な文章量があります。
しばらくは邦訳されそうにない気がするので*1、ざっくり目を通してみると概ね以下のようなことが読み取れます。

  • 機能を絞って実装され非常にシンプルだけど最低限必要な機能が用意されているものであること
  • セキュリティも意識された実装になっていること
    • クリアテキストでパスワードを保持するオプションは無い
    • ログイン失敗が続くと自動的にアカウントを一定時間ロックする昨日があること…など。
  • ややこしい手順を踏まなくても、ちょっとした拡張が容易に出来る事、既存のユーザ情報テーブルなどとの親和性も高いこと
    • ユーザの一意IDやEmail、その他の任意のユーザの情報(氏名等の追加の属性)と、パスワードや管理のための情報を分割して管理する仕組みになっていること
    • IDをキーにして既存のユーザー情報テーブルと統合することも容易な構造であること
  • アカウントの登録やパスワードの変更、パスワード忘れに対する救済策などを実現する機能があること
  • 役割(Role)に関する機能もWebSecurityクラスは持っていないため、別のもの(SimpleRoleProvider等)を使って行ってほしいこと

要は『機能を絞ってシンプルにし、それでいてセキュリティに配慮しつつも、容易に拡張できるようなっているよ』という感じでしょうか。


また、ASP.NETに詳しい人向けの情報として『このクラスの機能を実現するために低レベルの部分ではASP.NET標準のMembershipProviderの実装を使っている』ことなども書かれており、深く理解するための情報として有用かもしれません(ただし、WebSecurityの基底クラスにMembershipProviderがあるわけではありません。WebSecurityクラスは、同じくWebMatrix.WebData名前空間にある、SimpleMembershipProviderを”利用”する実装が行われているクラスです。そしてSimpleMembershipProviderの基底クラスにMembershipProviderがある、という構図と思われます)。



Remakrsの下には、少しだけサンプルコードが提供されています。WebSecurityのLoginメソッドを使ってログインを行っているサンプルですが、さすがに…これだけだと、ちょっと雰囲気がつかみにくいかもしれませんね。お奨めは、先にも挙げたとおりWebMatrixVisual Studioのテンプレートに含まれているサンプル実装です。

次回(?)からしばらく、このサンプルテンプレートを元に、WebSecurityクラスの全貌に迫っていこうかと思います。

*1:何となくですが、なんかそんな気がする…