WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

TreeView.SelectedNode のサーバー側での特定

by WebSurfer 2011年11月13日 19:12

TreeView のノードをクリックするとポストバックが起こり、サーバー側で TreeView.SelectedNode プロパティでクリックされた TreeNode を取得できます。

TreeView の Node の選択

上の画像は、book というノードをクリックし、book ノードに含まれる子ノードの内 title ノードを取得してその Value を表示したものです。

そのコードは下に示したサンプルのとおりです。データとして使用している XML ファイルは MSDN ライブラリの チュートリアル : TreeView コントロールでの階層データの表示 のものです。

しかしながら、このコードでは、どの book ノードをクリックしても、表示されるのは一番上の book ノード下の title ノードの Value になってしまいます。

何故でしょう? 理由は以下の通りです。

どのノードがクリックされたかのサーバー側での判定は、root からクリックされたノードまでの Value をつなげた文字列を javascript:__doPostBack 関数の引数に設定し、ポストバックされた際にそれを取得して識別しています。

下のサンプルコードの例では、book ノードのハイパーリンクとして a 要素の href 属性に以下のように設定されます。

href="javascript:__doPostBack('TreeView1','sbookstore\\genre\\book')"

book ノードの Value はどれも同じ book ですので、__doPostBack 関数の引数はどの book ノードでも同じになってしまいます。それゆえサーバー側ではどの book がクリックされたか特定できません。だから、最初に該当する一番上の book が選択されたと判定してしまうようです。

解決策は、book ノードの Value が一意になるように TreeView の DataBindings に以下のように設定してやることです。

<asp:TreeNodeBinding DataMember="book"
    TextField="#Name" 
    ValueField="ISBN" />

考えてみれば、Windows アプリとは違って、ブラウザの画面に表示されているノードはインスタンスを指していないので、当たり前ですね。

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">

  protected void TreeView1_SelectedNodeChanged(
    object sender, EventArgs e)
  {
    TreeNode selectedNode = TreeView1.SelectedNode;

    if (selectedNode.Text == "book")
    {
      foreach (TreeNode child in selectedNode.ChildNodes)
      {
        if (child.Text == "title")
        {
          Label1.Text = 
            "選択した本のタイトル: " + child.Value;
          break;
        }
      }
    }
    else
    {
      Label1.Text = String.Empty;
    }
  }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:TreeView ID="TreeView1" 
      runat="server" 
      DataSourceID="XmlDataSource1"
      OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">
      <DataBindings>
        <asp:TreeNodeBinding DataMember="title" 
            TextField="#Name" 
            ValueField="#InnerText" />
      </DataBindings>
    </asp:TreeView>
    <asp:XmlDataSource ID="XmlDataSource1" 
      runat="server" 
      DataFile="~/App_Data/Bookstore.xml">
    </asp:XmlDataSource>
    <br />
    <br />
    <asp:Label ID="Label1" runat="server">
    </asp:Label>
  </div>
  </form>
</body>
</html>

Tags: ,

ASP.NET

Access 2007 の DB を利用するアプリ開発

by WebSurfer 2011年11月8日 22:37

注意 1:
2010, 2013 用のドライバには 32/64-bit 版の両方があります(2007 用は 32-bit のみ)。Visual Studio は 32-bit ですので、ドライバに 64-bit 版を使うと、この記事に書いたような Visual Studio の Access DB への接続はできませんので注意してください。

注意 2:
下にリンクを張ったダウンロードページ「Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント」の「詳細」にある条件に "Jet の全般的な代替としての使用" はできないと書いてあります。一方 Microsoft Access 2010 を使用したデータ プログラミングには JET は非推奨だから ACE を使おうという意味のことが書いてあります。一体どうしろと言うのでしょうね。(汗)

Access 2007 をインストールしていない開発環境でも、Access 2007 データベース(accdb ファイル)を使用するアプリケーションを開発できます。

Microsoft.ACE.OLEDB.12.0 プロバイダの選択

Access 2003 以前で使用されていた JET (Joint Engine Technology) データベースエンジンは、Access 2007 では ACE (Access Connectivity Engine) データベースエンジンに代わったそうです。そのため、ACE データベースエンジン用のドライバが必要になります。

Microsoft ダウンロードセンターの 2007 Office system ドライバ: データ接続コンポーネントから AccessDatabaseEngine.exe をダウンロードして開発マシンにインストールすれば、ACE データベースエンジン用の OLEDB ドライバと ODBC ドライバが利用可能になります。

2019/6/24 追記: Office 2007 がサポートされなくなったためか、上の 2007 用のページはリンク切れとなってしまいました。探しても見つからないので、今現在は 2010 以降用を使うほかなさそうです。2010 用は以下からダウンロードできます。

Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント

(ちなみに、JET 4.0 データベースエンジン用の OLEDB プロバイダ、ODBC ドライバは Windows OS 同梱で提供されているのでインストールは不要だそうです。Jet データベース エンジンを使用するアプリケーションの開発/動作環境 を参照ください)

インストールすると、Visual Studio 2010 を Access 2007 のデータベース(accdb ファイル)に接続できるようになります。

上の画像は、Microsoft が提供しているサンプルデータベース "Northwind 2007.accdb" を Web アプリケーションルート直下の App_Data フォルダにコピーして、Visual Studio 2010 のサーバーエクスプローラーの「接続の追加」メニューから「詳細設定」を開き、"Northwind 2007.accdb" に接続しているところです。

接続できれば、Access 2003 の mdb フ���イルと同様に、AccessDataSource や ObjectDataSource を利用して Access 2007 データベース(.accdb ファイル)を操作するアプリケーションを、ウィザードベースで作成できるようになります。

Tags: ,

ADO.NET

ブラウザによる URL のエンコーディング

by WebSurfer 2011年11月7日 22:08

クエリ文字列に日本語を使用している場合、それをブラウザのアドレスバーから直接入力して要求をかけるのは問題がありそうです。

以下のような、日本語を含む URL をブラウザのアドレスバーに直接打ち込んで要求をかけると、ブラウザはどのような文字列をサーバーに送るでしょうか?

http://www.abc.com/日本語.aspx?data=日本語

下の画像は IE9 の場合で、Fiddler を使って HTTP-GET 要求をキャプチャし、HexView で表示したものです。サーバーに送信したバイト列を 16 進数で表したものと、その 16 進数に相当する ASCII コードの文字が表示されています。

Fiddler によるキャプチャ画面

ファイル名の "日本語" の方は UTF-8 が URL エンコード(ASCII 文字で %E6%97%A5 ... %AA%9E)されますが、クエリ文字列の方の "日本語" は Shift_JIS そのまま(反転表示したバイト列 93 FA 96 7B 8C EA)になっているのが見えるでしょうか。

IE9, Firefox 7, Chrome 15 で試してみましたが、ファイル名の方はいずれも UTF-8 の URL エンコードで同じ結果になりましたが、クエリ文字列の方はそれぞれ以下のように結果が異なりました。

ブラウザ クエリ文字列
IE9 Shift_JIS そのまま
Firefox 7 Shift_JIS を URL エンコード
Chrome 15 UTF-8 を URL エンコード

ということは、サーバーが受信した文字列を UTF-8 として解釈する場合(ASP.NET のデフォルト)、上記のブラウザのうち Chrome しかクエリ文字列を正しく送信できないということになるようです。

では、アドレスバー直打ちではなく、以下のようなハイパーリンクをクリックするとブラウザはどのような要求をサーバーに送るでしょうか?

<a href="default.aspx?data=日本語">リンク</a>

IE は文字コードのバイト列を生のまま送ります。例えば、"日本語" というクエリ文字列の場合、ハイパーリンクのあるページのエンコーディングが Shift_JIS なら 93 fa 96 7b 8c ea、UTF-8 なら e6 97 a5 e6 9c ac e8 aa 9e となります。

Firfox と Chrome は URL エンコードしてから送ります。ただし、Shift_JIS の場合、2 バイト目が ASCII の非予約文字のときは、その文字をそのまま使用します。"日本語" の場合、"本" の 2 バイト目 7b が ASCII 文字で '{' に該当するので、結果は "%93%FA%96{%8C%EA" になります。

特殊な例かもしれませんが、BlogEngine.NET の場合 '{' という文字が問題で、内部で URL の書き換えを行う際に例外がスローされてサーバーエラーになってしまうという問題がありました。

このような予期しない問題を避けるために、サーバー側できちんと UrlEncode メソッドを使って URL エンコーディングした文字列("本" は "%96%7b" になります)を使うのがよさそうです。(ただし、アドレスバー直打ちされた場合はどうしようもありませんが)

ちなみに、URL 本体('?' の左側の文字列)は、アドレスバーへの直打ち、ハイパーリンクへの設定、ページに使用されているエンコーディングの違い、ブラウザの違い(IE9, Firefox 7, Chrome 15 しか試してませんが)などに関係なく UTF-8 の URL エンコーディングになります。

なので、BlogEngine.NET 2.0 の Tag cloud の問題日本語の著者名の問題 で書きましたように、URL 本体の文字に URL エンコードしない日本語の文字列を使っていますが、今までのところ期待通りに動いています。運よく問題に遭遇していないだけという可能性は排除しきれませんが。(笑)

Tags: ,

その他

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年5月  >>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar