• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック
 

jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック

on

  • 3,777 views

Community Open Day 2012 北海道会場 セッション2

Community Open Day 2012 北海道会場 セッション2

Statistics

Views

Total Views
3,777
Views on SlideShare
2,927
Embed Views
850

Actions

Likes
0
Downloads
8
Comments
0

3 Embeds 850

http://devadjust.exblog.jp 843
http://webcache.googleusercontent.com 6
http://cache.yahoofs.jp 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック jQuery Validation x ASP.NET MVC で遭遇した不具合 & 対抗ハック Presentation Transcript

    • jQuery Validation x ASP.NET MVCで遭遇した不具合 & 対抗ハック @jsakamoto Community Open Day 2012
    • Twitter Hashtag• よろしければ、 #clrh71 でお願いいたします。 – #cod2012jp だけだと、全国会場の Tweet と混信しそうなので... – 本セッション中、MiniTwitter にて #clrh71 を含む Tweet をポップ アップします。
    • jQuery Validation についておさらい• クライアント側スクリプトによる入力検証機能を提供する JavaScript ライブラリ。 – jQuery のプラグイン• ASP.NET MVC の、標準のクライアント側入力検証エンジンに採用 – MVC3以降 – Visual Studio にて ASP.NET MVC アプリを新規作成すると標準で使用。• この資料を作成している時点での最新バージョン: – jQuery = v.1.7.2 – jQuery Validation = v.1.9
    • 本セッションのテーマ• jQuery Validation を使っている上で ”些細な” 不具合にいくつか遭遇• それら不具合について紹介、どう対策して解決したのかを披露• 対策はすべて、クライアント側 JavaScript コード上で施工 – 本セッションの本質的な部分では、C# とか ASP.NET とか出てきません。 – プラットフォーム問わず、Web アプリ共通の話題ではないでしょうか? – っていうか、むしろ、Ruby on Rails などなど、他のプラットフォームでは 問題になってないのか? 気になります。
    • デモ アプリ• こんな ASP.NET MVC4 な Webアプリを肴に、実演を 交えつつ、進めて参ります。
    • Case 1. 文字数検証 - input type=“text”
    • Demo
    • 何が起きてる?• jQuery Validation は、行頭行末の空白を除いた文字数で チェック – ”期待” とは異なったクライアント側検証。• サーバー側検証では、行頭行末の空白もそのままに文字 数チェックするのでセーフ。 – ”Post Back” な挙動。 – Webではクライアント側検証に頼らないという鉄則。
    • 対応• jQuery Validation の検証メソッドを改変すればいいmaxlength: function(value, element, param) { return this.optional(element) || this.getLength($.trim(value), element) <= param;} この trim 要らない!
    • 方法1 - jQuery Validation のソースを直接変更• MIT License• でも将来の jQuery Validation 本家のバージョンアップに ついていける?
    • 方法2 – 開発元にフィードバック• trim しているのは、それはそれで意味があるのでしょう。• その上でなお、破壊的変更が受け入れられるのか?• 仮に受け入れられるとして、リリースされるまで待てる? – “今そこにある危機”
    • 方法3 – 実行時にOverride• JavaScript なので、実行時に「書き換え」できます。 $.validator.methods.maxlength = function (value, element, param) { return this.optional(element) || this.getLength(value, element) >= param; };
    • JavaScript コードの Hack• いかにも “動的言語” らしく、Hack しやすい。• しかし Closure が使える...! – 関数型言語っぽい手法で作成されると手が出せない。• jQuery Validation はそんな実装されてなく良かった... これで学びました。
    • Case 2. 文字数検証 - textarea
    • Demo
    • 何が起きてる?• jQuery Validation は、改行は1文字として文字数チェック。• サーバー側検証では、改行は2文字として文字数チェック。 – POST データ中、改行が CR+LF になってる – Windows7上で、IE9 でも Firefox12 でも Chrome19 でも同じ挙動 ※以上を Fiddler v.2.3.9.3 で確認。MacOSではどうなんでしょう?• クライアント側とサーバー側とで検証動作が異なる。 – ちなみに、XHR要求だと改行が LF で送信されたり。
    • 対応• サーバー側で CR+LF を LF に置換することで対応可能。• でも、漏れなく実装するのは大変では?• それでは jQuery Validation の実装を変更しましょう。 – オリジナルの $.validator.prototype.getLength(value, element ) が 呼び出される前に、value に含まれる改行文字(LF)を2文字に置換し てオリジナル実装に渡すよう、カスタムコードを ”差し込む”。
    • 実行時に Override 元の実装をorgに確保var org = $.validator.prototype.getLength; getLength メソッドを 独自実装に差し替え$.validator.prototype.getLength = function (value, element) { LFを適当な value = value.replace(/¥n/g, "++"); 2文字に置換 return org.apply(this, [value, element]); }; 元の実装をapplyで実行
    • Case 3. Cancel ボタン
    • Demo
    • 何が起きてる?• “cancel” CSSクラスを持つ input か button がクリックさ れると「入力検証しない」のフラグが立つ。• そしてそのフラグは解除されない。 this .find("input,button") .filter(".cancel") .click(function() { validator.cancelSubmit = true; });
    • 正攻法 – input で Cancel ボタンを実装しない• a 要素で。• Twitter Bootstrap など昨今の CSS ライブラリを使えば、a も input も、同じ外観に作れる。
    • どうしても、という場合...• 「検証しない」フラグをワンショット遅延でオフに復元。 $(".cancel").click(function () { var validator = $(this).closest("form").validate(); setTimeout(function () { validator.cancelSubmit = false; }, 0); });
    • Case 4. IE8
    • Demo
    • 何が起きてる?• $.validator.elements メソッドの内部に原因• IE8 だとなぜか、$($(“form”)[0].elements).filter(“:input”) の結果が、要素数 = 0個になっている – IE9 でも、ドキュメントモードが IE8 かそれ以前だと再現
    • 対応 – jQuery Validation を最新に• この問題を抱えているのは、実は ver.1.8.0.1 まで。• jQuery Validation を ver.1.8.1 以降に Upgrade で解決。 – ver.1.8.1 のパッケージは 2011年6月10日頃から出現している模様。 – それ以前に作成されたASP.NET MVC3 アプリは注意?
    • jQuery Validation を最新にできない場合は...• $.validator.elements の実装を実行時に Override。• .filter(“:input”) ではなく、.find(“input, select, textarea”) で要素を絞り込む。$.validator.prototype.elements = function () { ... return $([]) .add(this.currentForm.elements) .find("input, select, textarea") ...;};
    • Case 5. CSS Class 名が検証ルール名にかぶった
    • Demo
    • 何が起きてる?• ASP.NET としての入力検証機構とは無関係に、jQuery Validation による入力検証機構は活きている• そのひとつ、CSSクラス名による入力検証の発動 – email – required – date – number – ...
    • jQuery Validation 標準の検証ルールは潰せる• $.validator.classRuleSettings からCSSクラス名ルールを削除 delete $.validator.classRuleSettings.email;
    • 徒然に
    • 些細なことにこだわってばかりで、自分が器の小さい人間に思えてきました...だって、結局は、サーバー側検証が機能するんだし...
    • 結局、フィードバックは、Microsoft を含め、どこにもしていません。他の仕事とか優先してしまい...どなたか Microsoft Connect とかに投稿いただません?
    • Web Forms や、MVC2 までのクライアント側入力検証では、些細とはいえ、こんな問題はなかったよな... と思ったり。さすが Microsoft 純正品クォリティ?今振り返るに、jQuery Validation の採用はどうだったんだろう...
    • Thank you...