検索
リンク
タグ
Azure
ASP.NET Core
Visual Studio
ASP.NET
SQL Server
Selenium
AJAX
C#
JavaScript
Fizz-Buzz
F#
.NET
jQuery
LINQ
AngularJS
ライトニングトーク
ASP.NET MVC
ADO.NET Entity Framework
Plone
WebMatrix
カテゴリ
最新の記事
最新のコメント
記事ランキング
最新のトラックバック
以前の記事
2019年 11月 2019年 10月 2019年 09月 2019年 08月 2019年 07月 2019年 06月 2019年 05月 2019年 04月 2019年 03月 2019年 02月 2019年 01月 2018年 12月 2018年 11月 2018年 10月 2018年 09月 2018年 08月 2018年 07月 2018年 06月 2018年 05月 2018年 04月 2018年 03月 2018年 02月 2018年 01月 2017年 12月 2017年 11月 2017年 10月 2017年 09月 2017年 08月 2017年 07月 2017年 06月 2017年 05月 2017年 04月 2017年 02月 2017年 01月 2016年 12月 2016年 11月 2016年 10月 2016年 09月 2016年 08月 2016年 07月 2016年 06月 2016年 05月 2016年 04月 2016年 03月 2016年 02月 2016年 01月 2015年 12月 2015年 11月 2015年 10月 2015年 09月 2015年 08月 2015年 07月 2015年 05月 2015年 04月 2015年 03月 2015年 02月 2015年 01月 2014年 12月 2014年 11月 2014年 10月 2014年 09月 2014年 08月 2014年 06月 2014年 04月 2014年 03月 2014年 02月 2014年 01月 2013年 12月 2013年 10月 2013年 09月 2013年 08月 2013年 07月 2013年 06月 2013年 05月 2013年 04月 2013年 03月 2013年 02月 2013年 01月 2012年 12月 2012年 11月 2012年 10月 2012年 09月 2012年 08月 2012年 07月 2012年 06月 2012年 05月 2012年 04月 2012年 03月 2012年 02月 2012年 01月 2011年 12月 2011年 11月 2011年 10月 2011年 09月 2011年 08月 2011年 07月 2011年 06月 2011年 05月 2011年 04月 2011年 03月 2011年 02月 2011年 01月 2010年 12月 2010年 11月 2010年 10月 2010年 09月 2010年 08月 2010年 07月 2010年 06月 2010年 05月 2010年 04月 2010年 03月 2010年 02月 2010年 01月 2009年 12月 2009年 10月 2009年 09月 2009年 07月 2009年 06月 2009年 05月 2009年 04月 2009年 03月 2009年 02月 2009年 01月 2008年 12月 2008年 11月 2008年 10月 2008年 09月 2008年 08月 2008年 07月 2008年 06月 2008年 05月 2008年 04月 2008年 03月 2008年 02月 2008年 01月 2007年 12月 2007年 11月 2007年 04月 2007年 03月 2007年 02月 2007年 01月 2006年 11月 2006年 10月 2006年 09月 2006年 08月 2006年 07月 ファン
ブログジャンル
画像一覧
|
2007年 11月 21日
ここ最近このブログに投稿しているネタは Plone 関連ばかりだが、実際には Plone ネタは現在進行形ではなく、すでに膠着した案件をおさらいと記録を兼ねて投稿している次第。
最近は、ASP.NET 開発が中心の毎日に戻っている。 さて、つい先日、ASP.NET + ASP.NET AJAX での開発でハマった出来事があった。 ASP.NET AJAX Library を利用して、とあるHTML要素の keydown イベントを取り扱う JavaScript コードを実装するタスクが発生。 keydown イベントハンドル時に、実際に押下されたキーがどのキーなのかを判別する必要があった。 今振り返れば不思議なことに、これまでキー押下イベントを扱うような Client 側 JavaScript を記述する機会がなかった(ASP.NET AJAX Libraryを使わない素の JavaScript でなら経験有り)。 さて、ASP.NET AJAX Libray のドキュメントを見てみる。 ASP.NET AJAX Library では、イベントハンドラの第一引数に、Sys.UI.DomEvent オブジェクトが渡され、この Sys.UI.DomEvent オブジェクトのフィールドなどに、そのイベントの詳細情報が格納されていてこれを参照することができるようになっている。 Sys.UI.DomEvent のリファレンスを見てみると、どうやら charCode フィールドを参照すればよいらしい。 ということで、charCode フィールドを参照する JavaScript コードを書いて走らせたのだが、なんと、charCode フィールドは undefined だというではないか。 何度もリファレンスを見直したり、コードをああでもないこうでもないとひねくり回したりして、しばらく悩んでいた。 そのうち、はたと気がついた。 keypress イベントなら charCode でいいけれど、keydown イベントなら文字じゃないキー押下も拾うはずだから、charCode という名前のフィールドはおかしんじゃないか、keyCode という名前のフィールドじゃないのか? もういちどリファレンスを確認したが Sys.UI.DomEvent に keyCode というフィールドがあるとは明記されていないようだ。 それでも一か八かで、charCode を keyCode に書き替えて再度試してみた。 見事成功。 カーソルキーの押下を判定しているのだが、IE7のほか、IE6でもFirefox2.0.0.9でもOpera9.2でもSafari for Windows Beta1でも、ちゃんと機能した。 あとで ASP.NET AJAX Control Toolkit のソースを眺めてみたら、たしかに keyCode フィールドを参照している。 うーん、keydown イベントでは charCode フィールドではなく keyCode フィールドを参照すべしなのは常識なのだろうか? たしかに、何らかの JavaScript ライブラリに頼らずに素の JavaScript でイベントハンドリングしていた時代は、event オブジェクトの keyCode フィールドを参照していたものだ。 しかし今回は ASP.NET AJAX Library を使うことから、ドキュメントを頼って何も考えずに charCode フィールドを参照しハマってしまった。 とりあえず一件落着だが...keyCode フィールドのことはリファレンスに明記しなくてもよいものなのだろうか、それとも明記されているのだがなにぶん英文なので読み落としているのか。 "ASP.NET AJAX charCode keyCode" で検索しても特に同じようにハマった話題は見つけることができない。 こんなことでハマったのは私だけ? 釈然としない...。 ▲
by developer-adjust
| 2007-11-21 22:36
| .NET
|
Comments(0)
2007年 03月 22日
最近、Microsoft ASP.NET AJAX Library に基づき作成されたコントロール集、ASP.NET AJAX Control Toolkit を使わせてもらう機会も増えてきた。
そんな今日この頃、ASP.NET AJAX Control Toolkit ver.1.0.10301 に収録されている TextBoxWaterMarkExtender コントロールについて問題にぶつかった。 TextBoxWaterMarkExtender コントロールは、TextBox コントロールを拡張し、拡張対象の TextBox コントロールの入力内容が空で且つフォーカスを持っていない場合は、予め設定しておいた "watermark"(透かし) テキストを TextBox 内に表示する、というものだ。 (公式サイトのライブデモはこちら:http://ajax.asp.net/ajaxtoolkit/TextBoxWatermark/TextBoxWatermark.aspx) 普通はやらないような実装だと思うのだが、TextBoxWaterMarkExtender コントロールを、反復系データリストコントロールである GridView の ItemTemplate 内で使用した。 すると、GridView 中2行目以降、TextBoxWaterMarkExtender によって拡張された TextBox コントロールについて、未入力のままであってもポストバック時に "watermark" テキストが入力内容として返ってくるのだ。 以下に問題を再現するサンプルを示す。 http://gentoo.dev-asp.net/samples/05UsingTextBoxWatermarkExtenderInDataList/ ブラウザに返された HTML コンテンツと、TextBoxWaterMarkExtender の C# ソースコードを見てみたところ、謎が解けた。 TextBoxWaterMarkExtender は、ClientScriptManager.RegisterOnSubmitStatement メソッドを使って、Submit 直前に "watermark" テキストをテキストボックスから取り除く JavaScript を注入する。RegisterOnSubmitStatement メソッドはスクリプトの重複登録を避けるために "キー" 文字列を添えてスクリプトコードを渡す仕様になっている。 ここで、TextBoxWaterMarkExtender は、自身の ID プロパティをキー文字列に使っていた。 今回の不具合はこれが原因である。 つまり、反復系データリストのテンプレート内のコントロールは、ID プロパティが同値のインスタンスが、バインドされたデータ件数ぶんだけ繰り返し現れるので、1行目のテンプレートに現れた TextBoxWaterMarkExtender のみが "watermark"除去用 Submit 時スクリプトの注入に成功し、2行目以降の TextBoxWaterMarkExtender は、ID プロパティ値を由来とするキー文字列が 1行目のものと重複するため、"watermark" 除去用 Submit 時スクリプトの注入は「すでに登録済み」としてフレームワークによって取り扱われないのである。 さて、対応方法はさほど難しくない。 TextBoxWaterMarkExtender の実装は、OnLoad メソッド内にて"watermark" 除去用 Submit 時スクリプトの注入を行っている。 そこで、まず、TextBoxWaterMarkExtender から派生した自前のクラスを作成し、OnLoad メソッドをオーバーライドする。 オーバーライドした OnLoad メソッドの実装内容はオリジナルの TextBoxWaterMarkExtender のコードをまるごとコピー&ペーストするが、一点だけ、RegisterOnSubmitStatement メソッドに渡すキー文字列を、(ID プロパティ由来はなく)UniqueID プロパティに由来するものとするよう、コードを変更すればよい。こうして作成した自前のクラスを使うようにすれば問題は解消される。 TextBoxWaterMarkExtender のソースを直接変更し、ASP.NET AJAX Control Toolkit の独自ビルドを使用するという手段も、場合によってはあるであろう。 今回の不具合は、今日時点の最新リリース、10301 で発生するが、CodePlex から最新のソースを取得してみても、特にこの点は変更はないようだ。 また、同 Issue Tracker をざっと眺めた感じでは、同類の不具合報告/改善要望は挙がっていないようだ。 後日、投稿してみることも検討中。 ところで、今回の件とは関係ないが、ASP.NET AJAX Control Toolkit について、CodePlex 上の Issue Tracker にはこれまたずいぶんとたくさんの不具合報告/改善要望が投稿されている。 内容をいくつか見てみたが、それだけ、ブラウザ互換やHTMLバージョン互換を維持するのは難しいのだな、という点や、今回の私のように、開発者が想定していたであろう場面を超えた利用が発生しているのだな、といった点がうかがい知れた。 とにかく、これだけ不具合報告/改善要望があがっていれば、今後もまだまだ成長しそうなプロダクトであるな、と感じた次第。 ▲
by developer-adjust
| 2007-03-22 21:49
| .NET
|
Comments(2)
2007年 03月 18日
先日、ASP.NET AJAX の UpdatePanel 利用時、RadioButtonList の SelectedIndexChanged が発生しないことがある という記事を投稿したが、とりあえず回避策が見つかった。
そもそもの本現象の原因だが、ASP.NET の RadioButtonList コントロールが、AJAX の技法による UpdatePanel のような"部分更新"を想定していないことだ。まぁ、もっともなことで致し方ないと思う。 具体的には、AutoPostBack=true を指定された RadioButtonList コントロールについて、Selected=true を指定された ListItem を含んでいる場合、レンダリングされる HTML はこんな感じだ(※雰囲気を掴んでもらうためにデフォルメしているので、実際はもう少々異なる)。 <input type=radio name=RadioButtonList1$0 checked value="コウテイペンギン"> <input type=radio name=RadioButtonList1$1 onclick=__doPostBack(...) value="オウサマペンギン"> <input type=radio name=RadioButtonList1$2 onclick=__doPostBack(...) value="アデリーペンギン"> 初期選択されている ListItem に該当する input 要素について、onclick イベントにポストバックを実行する JavaScript 関数が接続されていないわけである。部分更新の概念がない時代では、これでページ全体が書き換えられるので、なんら支障なく、目的の動作を果たしていたわけだ。 さてここまでわかったので、初期選択されている ListItem に該当する input 要素についても、onclick イベントにて ASP.NET ポストバック関数を呼び出すようにすれば、冒頭で示唆した問題を回避できるものと考えた。 まずは、ポストバックのための JavaScript 関数呼び出しはどのようなコードを書けばよいのか、である。 ClientScriptManager クラスには GetPostBackEventReference メソッド が用意されており、このメソッドを使えば、ポストバックのための JavaScript コード文字列が手に入る。 しかしややこしいことに、RadioButtonList コントロールの HTML レンダリング結果は複数の input type=radio 要素に分散するので、個々の input 要素についての JavaScript コードが必要になるはずだ。 ところが、GetPostBackEventReference メソッドは Control に対しての JavaScript コードを返してくれるのみで、個々の ListItem に対する JavaScript コードを返してくれることはないようだ(メソッドの引数には Control型しか受け付けない)。 私にはこれ以上わからなかったので、ここは妥協して、ASP.NET が出力した HTML をのぞき見て、"window.setTimeout('__doPostBack(\'(コントロールのUniqueID)$(ListItem の ItemIndex)\',\'\'),0" という文字列を手作りすることとした( ASP.NET の仕様が変われば通用しなくなるので、本来は禁じ手だが)。 次は、こうして作成した JavaScript コードを、input checked 要素の onclick 属性に書き出すようにすることだ。サーバー側のコードで、次のようにやればうまくいくようだ。 RadioButtonList1.SelectedItem.Attributes["onclick"] = "javascript:"+script; 以上の措置を講じることで、冒頭で述べた不具合は回避することができるようになった。 なお、この対策でも実は万全ではない。input type=radio 要素の onclick イベントでポストバックを発生させているので、選択済みの項目をマウスでクリックすることにより、ラジオボタンリストの選択が変化していなくてもポストバックが発生してしまうのだ。(私が確認した範囲では、SelectedIndexChanged サーバー側イベントは、そのイベント名のとおり、選択変更が発生した場合にのみ発生しているようだ。しかし、ViewState などの要因が関与しているかもしれない) 不用意なマウスクリックでもポストバックが発生してしまうので、サーバー側の負荷が心配だが、たいていのコードにおいては、それ以上の不具合・問題は発生しないであろう。ということで、私の手元では、ここまでの措置に留めることとした。 問題回避後のサンプルを作成したので、下記に設置しておく。 http://www.gentoo.dev-asp.net/samples/04FixNoActionWhenSelIdxChanged/ ▲
by developer-adjust
| 2007-03-18 23:03
| .NET
|
Comments(0)
2007年 03月 12日
Microsoft ASP.NET AJAX Library を利用していてぶつかった問題を、またひとつ紹介する。
DOCTYPE 宣言がない、または、DOCTYPE が Transitional で宣言されている ASP.NET ページに CollapsiblePanelExtender による Panel コントロールの 展開/縮小を実装した場合、このページを Internet Explorer で表示すると正しく動作しないようだ。 具体的には、縮小時に、縮小のアニメーションは表示されうのだが、アニメーション 終了後、展開された外見に戻ってしまうのである。 私の手元の環境では、IE 6 でも IE 7 でも発生した。いっぽう、Firefox 2.0.2 および Opera 9 では特に不具合は発生しなかった。 この件は、オフィシャルサイトに明記されている(下記参照)。 http://ajax.asp.net/ajaxtoolkit/CollapsiblePanel/CollapsiblePanel.aspx 問題を再現するサンプルはこちら(もちろん、IE で見ないと不具合は再現しない)。 http://gentoo.dev-asp.net/samples/02CollapsiblePanelNeedDOCTYPE/ 残念なことに、仕事上、Transitional にどうしても依存しているページレイアウトがあり、そのページでこの問題に遭遇してしまった。 致し方ないので、JavaScript コードを手組みで実装して回避した。とはいえ、もちろん、せっかくなので Microsoft AJAX Library のクライアント側ライブラリを利用しての実装ではある。 ▲
by developer-adjust
| 2007-03-12 12:57
| .NET
|
Comments(0)
2007年 03月 11日
言わずと知れた、ASP.NET 2.0 Web アプリケーションに AJAX を統合するライブラリ、Microsoft ASP.NET AJAX。実践的に利用しているが、いくつか壁にぶつかることも出てきた。
一例としては、RadioButtonList コントロールと (ASP.NET AJAX の)UpdatePanel コントロールの組み合わせ。AutoPostBack=true に設定した RadioButtonList コントロールの SelectedIndexChanged イベントハンドラで、現在選択されたラジオボタン項目の値を Label コントロールの Text に設定して表示する Web アプリを想像してほしい。 ここで、この Label コントロールを UpdatePanel コントロール内に収録し、Triggers の設定をすませておくことで、アラ不思議、ページ全体が再読込されることなく、AJAX の仕組みで、ちゃんと Label コントロールの表示が更新される。 しかし、RadioButtonList コントロールのいずれかのアイテムについて、Selected=true に初期設定されたアイテムが存在すると、うまくいかないケースが出てくる。Selected=true に初期設定されていないアイテム間を選択変更するごとには、ちゃんとサーバー側で SelectedIndexChanged イベントが発生することが確認できる。 しかし、Selected=true に初期設定されたアイテムを再度選択し直しても、今度は SelectedIndexChanged イベントが発生しないのだ。 なんとなく想像はつかなくもない。 クライアント側 JavaScript で、input type=radio 要素の click イベントを拾っているのだと思うが、その click イベント発生元の input type=radio 要素が、checked 属性を持っていない場合に限り、AsyncPostBack を発生させているのであろう。 そこで、この推測に基づき、RadioButtonList コントロールも UpdatePanel コントロール内に収録してみた。こうすれば、input type=radio 要素の checked 属性の有無も更新されるからうまくいくだろう、という読みだ。 案の定、このように実装を変更することで、先に述べた不具合は解消できた。 ところが、一難去ってまた一難。 今度はキーボードフォーカスについて問題が発生。 RadioButtonList コントロールについて、キーボード操作で選択変更しようとすると、AJAX の仕組みで RadioButtonList コントロール(が吐き出した input type=radio 要素群)も差し変わってしまうため、フォーカスを失ってしまうのだ(ブラウザにとってはそれまでフォーカスを持っていた要素が DOM から削除されるため)。 これらの不具合を実際に体感してもらえるよう、サンプルを作成してみた。 http://gentoo.dev-asp.net/samples/01NoActionWhenSelectedIndexChanged/ 今のところ、これといってうまい回避策は思いついていない。 特に、キーボードフォーカスの件は、今回紹介したようなサンプルに限らず、UpdatePanel 内に収録したコントロールには常につきまとう問題である。 もっと ASP.NET AJAX を深く掘り下げる必要があるようだ。そうすれば、おそらく適切なフックを仕掛ける余地がきっと残されているのだと思う。しかし、現時点の自分のスキルではまだまだ踏み込めていないところ。要勉強。 ▲
by developer-adjust
| 2007-03-11 23:44
| .NET
|
Comments(0)
|
ファン申請 |
||