none
DataPagerで「System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません」とエラーがでる。 RRS feed

  • 質問

  • ListView でデータベースから情報をバインドし、DataPagerで、page外部変数を利用して値を得ています。
    この辺りまでは、コードなしで問題なく実現できておりました。
    しかし、page=abcd...(文字列), page=12345(数値), page=%00(null), page=1234asdf(混合), page=<a>a</a>(HTML/[validateRequest]入れないとエラーになりますが...),page=' delete from...(SQL Inj)などの無害化テストを行っていたところ、この辺りは問題なかったのですが、ちょっとミスで default.aspx?& という状況を作り出してしまったところ、NullReferenceExceptionが発生。
    ほかに試したところ、たとえば default.aspx?page=3& というような場合になってもアウトなもようです。
    この不具合を例外キャッチなどして治したい(ページ処理としては1ページ目を表示させたい)のですが、DataPager自信でpage外部引数の処理が行われますし、「page」という文字以外にしてもだめなもようなので、お手上げ状態です。
    何か解決策がありますでしょうか。

    2009年9月19日 21:48

回答

  • > しかし、page=abcd...(文字列), page=12345(数値), page=%00(null), page=1234asdf(混合), page=<a>a</a>(HTML/

    バグというよりは、そのような使い方(DataPager コントロールが自動的に設定する以外の使い方)は想定外
    なのではないかと思います。

    MSDN ライブラリには、QueryStringField プロパティは、DataPager コントロールでページの移動に GET
    コマンドを使用する(デフォルトは POST)ように指定するもので、その目的は、検索エンジンですべてのデー
    タページにインデックスが付けられるようにするためと書いてありました。

    従って、想像ですが、クエリ文字列の設定は DataPager コントロールが自動的に行うもので、ユーザーが
    入力するような使い方(page=abcd... のような文字列が入力される)のは想定外で、結果は未定義というこ
    とではないかと思います。

    解決策としては、ListView の使用をやめて、代わりに GridView を使い、その PageIndex プロパティでペ
    ージを指定するのが簡単そうです。

    ListView には GridView の PageIndex プロパティに相当するものはありません。どうしても ListView を
    使う必要があるなら、少々工夫が必要です。以下のページが参考になると思います。

    Resetting the Page Index in a ListView
    http://leedumond.com/blog/resetting-the-page-index-in-a-listview/

    2009年9月20日 3:55
  • なるほど、バグのなのですね...
    解決するまでは、エラーページに飛ばすようにするか、他の方法を利用するしかないですね。

    先に紹介したコネクトのページに、現時点での回避策が投稿されています。DataPagerを継承し、OnInitをオーバーライドする方法です。こういう方法もあるということで参考になるかもしれません。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月20日 13:47
    モデレータ

すべての返信

  • バグのようですね。

    NullReferenceException in DataPager control
    https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=357344&wa=wsignin1.0


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月20日 0:53
    モデレータ
  • > しかし、page=abcd...(文字列), page=12345(数値), page=%00(null), page=1234asdf(混合), page=<a>a</a>(HTML/

    バグというよりは、そのような使い方(DataPager コントロールが自動的に設定する以外の使い方)は想定外
    なのではないかと思います。

    MSDN ライブラリには、QueryStringField プロパティは、DataPager コントロールでページの移動に GET
    コマンドを使用する(デフォルトは POST)ように指定するもので、その目的は、検索エンジンですべてのデー
    タページにインデックスが付けられるようにするためと書いてありました。

    従って、想像ですが、クエリ文字列の設定は DataPager コントロールが自動的に行うもので、ユーザーが
    入力するような使い方(page=abcd... のような文字列が入力される)のは想定外で、結果は未定義というこ
    とではないかと思います。

    解決策としては、ListView の使用をやめて、代わりに GridView を使い、その PageIndex プロパティでペ
    ージを指定するのが簡単そうです。

    ListView には GridView の PageIndex プロパティに相当するものはありません。どうしても ListView を
    使う必要があるなら、少々工夫が必要です。以下のページが参考になると思います。

    Resetting the Page Index in a ListView
    http://leedumond.com/blog/resetting-the-page-index-in-a-listview/

    2009年9月20日 3:55
  • なるほど、バグのなのですね...
    解決するまでは、エラーページに飛ばすようにするか、他の方法を利用するしかないですね。

    2009年9月20日 5:31
  • > なるほど、バグのなのですね...

    先に書きましたが、バグではなくて、想定外の使い方で結果は未定義なのだと思いますよ。

    > 解決するまでは、エラーページに飛ばすようにするか、他の方法を利用するしかないですね。

    これも先に書きましたが、ListView と DataPager を使って、かつ QueryStringField は使わな
    くても、工夫次第で、例外がスローされることを避けて、指定されたページに飛ばすことはでき
    ます。

    2009年9月20日 6:21
  • バグというよりは、そのような使い方(DataPager コントロールが自動的に設定する以外の使い方)は想定外
    なのではないかと思います。
    コネクトの回答に、
     We are escalating this bug to the product unit who works on that specific feature area.
    とありますが、このコメントは定型的なところがあって、この文だけでは本当にbugと認識されているかどうかはわかりません。ただ、状態が「終了 (修正済み)」になっていますから、何らかの修正が加えられたのは事実だと思います。ここから私はバグのようだと書きましたが、ちょっと決めつけて書きすぎたかもしれません。SurferOnWwwさんが言われるのはもっともだと思います。
    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月20日 13:46
    モデレータ
  • なるほど、バグのなのですね...
    解決するまでは、エラーページに飛ばすようにするか、他の方法を利用するしかないですね。

    先に紹介したコネクトのページに、現時点での回避策が投稿されています。DataPagerを継承し、OnInitをオーバーライドする方法です。こういう方法もあるということで参考になるかもしれません。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    2009年9月20日 13:47
    モデレータ
  • ご回答ありがとうございます。

    GridViewについては、確かに簡単なのですが余分なタグが大量に出力されるので、見送ってます。

    >バグというよりは、そのような使い方(DataPager コントロールが自動的に設定する以外の使い方)は想定外
    なのではないかと思います。

    確かに、自動的にDataPagerが設定する値以外の情報が入ることは想定外なのかもしれませんが、Webシステムの関係上、ユーザーによって外部パラメータ(GET,POST)が変更されるというアクションはプログラマーが意図しなくてもあるわけで(SQLインジェクションやXSS、なんとなく)、本来ならばパラメータが任意以外の文字列やパラメータが来た場合は、適切なを処理工程をしなければならないわけですが、一応、QueryStringの値を受け取って数値以外の文字列(NULLを除く)以外は自動処理はしてくれるものの、?&&のような文字列が入った場合に例外となる時点(無視して、他の文字列同様に処理してればよかったのですが)で、不具合という考え方もできるとは思います。

    あまりこの部分に時間をかけることもできませんので、参考にいただいたURL先の資料を検討しながら、ちょっと他の方法も考えてみようかと思います。

    ありがとうございました。
    2009年9月20日 23:47
  • > GridViewについては、確かに簡単なのですが余分なタグが大量に出力されるので、見送ってます。

    「余分なタグ」とはどういうものでしょうか? 自分が試した限りでは GridView を使っても余分と言えるタグ
    は生成されないのですが。

    やり方にもよるのかもしれませんが、余分かどうかはともかくとして、HTML コードの量では、むしろ ListView
    の方が倍以上多いという結果になります。

    > QueryStringの値を受け取って数値以外の文字列(NULLを除く)以外は自動処理はしてくれるものの、?&&のよ
    > うな文字列が入った場合に例外となる時点(無視して、他の文字列同様に処理してればよかったのですが)で、
    > 不具合という考え方もできるとは思います。

    個人的意見(独断と偏見?)ですが、不具合というよりはセキュリティ対策ではないかと思います。

    & でつないで別のクエリ文字列が入力されるというのは DataPager.QueryStringField プロパティの使い方
    としてはあり得ず、XSS 攻撃が疑わしいということで、無視しないで例外をスローしている・・・というのは考えす
    ぎでしょうか?

    2009年9月21日 1:56