111008 silverlight square_datavalidation

Post on 22-Jun-2015

1.155 views 0 download

Transcript of 111008 silverlight square_datavalidation

入力データ検証を使いこなそう

Silverlightを囲む会in東京#4

田中 孝佳(@tanaka_733)

はじめに

サンプルアプリの公開

説明に使うサンプルアプリを公開しています

– http://techblog.hilife-jp.info/2011/10/silverlightin4.html

– PC持参の方はぜひどうぞ

– IS12T, Win8MetroUIではだめですm(_ _)m

ソースコードはこちらで公開しています

– https://skydrive.live.com/?cid=B43F4832F5BAFBB9&id=B43F4832F5BAFBB9%211121#

で、公開してるブログの紹介

銀の光と藍い空

– http://techblog.hilife-jp.info/

Silverlight(Web), WP7, Azure, Kinect ネタが中心です

最近はSilverlight 5 シリーズやってます

– http://techblog.hilife-jp.info/search/label/Silverlight5

自己紹介 (@tanaka_733)

ERPパッケージベンダーの研究部門 – クラウドを使っていい感じにする研究

Silverlightは業務アプリ開発で使ってます – サーバーサイドはJava – 前回発表したものです

https://skydrive.live.com/view.aspx?cid=B43F4832F5BAFBB9&resid=B43F4832F5BAFBB9%211128

今回から 囲む会in東京 の運営にも 参加しています

WP7, Kinect, クラウド関連の勉強会 にも出現します

なぜクライアントサイドの 入力データ検証が必要なのか

サーバーサイド検証との違い

サーバーサイドの検証は信頼性のため そして業務用要件を満たすため

– SQLインジェクションなどを防ぎたい

–業務的にありえない値を入力させたくない

クライアントサイド検証はUX向上

–サーバーサイド検証だけだと応答性が悪い

–どんな値を入力すればいいか伝えてあげる

単にNGを出せばいいわけではない

サーバーサイド検証

Server

検証

Client

検証

API呼び出し

クライアントサイドに求められる事

あらかじめ入力形式を教えてあげる

–入力データ検証を助けるため

入力形式が誤っていた時、 どう修正すればいいか伝える

–よくない例

入力データ検証を実装するには

WebフォームだとJSが基本

HTMLは静的なので単体では検証できない

–サーバーサイドで毎回検証するのは 通信コスト・サーバーの処理コストがかかる

そこでJavaScriptの出番

–でもサーバーサイドでの検証も必要ですよ

JavaScriptが無効だったり、 フォームを通さず通信されたりします

公開APIを用意すると、 もはやサーバーサイド検証のみ

Silverlightでの検証

入力検証の仕組みが用意されています

– ASP.NET の検証コントロール的なもの

WCF RIA Servicesなど使えば、 サーバーサイドとコードを共有する ことも可能

–ただし今回はやりません

–どちらもC#/VB であることの強みですね

Silverlightにおける 入力データ検証の実装

用意されているもの

UI部品

– DataForm (ちょっと特殊なので今回はなし)

– Label

– DescriptionViewer

– ValidationSummary

– TextBox, ComboBoxなど入力系UI

検証ロジック

–いくつかのやり方が存在

UI部品を使ったサンプルアプリ

このアプリを例にとって説明していきます

その前に前提条件

MVVMでの実装です – 今回の実装にはPrismを使っていますが、

MVVMサポートライブラリに依存しない話です

– ViewとViewModelの分離と Bindingが重要 検証ロジックはViewModel側に定義します

今回はロジックがないのでModelは出てきません

Silverlight4 です (5 RCでも動作を確認)

Rx使ってます – 非同期検証を簡単に書きたかったから

VM側の実装方法

データ検証の実装方法いろいろ

検証方法の定義

–自前の検証関数で定義

– DataAnnotationsで定義

VMでの実装方法

–検証してNGだったら例外を投げる

– IDataErrorInfoをVMが実装する

– INotifyDataErrorInfoをVMが実装する

データ検証の実装方法

検証方法の定義

–自前の検証関数で定義

– DataAnnotationsで定義

VMでの実装方法

–検証してNGだったら例外を投げる

– IDataErrorInfoをVMが実装する

– INotifyDataErrorInfoをVMが実装する

個人的に おすすめ

おすすめの理由

DataAnnotations

–検証ロジックを宣言的に記述できる

if (str.Length >= 8 && str.Length <= 20) とか書かなくていい

– Label, DataformなどUIとの相性がよい

INotifyDataErrorInfo

–例外を投げる=処理が中断される のが嫌い

– IDataErrorInfoより改善されている

Data Annotationsの使い方

DataAnnotationsの使い方

プロパティにAnnotationを付与

Annotationに従って検証する処理を追加

– Validator.TryValidateProperty やTryValidateObjectで検証できる 今回はINotifyDataErrorInfo を実装したViewModelの基底クラス内 で記述します

DataAnnotations一覧

検証属性 説明

CustomValidationAttribute 検証用にカスタム メソッドを使用します。

DataTypeAttribute 特定の種類のデータ (電子メール アドレス、電話番号など) を指定します。

EnumDataTypeAttribute 値が列挙体に含まれることを保証します。

RangeAttribute 最小値および最大値の制約を指定します。

RegularExpressionAttribute 正規表現を使用して有効な値を指定します。

RequiredAttribute 値が必須であることを指定します。

StringLengthAttribute 最大文字数および最小文字数を指定します。

ValidationAttribute 検証属性の基本クラスとして動作します。

http://msdn.microsoft.com/ja-jp/library/dd901590%28v=vs.95%29.aspx

DataAnnotationsの使い方

プロパティに付加する

setterのコードは後で。

DataAnnotationsの欠点

複雑な検証ロジックは カスタム検証メソッドが必要 –例えば、IPv4アドレスとかCIDRとか

–正規表現でできるかもしれないけど、 複雑な正規表現はわかりづらい

複数プロパティ間の検証がしづらい –開始日は終了日より前とか

–プロコトル一覧の選択がTCPなら ポート番号が入力必須とか

カスタム検証メソッドの定義

検証メソッドは下記の条件を満たすこと

– publicなクラスで定義

– public staticなメソッド

–返り値はValidationResult

成功時はValidationResult.Success

–第一引数は検証対象の値を表すオブジェクト

–第二引数は任意 検証要求についての追加情報を提供する ValidationContext

カスタム検証メソッドの例

IPv4アドレスをチェックする

– IPAddress.TryParse メソッドを使用

– ValicationContextは使っていないので省略可

INotifyDataErrorInfo の使い方

IDataErrorInfoとINotifyDataErrorInfoの違い

MSDNにはこう書いてます

–一般に、Silverlight の新しいエンティティ クラスでは、IDataErrorInfo を実装するのではなく、INotifyDataErrorInfo を実装して、柔軟性を高める必要があります。

IDataErrorInfoの特徴

–オブジェクトにつき1つのエラーメッセージ

–検証のタイミングはBinding時のみ

INotifyDataErrorInfo メンバ

HasErrors プロパティ – オブジェクトの検証エラーが発生しているかどうかを示します

GetErrors メソッド – 指定されたプロパティまたはオブジェクト全体の検証エラーを含む IEnumerableを返します

– IEnumerableの要素はToStringメソッドでエラーメッセージを返す

ErrorsChanged イベント – IEnumerable が変更されるたびに、ユーザー インターフェイス (UI) スレッド上で発生させる

INotifyDataErrorInfoの実装例

ViewModelに実装させたいことが多い

そこで、ViewModelの基底クラスとして INotifyPropertyChangedと一緒に実装

使用するMVVMインフラに合わせて 実装しておくと便利

– Prismの場合、 INotifyPropertyChanged を実装したNotificationObjectを継承し、 検証結果を格納するErrorsContainerを使います

INotifyDataErrorInfoの実装例

ViewModelBaseクラス

ValidateProperty, ValidateObject メソッドを呼ぶと検証する

検証するとその結果をErrorsContainerに格納

検証結果に変更があると、ErrorsChanged イベントハンドラを呼び出す

この実装の注意点

初期化時の値のままだと、 検証は起きません

–最初から検証すると、 入力画面がいきなり真っ赤でやな感じ

なにも入力せずに送信する事があるので、 TryValidateObjectを必ず行う

プロパティの実装

コードスニペットにしておくのがお手軽 <Code Language="csharp"> <![CDATA[#region $property$ private $type$ $var$; public $type$ $property$ { get { return $var$; } set { if ($var$ == value) { return; } $var$ = value; RaisePropertyChanged("$property$"); ValidateProperty("$property$", value); } } #endregion $end$]]> </Code>

複数プロパティの関連の検証

複数プロパティの関連を検証

DataAnnotationでは単一プロパティしか 検証できない

方法は2つ(もしくはそれ以上)

– ValidationContext経由で検証に必要な ほかのプロパティを渡す

– ValidatePropertyメソッドなどを継承して、 そのオブジェクト特有の検証処理を追加する

ValidationContextを使う方法

ValidationContext.Items に必要な値をキーを指定して渡す

検証メソッドでは必要な値を取り出す

UIコンポーネントの使い方

使えるUIコンポーネント

入力系UI – 検証時にポップアップ

Label – 必須入力時にVisualStateが代わる

– Display要素でLabelのContentを指定できる

DescriptionViewer – メッセージを表示

ValidationSummary – メッセージを一覧表示

入力系UIでの設定

ValidationSummary使用時には Bindingオプションを指定します

Windows Phone 7 では

入力UIの検証属性は存在する

検証系のUIは非サポートとの記述

実際に検証属性を使っても何も起きなかった

要はUI側のデータ検証は使えない –画面が小さいので そんな面倒な入力はさせるなってこと!?

ロジック内でのデータ検証には使えそう

+α 非同期の検証が必要なとき

検証はクライアントサイドのみで完結が原則

– この場合の検証は同期処理でOK

しかし、例えば・・・

– SNSの入会フォームで ユーザーIDの存在チェックは それだけ先にチェックしたい!

– 検証している間に他の項目を入力できる

この場合非同期の検証が必要

– Silverlightだと通信がからむので必須

+α 非同期の検証の実装

INotifyPropertChangedを実装している場合、 非同期処理の最後でGetErrorsの結果を変更してErrorsChangedを呼べばよい

今回のViewModelBaseの場合は、 ErrorsContainerに追加しさえすればOK

+α 非同期の検証の実装サンプル

おなじみ(?)のRx使ってます

実際は、3秒待ってではなく、 通信してWebResponseなりを見て検証する

LTで面白い話があるそうなのでそれも期待

ご清聴 ありがとうございました