Navigation for ASP.NETの紹介 #aspnetjp by @masaru_b_cl

この記事はOne ASP.NET Advent Calendar 2012 : ATNDへの参加エントリーです。

昨日は@kiyokuraさんの「ASP.NET 4.5 Web Formの『強く型指定されたデータコントロール(Strong Typed Data Controls)』を試してみる – 三日坊主と呼ばせない!日記です。

用意していたネタが丸かぶりになったので、急遽ネタ変更したことは内緒でもなんでもなくあばばば、といった感じです!

 

Navigation for ASP.NETとは?

データバインド一発、単体テスト可能なWebFormsアプリを作ろうぜ!なライブラリーです(適当)。

従来Response.Redirect(“/path/to/page.aspx”)等としていた画面遷移を隠し、しかも単体テスト可能にしちゃいます。

が、今回は単体テスト部分は割愛します。すんません・・・

 

導入

NuGet一発です。

 

image

 

Navigationを使用するWebアプリケーションの構成

Navigationを使用するサイトの構成は、次のようになります。

 

image

 

このうち、App_Browserフォルダーとその中身については、とりあえず「おまじない」でよいでしょう。

 

StateInfo.config

Navigationでキモとなるのが「StateInfo.config」です。

 

<StateInfo>
  <dialog key="Person" initial="Listing" path="~/Listing.aspx">
    <state key="Listing" page="~/Listing.aspx" title="Person Search">
      <transition key="Select" to="Details"/>
    </state>
    <state key="Details" page="~/Details.aspx" title="Person Details">
    </state>
  </dialog>
</StateInfo>

StateInfo.config

 

アプリケーションのページにkeyを紐づけ、このkeyでナビゲーション操作ができるようにします。

これにより、ページの細かなURLを開発者が意識する必要がなくなります。

 

Person.cs

POCOとして、エンティティであるPersonクラスを作成します。

using System;

namespace NavigationWebSite
{   public class Person
  {
     public int Id { get; set; }
     public string Name { get; set; }
     public string Address { get; set; }
     public string PhoneNumber { get; set; }
     public string MailAddress { get; set; }
   }
}

Persion.cs

 

PersonLogic.cs

POCOとして、Person操作のためのPersonLogicクラスを作成します。

メソッド引数に[NavigationData]属性をつけることで、Navigationを通してパラメーターが設定できるようになります。

using System;
using System.Collections.Generic;
using System.Linq;

using Navigation;

namespace NavigationWebSite
{
   public class PersonLogic
  {
     private IEnumerable<Person> people = new[] {
       new Person { Id = 1, Name="TAKANO Sho", Address="Nagaoka, Niigata Pref., Japan",
         PhoneNumber="090-1234-5678", MailAddress="takano-s@example.com" },
       new Person { Id = 2, Name="SUGITA Taro", Address="Joetsu, Niigata Pref., Japan",
         PhoneNumber="090-1111-1111", MailAddress="sugita-t@example.com" },
       new Person { Id = 3, Name="TAKAHASHI Ken", Address="Niigata, Niigata Pref., Japan",
         PhoneNumber="090-22222-2222", MailAddress="takahashi-k@example.com" },
       new Person { Id = 4, Name="SHIBATA Takeru", Address="Uonuma, Niigata Pref., Japan",
         PhoneNumber="090-3333-3333", MailAddress="shibata-t@example.com" }
     };
     public IEnumerable<Person> Select()
     {
       return this.people;
     }
     public Person Find([NavigationData]int id)
     {
       return this.people.Where(x => x.Id == id).FirstOrDefault();
     }
   }
}

PersonLogic.cs

 

Listing.aspx、Listing.aspx.cs

GridViewコントロールを使ってWebページを作成します。データバインドも活用し、昨日@kiyokuraさんが紹介したStrong Typed Databindingも使えます。

従来のものと違うのは、データソースコントロールが不要な点です。そのかわり、GridViewのSelectプロパティでPersonLogicのSelectメソッドを呼び出すようにしています。

また、Navigationの機能の一つ「NavigationHyperLinkコントロール」を使って「選択」リンクで詳細画面に遷移するようにしています。このコントロールのプロパティは次のように設定します。

プロパティ 説明
Action StateInfo.configのtransition要素のkeyに指定したActionを指定する。
ToData 繊維先に渡すデータをNavigationDataクラスのオブジェクトとして指定する。
ここで指定したkeyはPersonLogicクラスのNavigationData属性をつけた引数名と対応しており、valueに指定した値が自動的に引数に設定される。

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Listing.aspx.cs"
  Inherits="NavigationWebSite.Listing" %>
<%@ Register Assembly="Navigation" Namespace="Navigation" TagPrefix="cc1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <meta charset="utf-8" />
  <title>Person Search</title>
</head>
<body>
  <form id="form1" runat="server">
    <header>
      <h1>Person Search</h1>
    </header>
    <article>
      <asp:GridView ID="PeopleGridView" runat="server"
        AutoGenerateColumns="False"
        ItemType="NavigationWebSite.Person" SelectMethod="Select"
        OnCallingDataMethods="PeopleGridView_CallingDataMethods">
        <Columns>
          <asp:TemplateField>
            <ItemTemplate>
              <cc1:NavigationHyperLink ID="SelectNavigationHyperLink"
                runat="server" Action="Select"
                ToData='<%# new NavigationData() { { "id" , Item.Id } } %>'
                Text="選択" />
            </ItemTemplate>
          </asp:TemplateField>
          <asp:BoundField DataField="Name" HeaderText="Name" />
          <asp:BoundField DataField="Address" HeaderText="Address" />
          <asp:BoundField DataField="PhoneNumber" HeaderText="PhoneNumber" />
          <asp:BoundField DataField="MailAddress" HeaderText="MailAddress" />
        </Columns>
      </asp:GridView>
    </article>
  </form>
</body>
</html>

Listing.aspx

 

using System;
using System.Web.UI.WebControls;

namespace NavigationWebSite
{
   public partial class Listing : System.Web.UI.Page
  {
     protected void PeopleGridView_CallingDataMethods(
       object sender, CallingDataMethodsEventArgs e)
     {
       e.DataMethodsObject = new PersonLogic();
     }
   }
}

Listing.aspx.cs

 

Details.aspx、Details.aspx.cs

Listing.aspx、Listing.aspx.csと同じように作成します。

ここでは省略します。

 

コードはこれだけです。従来のWebFormsに比べてコードビハインドがかなりすっきりすることがわかると思います。

 

実行結果

では、実行してみましょう。

image

先頭行の「選択」リンクをクリックすると、詳細ページに遷移します。

image

ブラウザーの「戻る」操作で戻った後、今度は4行目の「選択」リンクをクリックすると、4行目の詳細画面に遷移します。

image

 

ちなみに、各画面のURLは”http://localhost:2406/Details.aspx?c0=0-1&c1=0-0&id=12_3″といったように、Navigationにより埋め込まれた情報が含まれています。これにより、初期画面で選択したidを詳細画面に渡すことが可能になっています。

 

まとめ

昨今はASP.NET MVCに押されているWebFormsですが、Navigationを使うことでまだまだそのポテンシャルを生かしつつ、単体テスト可能にすることが可能です。

私も継続的に調査していこうと思います。

 

負けるな!WebForms!

 

なお、今回のコードは次のGistに挙げてあります。

Navigation for ASP.NETのサンプル — Gist

 

明日は?

Developer @ ADJUSTで有名な、MS MVP for ASP.NET/IISの@jsakamotoさんにバトンタッチです。

ASP.NET MVC における AJAX による部分更新と既定のエラーページ : Developer @ ADJUST

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中