アーカイブ

Archive for 2012年12月

最新の GridView なら検証の設定も楽々!

※この記事は One ASP.NET Advent Calender の21日分のエントリーです。
21日分、、、

前の記事では GridView の SelectMethod プロパティを設定してデータの抽出を行いました。
データの更新には UpdateMethod を利用します。

image

GridView に UpdateMethod と AutoGenerateEditButton プロパティの設定を追加します。

image

UpdateMember メソッドの実装はこんな感じです。
ASP.NET MVC を使ったことのある人にはわかりやすいですね。
UpdateMember メソッドは Member 型の引数をとっていますが、これはモデルバインダーという仕組みが今回 WebForms にも採用されているからできることです。
モデルバインダーはブラウザからのリクエストであがってきたデータを、モデル(上記の場合は Member)のプロパティ名と照らし合わせて、自動的に Member 型のインスタンスを生成してくれます。

データの追加の部分は EntityFramework の最近のバージョン(4.2からじゃなかったかな?)ではこういう記述でデータの追加ができます。

image

デバッグの実行を開始すると編集リンクが追加されていて、データの編集が可能になっています。
Name を「おの2」としてデータが更新できることを確認してみましょう。

image

さて、ここから今日の本題。
以前の GridView では、データの更新時に検証を行おうとすると、データのフィールドをテンプレートフィールドにして、そこに検証コントロールを一つ一つ貼っていかないといけない、というかなり手間のかかるものでした。
それが、今なら。。。

まず、GridView のすぐ下あたりにエラー時のメッセージを表示するために ValidationSummary を貼り付けます。

image

Member クラスの Name プロパティに Required 属性を追加します。
Name を必須の入力項目にするわけですね。

image

Member クラスは EDM を作り直したら上書きされますので、そのような操作を行うときは注意しましょう。
まぁ、どんな属性を設定したか覚えておけばいいだけの話です。
そして UpdateMember メソッドをちょっと修正します。

image

このあたり、ASP.NET MVC と同様ですね。
で、デバッグ実行して Name を空にして更新しようとすると、

image

このように、きちんと必須チェックを行ってくれるようになります。
モデルバインダーが Member のインスタンスを生成する際、設定されている属性によるチェックも自動的に実施してくれて、エラーの状態まで登録してくれるのでこのようになるんですね。

エラーの状態はプログラムで追加することもできます。

image

こんなふうに ModelState にエラー状態を追加すると、どんな場合でも更新できなくなります。

image

まあ、ふつうは独自の更新チェックの条件を追加する場合に使うんですけどね。

ここまででも便利は便利なのですが、もうひとつ。

image

GridView の ItemType プロパティに Member クラスを設定します。
そうすると、

image

さっきのすべての更新をエラーにするプログラムを修正していないのに、必須入力の検証が行われて、またそのチェックが実行された項目に「*」が表示されています。
これ、HTMLをみるとわかりますがクライアント側でスクリプトによる検証が行われているんですね。

ItemType プロパティを設定することで何が起きてるのか。。。
という話を続けるには記事がながくなりすぎたので、それは次の機会にしたいと思います。

しかし、GridView、かなり使えるやつになってると思いません?
環境が許すならどんどん使っていきたいですね。

広告
カテゴリー:.NET, ASP.NET 4.5, ASP.NET 備忘録

最新の GridView ならページングもソーティングも楽々!

この記事は One ASP.NET Advent Calender の20日のエントリーです

GridView は便利なんですけど、ページングやソーティングをしっかり実装しようとするとなかなか手ごわいですよね。
データ量が限られてるのがわかってるなら SqlDataSource でさくっと動かしてもいいんですけど、のちのち問題になるのわかりきってますしねぇ。。。

と、面倒だった実装が最新(4.5)版の GridView なら楽々です。
ということでとにかく動かしてみましょう。

さて、まずは新しい Web サイトで ASP.NET Web フォームサイトを作って DB を追加します。
DB じゃなくてもいけるはずですが、明日もこの環境使うために DB で。
そして WebForms で CodeFirst で簡単に DbContext 作る方法がわかってないので DB First で Entity Framework 使っていきたいと思います。

#ASP.NET MVC なら POCO のクラス書くだけであとはスキャッフォールディングにおまかせで DbContext 作ってくれるんですけどね。。。

と、気を取り直して DB 作成。

image

そそ、この新しいテーブルデザイン画面いいですよね。
なにがいいって IDENTITY の設定がワンクリックでできること。
最初は項目表示されてないので右クリックして表示項目を追加してあげるひつようがありますが。
あと、CREATE 文もぱっと目に入ってくるので SQL の勉強にもいいですよね。
つい保存ボタン押したくなっちゃうんですが、専用の「更新」メニューをクリックして DB つか Member テーブル作成、っと。
で、GridView でページングとソーティングの話ですから適当にデータつっこんでおきましょう。

さて、DB First ですから次は EDM 追加します。

image

image

もうデフォルト設定のままウィザードたたいて突っ走ってしまいますよ、と。。。

image

はい、できました、っと。
なんかセキュリティの警告でますけど、T4テンプレートでソース生成するときって出るみたいです。
なぜか連続2回。
まぁ、とにかく EDM できたけどタブに[*]ついてるので一回ビルド走らせておきます。

で、今回かなり優秀になってるな、と思ったのが

image

へんな名前空間とかなしで、Member クラスを生成してくれます。
これなら使い勝手いいですよね。

と、GridView はどうしたんだ、といわれそうなので新規でWebページを追加します。
で、いきなりコードを表示させて次のようなデータを呼び出してくるメソッドを追加します。

image

と、ここで待望の GridView です。
GridView を Web ページに追加して SelectMethod プロパティにさっき書いたメソッドを設定してあげましょう。

image

はい、ここでとりあえずデバッグ実行してみましょうか。

image

さくっとデータ拾ってきてますね。
では、本題のページングとソーティング。

image

プロパティの設定を3つ追加しました。
で、実行すると。。。

image

あらあら、エラーです。
でも、このエラーきちんと見ておいてくださいね。
LINQ に慣れてる人ならもうなんとなくわかるかも。
で、OrderBy つけろ、と言われているのでデータ取り出すとこにデフォルトのソート順設定しましょう。

image

ま、こんなとこでしょうか。
さて、デバッグ実行っと。

image

はい、ページングとソーティングのリンクが追加されました。
2ページめは、、、

image

ちゃんと表示されますね。
Name をクリックすると、、、

image

image

ソートした状態でのページングもOK、っと。
ソーティングの昇順降順もきちんと保持しているようで、同じソートリンクを何回もクリックするとそのたびに昇順降順が入れ替わります。

いやー、ここまでコード何行書きました?
いままでのあの苦労はなんだったんだろう、と思いません?

で、ちょっとだけ裏側を解説すると、さっきでたエラーで メソッド Skip を GridView が使ってるのがわかります。
Skip、Take は LINQ 使ってページングするときの定番ですよね。
SelectMethod で IQueryable を返しているので、そこに Skip、Take がのせられてデータをとってきてるんだろう、という推測ができます。
なら、ソーティングは当然 OrderBy が使われてるんだろうな、と。
LINQ は遅延実行されるので、実際に DB から取り出されるのは Skip、Take で指定された必要なデータのみ。
なので、ViewState の肥大化なんて気にすることなく安心して利用することができますね。

と、とりあえず今日はここまで。
明日は GridView 使ううえでやっぱり面倒だった検証関係をとりあげます。

そだ、最後にひとつ。
わかりやすいので GridView を例にあげてますけど、ほかのデータ操作系のコントロール、DetailsView、FormView、ListView、ListView でもこれ使えますからね。
便利になりますねぇ。。。

カテゴリー:.NET, ASP.NET 4.5, ASP.NET 備忘録

Visual Studio Express 2012 for Web を紹介してみる

本日は Visual Studio Advent Calender 13日めのエントリーということで、表題のような記事を書いてみようと思います。

Visual Studio は 2005 のころから(だったはず) Express エディションという形で無償版が提供されています。
ですがネットを見ていると意外に Express エディションのことが知られていないように思うこともあります。
無償で使えて商用利用も可、機能的にもふつうにプログラムを組むうえでの機能は有償のほかのエディションとほぼ一緒。
たとえば昨日の VS Advent Calender のエントリで紹介されたページインスペクターの機能などもふつうに使える、JavaScript のインテリセンスなどもばんばん使える、こんな高機能の IDE が無償で使えるのが知られてないってなんかもったいないじゃないですか。

ちなみに、この Blog の記事とかどこかの勉強会とかでお話させてもらうときとか、私は基本的に Express エディションを利用するようにしています。
それなら Visual Studio をインストールできる環境さえあれば、誰でも手軽に確認できますからね。

ということで、前置きはこのあたりで終えて本題にはいっていきましょう。 <= ながいよ。。。

まずは作成できるプロジェクトの紹介から。

VS Express 2012 for Web では、Web アプリケーション プロジェクトも Web サイト プロジェクトも当然のように構築することができます。

image

 

image

このキャプチャで注目してもらいたいところは、プロジェクトの選択の上部でターゲットのフレームワークのバージョン選択ができるようになっている点です。
2010 の Visual Web Developer ではバージョンの選択は一度プロジェクトを作成してからプロジェクトのプロパティで変更する必要がありました。
2012 ではここでバージョン 4 と 4.5 をあらかじめ選択することができます。

それ以下のバージョンはどうなるんだ、って?
まず、.NET Framework 3.5 (2.0 ~ 3.5 はランタイムが同じですからひとくくりで考えてください) は VS 2012 とは別にインストールする必要があります(Win8の場合、ですが)。
それらがインストールされていれば、2010のころと同じように一度プロジェクトを作成してから、プロパティでターゲットフレームワークを変更することは可能になっています。

#ちなみに、Ultimate ではプロジェクト作成時に 3.5 以下のフレームワークを選択することができるようになっています。

構築できるプロジェクトのテンプレートについては特に Express だからどう、という変化はありません。
4.5 の環境での ASP.NET のテンプレートの概要についてはこの Blog の以前の記事を参考にしてください。

で、ちょっとみておきたいのがデータベースの操作ツールです。

image

有償版のエディションと同様、新しいデータベース操作ツールが利用できるようになっています。
データベースへのアクセスがデータベースエクスプローラーから(有償版ではサーバー エクスプローラーから)という点は過去の Express と同様です。

NuGet (ライブラリ パッケージ マネージャー)も最初から組み込まれています。

image

このあたりは VWD でも使えていたものですから使えて当然ですね。

2012 になって追加された機能としては、テストプロジェクトが使えるようになったこと!

image

テストエクスプローラーで Red/Green とか確認できるですよ!
これでテスト駆動開発もばっちりです。

それと、もひとつ。

image

TFS につながるようになったですよ!
これでソース管理もバッチリです!

2010 までの VWD で、「Express はこういった機能がないだけで、あとはふつうに開発に使えます」と紹介していた「なかった機能」がすっかり追加されてしまいました。
いいんでしょうか、これが無償で。

アドインの追加はできないので便利な拡張機能をいれたり、痛IDEにしたりすることはできませんが。。。
それさえ我慢できれば、快適な開発環境が無償で手に入ります。

ほかにデスクトップアプリ、Win8 ストアアプリ、 WPアプリの開発も Express エディションが用意されています。
まずは触ってみる、それができるのが Express エディションの良いところですね。

カテゴリー:.NET

Form 認証に関するあれこれ

※この記事は One ASP.NET Advent Calender 2012 6日めのエントリーです。
ええ、6日分です。。。だれがなんといっても6日分です。。。

 

テンプレートに組み込まれているため、あまり考えもせずにさくっと使えてしまう Form 認証ですが、その実行を支えている要素についてあれこれ考えてみたいと思います。

 

○Form 認証を有効にする

Form 認証を有効にするには、web.config に authentication 要素を記述します。

<authentication mode="Forms" />

この設定は、ルートフォルダ直下のweb.configに記述する必要があります。

不思議なことに、 WebPages のテンプレートにはこの記述が存在しないのに、Form 認証が実行されます。
これは、SimpleMembershipProvider を含む WebMatrix.WebData.dll が登録されていると、アプリケーションの起動時に強制的に Form 認証を使うように設定されるためです。

 

○ログインの実行

WebFormsだとログインの実行に使われるのは Login コントロールです。
SqlMembershipProvier や Universal Membership Provider とともに使えば、コントロールを貼り付けるだけでログインの操作は自動でできるようになります。
ただ、これだとなかの動きはまったく見えませんね。

SimpleMembershipProvider とともに使われるのは WebSecurity.Login メソッドです。
ドキュメント中に記載がありますが、「ユーザーがログインすると、ASP.NET によって Cookie に認証トークンが設定されます。」
Loinコントロールも実は同じことをやっています。

この動きがはっきり見えるのは ASP.NET MVC 3 のテンプレート中の LogOn 時の動きです。
Membership.ValidateUser メソッドを使ってユーザーが登録されているかどうかを確認し、 FormsAuthentication.SetAuthCookie メソッドによって Cookie に認証トークンを設定しています。

ここで重要なことは、

  • ASP.NETのログインとはCookieに認証トークンを設定することである。
  • 認証トークンは FormsAuthentication.SetAuthCookie メソッドによって発行することができる

ということです。
なんらかの MembershipProvider を使わなくても、たとえば独自のデータベースの情報からユーザーが登録されているかどうかを判定して、FormsAuthentication.SetAuthCookie メソッドを使えば ASP.NET が用意している Form 認証の仕組みを使うことができるのです。

なお、Session の管理にも Cookie が使われますが、Session 用の Cookie と認証トークンとしての Cookie は別のものです。
Session と認証トークンはそれぞれ別に管理される、ということは覚えておいてよいことかと思います。

 

○ログインユーザーの認証

ログインすると Cookie に認証トークンが設定されることはわかりました。
では、この認証トークンはどのように使われるのでしょう。
このあたりは ASP.NET のフレームワークがうまくいろいろとやってくれるところです。
具体的には HttpApplication クラスのアプリケーションイベントの発生順をみてください。

ここの AuthenticateRequest イベントのタイミングで、フレームワークは認証トークンを解析し、HttpContext.User.Identity.IsAuthenticated に true を設定します。
まぁ、1リクエストを処理する間存在するある意味大域変数とも考えられる HttpContext にユーザーの情報を設定するわけです。

その後、AuthorizeRequest イベントのタイミングで承認(URLにアクセスする権限があるかの確認)が行われます。
承認の作業は HttpContext のユーザー情報を確認し、そのユーザーがアクセスする権限を持っているかどうかが判断されます。

 

○承認の設定

承認の設定は web.config に

<authorization>
  <deny users="?"/>
</authorization>

のように記述されます。
これは認証されていないユーザーへのアクセスを許可しない、という設定ですね。

web.config はフォルダごとに配置することが可能ですので、特定のフォルダに上記を含む web.config を配置すると、そのフォルダ内のリソースは認証されていないユーザーには表示されない、ということになります。

この設定は location 要素を利用することで特定のファイルにのみ設定を有効にすることも可能です。

<location path="Manage.aspx">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>

また、location 要素にフォルダを設定することもできますので、各フォルダごとに web.config を配置するのではなく、ルートの web.config 内にすべての設定をまとめて記述することも可能です。

この承認の設定は、実際には URL に対して行われている、ということを理解するのが重要です。
ASP.NET MVC のように、フォルダの構成と URL の構成が一致しない場合、URL に合うように承認の設定を記述する必要があります。

ASP.NET MVC で /admin の中を認証ユーザーのみに公開したい、といったとき、 View フォルダ内の adminフォルダに 承認の設定を記述してもそれは有効になりません。
その場合、ルート直下にadminというフォルダを作成してしまってそこに承認の設定を配置するか、location を使って /admin にたいして承認の設定を記述すれば有効になります。

まぁ、実際には ASP.NET MVC では Authorize 属性をコントローラ(クラス)、またはアクション(メソッド)に設定することで承認の設定とするほうがわかりやすいでしょう。
この場合、web.config には承認の設定は記述しません。
そのため、HttpApplication の AuthorizeRequest イベント時には承認の解決は行われていません。
Authorize 属性は Actionフィルターの一種ですので、各アクションの実行直前のタイミングで承認が行われることになります。

○まとめ

ASP.NET の Form 認証がどのようにして実行されているかをまとめてみました。
ここに記述した内容が理解できていると、独自の認証の仕組みを構築するのに MembershipProvider のカスタマイズなんておおげさなことをしなくても、ちょっとした実装でそれなりの仕組みを構築できるようになっていることがわかるのではないかと思います。

実はこれから Membership の仕組みに新しいものが登場することになっています。(ロードマップ参照
ただ、ここに記述した認証/承認のベースの仕組みは ASP.NET 登場当時からのものであり、今後もこのベースそのものが変わることは考えにくいと思っています。
基礎となっている部分をしっかり理解していれば、新しい仕組みがでてきてもどこが違うのか、をおさえるだけで使えますから、このあたりの知識は無駄にならないんじゃないかなぁ、と思っています。

カテゴリー:.NET, ASP.NET 備忘録